Unicode is a medium rated machine on HackTheBox created by wh0am1root. For the user part we will forge a JWT to get access to the admin panel. From the admin panel we will find a LFI vulnerability with which we can read database credentials that were reused as another user. Once on the machine this user can run a custom binary with sudo. We are able to abuse this using brace expansion in a curl command to write our public key to root’s authorized keys.
User
Nmap
As usual we start our enumeration with a nmap scan against all ports followed by a script and version detection scan against the open ones to get an initial overview of the attack surface.
All ports
1 |
|
Script and version
1 |
|
JWT Forge
There are only two ports open on the machine and 80 seems to be more promising so we will start there. Opening it up in our browser we see the Hackmedia landing page.
We are also able to register our own account which we do to check for additional functionality within the website.
Looking at our cookies we see that auth is handled by JWT tokens.
Taking a close look at the JWT we see that it pulls the public key from a jwks.json from the website. This means if we can redirect it to our own jwks.json we can forge our own jwt’s.
Looking at the source of the home page there is a convenient looking open redirect.
To forge our own tokens we need to generate a RSA public private key pair in a first step.
1 |
|
Then we download the jwks.json
from the target to see what format it expects.
1 |
|
jwks.json
1 |
|
Next we take the public key and bring it into a format we can use with pythons authlib module to generate a new n
.
1 |
|
jwks.py
1 |
|
Running the script we get our new n
which we replace in the jwks.json
file.
1 |
|
jwks.json
1 |
|
Next we stand up a python webserver so the target can reach our jwks.json
1 |
|
With all pererations met we can now forge our own token using the key pair we generated, a redirect url pointing to our jwks.json
and the new username of admin
.
Exchanging the cookie and refreshing the page the target retrieves our jwks.json
and we are logged in as admin afterwards.
1 |
|
LFI
Looking at Last Quarter
report we see it tries to load a pdf file.
Bypassing the WAF with unicode we are able to include other files aswell.
Checking the /etc/nginx/sites-available/default
configuration file it contains two very interesting comments.
1 |
|
The db.yaml
file is stil in the location mentioned and we can retrieve it.
1 |
|
With these credentials we are now able to log into the machine as the user code and grab the user flag.
1 |
|
Root
Brace expansion
Checking for sudo rights we see that code can run the custom looking binary /usr/bin/treport
as root with no password.
1 |
|
Running the binary it displays multiple options.
1 |
|
To test the 3.Download A Threat Report.
functionality we first create a testfile and server it with a python server.
1 |
|
Retrieving it with treport
we can see that curl is used to retrieve it and our argument is passed to it.
1 |
|
1 |
|
This seems very interesting for command injection. First we need a file we want to write on the target system. A public ssh key into root’s authorized_keys seems like a good candidate.
1 |
|
We serve the public key again using python.
1 |
|
Next we select the 3.Download A Threat Report.
again. This time we use brace expansion to specify additional parameters to the curl command.
1 |
|
Our key get’s downloaded and we can ssh into the machine to grab the root flag
1 |
|
1 |
|