Home
Writeups Misc About
PriMeD5

PriMeD5

Thanks to JosePisco for the very useful hint of "a property md5 has on collisions". Completely shifted my approach.

The server is signing the hash of the prime sent using RSA, and there is no information to figure out the private keys so we have to forge two numbers n1 and n2 such that MD5(n1)=MD5(n2).

Initially my approach is to use fastcoll to generate MD5 collisions with a given prefix, but this approach is just too unreliable, as the probability of finding a prime with some reasonably chosen prefix is too low - fastcoll always generate 1024-bit messages anyways. Obviously this is still possible, but this is too painful to go through.

My solution relies on the fact, from this paper on MD5 Hash Collisions. Given two inputs M and N, if MD5(M)=MD5(N), in words, the MD5 hashes of M and N are the same, then for any input T, we have:

MD5(M||T)=MD5(N||T)

where || denotes string concatenation. Hence, our task is to find some 64-byte M and N that have the same MD5 hash. M and N must be 64 bits long as the size of the prime sent can only be 128 bytes (1024 bits), and finding MD5 collisions involving a prime with a composite number is the same problem as the fastcoll solution above.

From a bit of Googling, we encounter this link providing the two 64-byte blocks that provide the same MD5 hash. From this, we can obtain the number representation of the two byte strings:

Finding the suffix is equivalent to finding the next prime starting from input1 (denote by I for easier typing) left shift by 512 bits. We are banking on the property that there should be a prime in the range of I2512 to I2512+2512. The following Sage script does the job nicely:

This will provide the prime with the first 512 bits the same as input1. We can take the 512-bit suffix of the prime, then append to input2, in order to obtain a byte string having the same MD5 hash as the prime. The work left is simple, sent the prime to the server to obtain the signature, then send the other number (composite) to the server with the obtained signature to retrieve the flag.

Python Implementation: