DOMECTF2020

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.

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 = (S*q/pattern) the bound for the root is, in fact, close to S*k, 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.

b’{Unb0x th1s f0r y0ur fl4g,juskizl{XSeVsIFDmAWoiK7BkUjrEI7zLCYYnERL}}’

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}

Experience the Beagle Security platform

Unlock one full penetration test and all Advanced plan features free for 10 days

Find surface-level website security issues in under a minute

Free website security assessment

Experience the power of automated penetration testing & contextual reporting.