Crypto Failures

Implementing your own military-grade encryption is usually not the best idea. - by shamollash

The following post by 0xb0b is licensed under CC BY 4.0


Recon

We start with a Nmap scan and find two open ports. We have SSH on port 22 and a web server on port 80.

We visit the page and see that we are logged in as a guest. There is talk of an SSO cookie that is supposed to be secured by military grade encryption.

We find the cookie as follows:

In the source, we find a comment that the .bak files should still be removed. Furthermore crypt is written in bold.

We intercept a request to the index page using burp and check whether index.php can also be called. And we get the index page.

If we now request index.php.bak, we find the source of the index page and thus also the generation of the cookie. The config.php is unfortunately not available as a backup, with that we might have had access to the key.

Source Code Analysis

If a cookie secure_cookie is not set, it gets generated by generate_cookie(). The structure of the cookie is user:UserAgent:ENC_SECRET_KEY. So we are at least in control of the User-Agent parameter, but more on that later. The generate_cookie function first calls generatesalt(), to generates a random 2-byte salt from an alphanumeric character set. This salt and the cookie string is then passed to the function make_secure_cookie.

The make_secure_cookie() function essentially applies crypt() in chunks of 8 characters of the passed cookie string including the salt.

The verification process extracts the salt from the first two characters of the stored cookie (substr($_COOKIE['secure_cookie'],0,2)). Which is then used to generate a secure cookie to compare it with the one passed.

Once a valid cookie is verified, the user is either given access or denied based on their username. The username is set by the user cookie. If the user is admin a flag will be shown.

Admin Access

Since we are able to extract the salt of a hash, and we know that every chunks of 8 characters of the cookie string will be hashed with the salt, it is easy to impersonate the admin. All we have to do is to replace the first hash with the one representing the admin user and setting the user cookie to admin.

We run our script to generate a new secure_cookie.

Next, we replace the secure_cookie with ours and set the user cookie to admin and reload the page. We are now logged in as admin and get the first flag.

Obtaining The Secret: ENC_SECRET_KEY

The next step is to extract the secret key. Since we know the salt, we can now bruteforce any 8 chunk block. With a character set of 65 characters, that would be 65^8 permutations that we would have to try for each block. That would not be feasible.

Instead, we could reduce it to one byte. Because we have control over the User-Agent and could create a block of which we already know 7 bytes and would only have to bruteforce one byte.

We hash the block with the 7 known bytes and the unknown character and when this resulting hash reappears in the cookie, we know that the unknown byte must be part of the key.

So we could brute-force the second chunk with the following string, generated by the user agent = AAAAAAAA guest:AAAAAAAA:_ and thus determine the first character of the key.

Chunk A: guest:AA

Chunk B: AAAAAA:_

So, we use the User-Agent as padding, that allows us to brute-force a single character at a time.

We chose a padding of 256 since the flag is really long.

We then just need to reduce the padding and update our know string $test_string with the character sequence found until we finally uncovered the entire key.

We illustrate this in the following graphic. The test string is outlined. If we get a hit with a hash, we reduce the user-agent by one A and adjust the test string by removing the first character and appending the next known one.

After running our script, we get the key after a short time.

Last updated

Was this helpful?