Week 29 - 2023
Week 29 - 2023¶
Done¶
- RB take-home project
- Agda opinion
- Fixed some bugs in puro
TODO¶
Stuff I tried¶
Verifying the RSA signature was pretty simple, decrypting signatures with the public key yields a PKCS1 padded sha256 hash of the packet. The key provided is just a big-endian 3 byte exponent followed by a 64 byte modulus.
I am having a lot of trouble with figuring out the right way to combine the original data and key, no combination of the ordering or typical crc32 parameters for seed, refl in, refl out, and polynomial seem to work.
The checksum count is always equal to (len(data) - 76) / 4 so my assumptions about the structure of the packet seem correct. The length of all checksums in the payload dump is similar to cat.jpg so I assume cat.jpg is processed in 4 byte chunks to produce 4 byte checksums.
There are some repeating sequences of 0x32323232 in cat.jpg which do not correlate to any repeating checksums in the packets, so I assume each checksum rolls into to the checksum following it, this also makes sense because the README hints that the order of packets will be a problem.
This is a really weird way to use crc32, it’s technically bijective but the receiving end will have trouble reversing one, no packages I found supported that. It would make a tiny bit more sense if crc32 was used as a crude PRNG and the plaintext was xored at the end like a stream cipher.
The repeating xor key part makes sense but the order that you xor is unspecified, the first packet’s xor key is 0x11bc so I assume you have to xor 0x11bc11bc before or after applying the checksum.
For processing the first few bytes of cat.jpg into the expected checksum I’ve tried:
- Xor before and after:
crc32(chunk) ^ 0x11bc11bc,crc32(chunk ^ 0x11bc11bc) - As a stream cipher:
crc32(n) ^ chunk ^ 0x11bc11bc - Everything above with varying sizes for the first chunk:
b'\xff'b'\xff\xd8'b'\xff\xd8\xff'b'\xff\xd8\xff\xe0'. - Everything above with varying reflIn / reflOut in case the endianess was wrong
- Everything above with polynomials from less popular crc32 standards:
[0x04C11DB7, 0x000000AF, 0x1EDC6F41, 0xA833982B, 0x814141AB] - Everything above but with different seed values:
[0xFFFFFFFF, 0, 0x52325032, 0x11bc11bc] - Brute forcing a polynomial that produces
0xc3d42976or0xc3d42976 ^ 0x11bc11bc - Looking for a magic key by xoring the first and second checksum using the relation
crc(x) ^ crc(y) ^ z = crc(x ^ y) - Looking for a magic key
crc32(chunk, previous) ^ magic ^ 0x11bc11bc - Lots more messing around with different crc32 implementations and brute forcing with a c++ program.
Updated August 23, 2023