Hello ! Today we are going to take a look at the Stocker machine on HackTheBox. Here is a summary if you want to skip to some part of the exercise :
First contact
As always, we are going to start by doing a simple nmap scan of the target, to know what kind of machine we have in front of us :
Here, we can see an ssh server running on the machine, as well as a web server. If we try to access the webserver with Firefox, it redirects us to http://stocker.htb, so let’s add this address to /etc/hosts and go back to Firefox :
We are given a basic page for a company buying and selling various items, the page is not really interactive, there is no login nor contact options. Let’s try to see if there are any interesting directories on the website :
gobuster dir -w=$wordlist -u="http://stocker.htb"
Nothing out of the ordinary, so let’s try to find subdomains using virtual hosts with ffuf. When first using it, we see a lot of 301 codes, so let’s filter them. The final command is :
ffuf -w $wordlist -H "Host : FUZZ.stocker.htb" -u "http://stocker.htb" -mc all -fc 301
Bingo, we found the subdomain http://dev.stocker.htb, we add it to /etc/hosts and visit the page, this is what we get :
We are onto something, we’ll need to find a way to get behind this page.
Login bypass
We are in front of a locked gate, since we haven’t found any credentials yet. Let’s see what is around on the website :
One page sticks out : /stock, but we cannot access it without being logged in. Brute forcing the login page did not result in a success, so we are going to try other methods, such as SQL injections. Unfortunately, running sqlmap tells us that the target might not be vulnerable :
Maybe the application is not vulnerable to SQL injections, or maybe the database is not an SQL database, but a NoSQL database ? Let’s try some NoSQL injections to maybe find out. We are going to make a dumb login request and analyze the request made to the server it to see where we can inject our parameters. Basic injections such as
username[$ne]=aaaa&password[$ne]=aaaa
did not work, but, if we try to directly send a json object instead of form-data as the request was originally using, the injection works. Using this request :
{"username": {"$ne":"aaaa"},"password":{"$ne":"aaaa"}}
We are redirected to http://dev.stocker.htb/stock, and we can now access the page without any error :
Let’s now look around the site to see what this subdomain really is.
Getting a shell
This looks like the development version of a shopping website, probably the one the company is going to use once it is ready. There are a few test items, but one interesting thing we find when we try to order on the site is that there is an API behind it. If we order a few items, we have the possibility of viewing an order summary, which redirects us to http://dev.stocker.htb/api/po/$order_id.
Trying to enumerate the API gives us the /api/products endpoint, but nothing really interesting comes out of it.
The order summaries we can get through the api are pdf files created based on our orders. Maybe there is a way for us to manipulate this data in our orders to create interesting summaries.
When we order something, this is the request sent to the server :
Out of the fields present here, some are likely to also be on the generated pdf, like price, title and amount. What if we tried to inject something into the title field for example ?
Using this request :
We get an error when we then try to access the order summary for the newly created order :
We get an error, it looks like like our injection worked ! We can now inject HTML into these order summaries. Injecting a full JavaScript reverse shell does not seem to work, but we can instead inject iframes to access files on the server. For example, by injecting :
<iframe src='file:///etc/passwd' width='1000' height='1000'>
We get access to the passwd file of the server :
We discover that the website uses MongoDB, and we find one interesting user : angoose. Asking for /home/angoose/.ssh/id_rsa doesn’t return anything, so this user probably hasn’t any ssh keys stored, or we can’t access them with the user we currently control (probably www-data). Trying to access the bash history doesn’t work either. One other interesting place to look into could be the site’s code, since the JavaScript behind the site probably needs authentication to connect to the database, they might be stored somewhere, and indeed, this is what we find here :
Bingo, we find a passphrase for the database. We can’t connect to it ourselves, but maybe someone reused passwords for different applications. Let’s try to ssh as angoose with this passphrase :
Yay, we are in, and we can read the user flag, now, it’s time to get root !
Privilege escalation
One of the first thing we usually do when trying to escalate our privileges on any Linux machine is see if the user can use sudo and what it can do with it. Here, we find that we can use node to execute JavaScript code as root, as long as the .js file we want to execute matches /usr/local/scripts/*.js.
But, it appears that we cannot write anything to this folder. Fortunately for us, using wildcards is highly dangerous, since this means that we can use directory traversal to execute any .js file on the system. For example, /usr/local/scripts/../../../tmp/shell.js matches /usr/local/scripts/*.js.
So, we upload our shell to .tmp, and execute it as root :
sudo node /usr/local/scripts/../../../tmp/shell.js
On our listener, we get a root shell :
And we can read the root flag ! We won this machine !
As usual, I hope you had fun with this machine !
Leave a Reply