Decryptify
Use your exploitation skills to uncover encrypted keys and get RCE. - by 1337rce
Last updated
Was this helpful?
Use your exploitation skills to uncover encrypted keys and get RCE. - by 1337rce
Last updated
Was this helpful?
The following post by 0xb0b is licensed under CC BY 4.0
We start with an nmap scan and find two open ports. We have SSH on port 22
and a web server on port 1337
.
We visit the page on port 1337
and have a login page in front of us. We can log in using a username and invite code or mail and invite code. Furthermore, we also discover a link to the API documentation.
Unfortunately, the API documentation is password protected.
We use Feroxbuster for a recursive directory scan and find some interesting directories and pages...
Including http://decryptify.thm:1337/js/api.js
, looks like some Javascript for the API documentation.
However, this is obfuscated.
We use beautifier.io
to counteract some of the obfuscation.
It is noticeable here that the functions are called one after the other through their dependencies using the call j(0x169)
. Maybe this is how we get the password for the API documentation.
We insert the obfuscated snippet into our browser console and then call j(0x169)
. We get a string back from the k
array.
We use this as a password at http://decryptify.thm:1337/api.php
. And we actually get access! We gain insight into the token generation.
The token are generated with the following steps:
Extract Email Length:
The function calculates the length of the given $email
string.
Convert First 8 Characters of Email to Hex:
The function extracts the first 8 characters of $email
and converts them to a hexadecimal number using hexdec()
.
Calculate Seed Value:
The function adds the email length, a constant value ($constant_value
), and the hex-decimal converted value to form a seed.
Seed the Random Number Generator:
The mt_srand($seed_value)
function sets the seed for PHP’s Mersenne Twister (mt_rand()
).
Generate Random Number:
mt_rand()
produces a pseudo-random number.
Encode in Base64:
The generated random number is converted into a Base64 string and used as the invite code.
Predictable Randomness (Weak Seeding)
The seed value is deterministic, as it is calculated using the email and a constant value.
Given the same email and constant, mt_rand()
will always generate the same invite code.
Further information about insecure randomness can be found in the recent release walkthrough room Insecure Randomness:
From our directory scan using Feroxbuster we also found the following page: http://decryptify.thm:1337/logs/app.log
. Here we can see that the users alpha@fake.thm
and hello@fake.thm
were created. The invite code for alpha@fake.thm
is visible, but this user has been deactivated. The invite code for hello@fake.thm
is not visible.
However, we can see with a login attempt that the user hello@fake.thm
actually exists.
The steps of token generation can be reversed, as we are in possesion of an e-mail and its corresponding token. So we are able to brute force the constant. With that constant and a given email we are able to predict the token for that email as the seed will be always the same for mt_rand().
Steps to calculate the constant:
Decode the invite code → base64_decode($invite_code)
to retrieve mt_rand()
value.
Brute-force possible constant_value
:
Iterate over a range (0
to 100000
).
Compute seed_value
using guessed constant_value
.
Check if mt_rand()
matches the expected value.
Return the correct constant_value
when found.
With that small script we are able to reverse the constant value:
We now use the php code found in the api documentation with the constant value of 99999
and the email hello@fake.thm
to generate its invite token.
With that token, we are able to log in...
... And find the first flag on the dashboard.
In the source of the dashboard page we find a hidden field with the name date
and something base64 encoded as value.
Using that parameter without the value reveals us a padding error. So we might be able to pull off a padding oracle attack.
Some more insights about Padding Oracles can be found in the recently released walkthrough room of TryHackMe.
Padding oracle attacks happen when an application reveals whether the padding in encrypted data is correct or not through detailed error messages or variations in response time. Attackers can exploit these slight clues to figure out the original data without the encryption key. This attack targets encryption methods like Cipher Block Chaining (CBC), which uses padding to handle data of different lengths. The padding oracle attack is named because the server acts as an "oracle" by providing feedback on whether the padding in the ciphertext is valid. [https://tryhackme.com/room/paddingoracles]
There are some tools like padbuster or padre to pull that attack off. We will use padre.
A similar room with a padding orcale is the New York Flankees room from last year:
We capture a request to retrieve the needed cookies.
Next, we want to identify what this base64 is actually and use the padding oracle attack to decrypt that data. Running padre with the value in the source, we see date +%Y
command is being issued, giving the current year in the footer.
Now we use the padding oracle to encrypt our own command, for this we chose id
.
We pass the encrypted output as a value for the date
parameter and see, that we are able to issue arbitrary commands.
Next, we want to run the command cat /home/ubuntu/flag.txt
to read the final flag.
We pass the output of padre for the date parameter and are able to read the final flag.