Craft — HackTheBox
This is a write-up on how I solved craft from HacktheBox.
Hack the Box is an online platform to test and advance your skills in penetration testing and cybersecurity.
About this box:
One of my favorite boxes from HackTheBox, very real-world applicable. There are lots of steps, but it’s very straightforward and you probably have already found your next step before you know how to use it, we will see a lot of common mistakes, this one really forces you to understand all the pieces of the web-app it is running in order to get user. So it feels very real.
Actually, Craft was my first Medium level box.
Recon:
Use Nmap to scan the target ports:
nmap Network exploration tool and security / port scanner
-sV (Version detection)
-sC Performs a script scan using the default set of scripts.
Only two ports are opened 22 and 443. We can directly access to https://10.10.10.110 and see what we get.
So, we got a simple page, if we navigate to the source we get two URL.
https://api.craft.htb/api/
https://gogs.craft.htb/
To access these URLs we need to add them in the host file.
Open hosts file with your favorite editor and add the IP address and URLs:
sudo vim /etc/hosts
We have craft API:
And also we have “A painless self-hosted Git service.” — GOGS, where craft-API source code is hosted:
And we got a flask based web application:
Let’s dive into code
If we look at API modules, we will see ‘eval’ function in
craft_api/api/brew/endpoints/brew.py
Eval is a very dangerous function, we can use it to execute System command.
However, when a user is able to provide the input, eval()
will execute anything that’s fed to it. A user could build a string where additional python code is executed, such as erasing all files on the system or spawning a reverse shell. Therefore, eval()
should never be used to process user input.
We see that eval()
is used to make sure the ‘abv’ value submitted by the user is less than 1.0.
It expects something like this:
We can exploit this by sending the following POST request to the API, which would open a reverse shell to the device with IP 10.10.15.130 on Port 9999.
BUT, this won’t spawn the reverse shell, To trigger the eval function, we need to send an authorized request on brew endpoint.
Get reverse shell
For authorization, we need the username and password. Random/Default one does not work. Let's continue looking at the Gogs repository.
If we look at the commit history, we will see that Dinesh has no idea about cyber hygiene. he left username and password in the history:
Let’s generate token and send an authorized request on the API:
First set up a listener on port 9999:
nc -nvlp 9999
And run our python script:
We got the shell!
Wait a sec! we are root? Where is the flag?
We are in jail! It’s a docker container.
Okay, let's look at what we got.
We have the same repository but the difference is that we got credentials of the MySQL
From database/models.py
we know that there is 2 table in our database.
We can modify dbtest.py
code and dump all the content from the “user” table
Change SQL query to:
sql = "SELECT * FROM `user`"
And to get all row:
result = cursor.fetchone()
=>
result = cursor.fetchall()
We get new credentials!
Use those credentials to log in on Gogs, Ebachman’s credentials do not work but we can log in as a Gilfoyle.
Oh man, Gilfoyle has a secret repository that contains a .ssh folder. Why him? he is my idol! c’mon… it should be Denish 🤣
We have a public and private key:
Okay, grab id_rsa and ssh via Gilfoyle’s account:
ssh -i id_rsa gilfoyle@10.10.10.110
Oh crap, it needs the passphrase. I tried to crack it with John but it took me a while and realized that it can be the password of Gilfoyle’s account.
Use ‘ZEU3N8WNM2rh4T’ as passphrase and we are in!
Okay, we can read user.txt and submit it for 15 points:
Privilege escalation
From the secret repository, we know that we have vault on our box
Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, SSH keys, or certificates. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.
In the vault directory, we also have secrets.sh file
It appears as though he’s running vault as root.
With the following command, we can generate OTP(one-time password) for SSH.
vault write ssh/creds/root_otp ip=10.10.10.110
And we are root!
It was my first writeup about HackThebox, I hope you enjoyed!
Feedback is welcome.
References
1. http://vipulchaskar.blogspot.com/2012/10/exploiting-eval-function-in-python.html
2. http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet/
3. https://www.vaultproject.io/docs/commands/ssh.html