I've been working my way through an undocumented TCP-based protocol by monitoring traffic with tcpdump, Wireshark, and some Python packages (scapy, numpy) with good luck so far, but I've hit a wall with what I think is some sort of checksum/hash/CRC.
Watching a client binary, it sends its first "hello" sort of message, gets back a response from the server with some basic things (server version, etc.), then sends a set of commands in the subsequent messages. It's that second and subsequent message type I can't figure out. Here's an example:
2f c6 00 f2 00 36 01 08 56 cc 80 c4 00 00 00 00
00 00 00 00 01 04 72 6f 6f 74 00 68 6f 73 74 6e
61 6d 65 00 6c 6d 67 72 64 00 2f 64 65 76 2f 70
74 73 2f 30 00 00
The first 22 bytes are what I'm calling the header, since it's a fixed-length segment and after that it's all just null-terminated ASCII strings. The bytes of that header:
- 1st: always
0x2f
- 2nd: looks like a sort of sum over the message bytes but I'm not 100% on that part
- 3rd and 4th: total mystery to me and the reason for this post
- 5th: always
0x00
- 6th: total number of bytes in the message
- 7th-8th: always
0x0108
- 9th-12: four-byte unix timestamp
- 13th-20th: always
0x00
- 21st-22nd: always
0x0104
My question is about the 3rd and 4th byte: what method is the client using to come up with those values, and/or what should I try to figure it out myself?
I can test a wide variety of values by varying the hostname, username, system time, and TTY the client is running under, so I can easily gather gobs of example packets if needed. So far I've tried a statistical approach with that by looking at a histogram of what values those bytes take on across a wide range of inputs. I haven't discovered too much from that, except:
- 3rd byte spans 0 - 63 (i.e., its first two bits are always 0)
- 4th byte spans 0 - 255
- neither byte ever takes on the values 10 - 13 (there's a gap in an otherwise evenly-spread histogram on these specific values)
Another method was to give it a few specific values of hostname to see how it behaves. These things DO change the value of both of those mystery bytes:
- Switching the order of message bytes
- Inverting a bit in a particular position in two different bytes
I then tried crunching through different types of checksums I've read about (variations on BSD and Fletcher) as well as CRCs (trying a 15-bit polynomial to produce a 14-bit remainder, but, is that actually a thing that's done?) with no luck so far. Any ideas?