Adleman resigned from his job and left his documents in a locker. He had kept a secret password to open it.
He has sent some files to his co-workers and it contains the crucial information to identify the password.
Help the team to recover the password.
Solution
In the challenge, we get encryption code, encrypted flag, encrypted private key and encrypted public key.
The code is quite short and simple:
RSA key pair is generated in some secret way
Private RSA key is encrypted via AES-ECB
The flag is encrypted using public RSA key
Public key is encrypted using some online encrypter.
The goal seems clear - we need to somehow recover the private key from the public key and the AES-encrypted version of the private key.
For RSA decryption we need four parameters - ciphertext, d, prime factors p and q, and n. Since none of the values is provided we have to find those values.
From the question itself, it is clear that the password for decrypting the public key file is “Adleman”. The public key consists of two values n and e which can be extracted using the following code snippet.
If we look closely at the private key, we can notice a very strange pattern at a certain point:
The private key is encrypted using AES ECB mode in which identical plain text blocks are encrypted using identical ciphertext blocks. We can notice that this particular piece of data falls into place where the first prime factor should be, plus-minus few bytes in the block before and block after.
This means that the prime factor has to have such a repeating pattern and the prime has to be something like X ABCD ABCD ABCD … Y.
We could also write this down as ABCD * 0x10001000… + S where S is the unknown part located in the non-repeating blocks.
And the pattern we obtained is
For now we have the value of n ,
Then,
Now let’s introduce a polynomial f(x) = (N-x)/pattern. From the above equation it’s clear that for x0 = S*q this polynomial reduces to 0 mod q because it would be a multiple of q. We also know that q is a factor of N.
However, we can’t directly use Coppersmith method here, because S*q is actually very big, it’s bigger than one of the factors, so at least N^1/2 and Coppersmith bound for this case would allow for finding roots about N^1/4.
But we can go one step further and make an approximation:
Now we can re-formulate the polynomial to f(x) = N/pattern - x, and since we’re now looking for x0 = (Sq/pattern) the bound for the root is, in fact, close to Sk, which we can hope is small.
We can look at this via a simple sanity check:
This shows us that with this setup the root we would be looking for is about 512 bits long.
The solver for this problem is as described above:
We will get the p and q value from this code.
There was one more thing to consider - the pattern might be shifted, since the blocks are not perfectly aligned. We don’t really know where is the first 1, so we check the shifts as well:
Now we have all the values required for decryption using RSA. Giving the p and q values to the following code will generate a flag.
Now juskizl{XSeVsIFDmAWoiK7BkUjrEI7zLCYYnERL} should be decrypted for the actual flag. It is clear that some substitution cipher is used and the pattern will consist of capital and small letters. Leaving the numbers behind apply a monoalphabetic substitution cipher to the random value obtained. As we know that juskizl will be domectf, we can actually figure out substitution used which is a monoalphabetic substitution cipher with a shift of 6 positions. And the final flag is:
domectf{RMyPmCZXgUQicE7VeOdlYC7tFWSShYLF}
Automated human-like penetration testing for your web apps & APIs
Teams using Beagle Security are set up in minutes, embrace release-based CI/CD security testing and save up to 65% with timely remediation of vulnerabilities. Sign up for a free account to see what it can do for you.