Sau - HackTheBox CTF Writeup

mircea
@mircea.codes

Sau - HackTheBox CTF Writeup
Recon
Nmap
First, let's start a simple nmap scan on our target. I first ran it without the -p-
flag, and using the info I gathered I started further enumerating while having the all-ports scan in the background, just in case there is something running on a more obscure port.
nmap -sV -sC -p- 10.10.11.224
And here are the scan results:
Nmap scan report for 10.10.11.224
Host is up (0.10s latency).
Not shown: 65531 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 aa8867d7133d083a8ace9dc4ddf3e1ed (RSA)
| 256 ec2eb105872a0c7db149876495dc8a21 (ECDSA)
|_ 256 b30c47fba2f212ccce0b58820e504336 (ED25519)
80/tcp filtered http
8338/tcp filtered unknown
55555/tcp open unknown
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| X-Content-Type-Options: nosniff
| Date: Thu, 31 Aug 2023 17:19:43 GMT
| Content-Length: 75
| invalid basket name; the name does not match pattern: ^[wd-_\.]{1,250}$
| GenericLines, Help, Kerberos, LDAPSearchReq, LPDString, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 302 Found
| Content-Type: text/html; charset=utf-8
| Location: /web
| Date: Thu, 31 Aug 2023 17:19:15 GMT
| Content-Length: 27
| href="/web">Found</a>.
| HTTPOptions:
| HTTP/1.0 200 OK
| Allow: GET, OPTIONS
| Date: Thu, 31 Aug 2023 17:19:16 GMT
|_ Content-Length: 0
From the report we find out the following:
- 2 open ports: ssh(22) and 55555
- 2 filtered ports: 80 and 8338
Opening up 10.10.11.224:55555
in a browser gives us this:
We also get automatically redirected to /web. From the nmap scan we can assume there is an API running here as well.
To further enumerate I started gobuster while I took a look at the source code of the page.
Gobuster
gobuster dir -u http://10.10.11.224:55555/ -w /usr/share/wordlists/dirb/common.txt
The results of this gobuster scan were not very useful.
Looking at the source code, however, we find some extra, potentially useful, information.
function createBasket() {
var basket = $.trim($("#basket_name").val());
if (basket) {
$.ajax({
method: "POST",
url: "/api/baskets/" + basket,
headers: {
"Authorization" : sessionStorage.getItem("master_token")
}
}).done(function(data) {
localStorage.setItem("basket_" + basket, data.token);
$("#created_message_text").html("<p>Basket '" + basket +
"' is successfully created!</p><p>Your token is: <mark>" + data.token + "</mark></p>");
$("#basket_link").attr("href", "/web/" + basket);
$("#created_message").modal();
addBasketName(basket);
}).always(function() {
randomName();
}).fail(onAjaxError);
} else {
$("#error_message_label").html("Missing basket name");
$("#error_message_text").html("Please, provide a name of basket you would like to create");
$("#error_message").modal();
}
}
This is the bit of code that handles creating the basket in the front-end. By sending a POST request to /api/baskets/basket_name
the API creates the basket.
Now that we know that there is an api at /api
, I ran gobuster again in hopes that there are other accessible endpoints besides baskets
.
gobuster dir -u http://10.10.11.224:55555/api/ -w /usr/share/wordlists/dirb/common.txt
It appears there also is a /version
endpoint that reveals that the server is running request-baskets version 1.2.1. It also gives us a link to the source code on github, but we already knew this from the website's footer.
Creating a basket
Before digging into that source code let's try making our own basket and see what else we can find out.
Looking at the top bar we see there is a settings tab for the basket we created.
Forward URL looks interesting...
From the github documentation of request-baskets we can see this:
It is possible to forward all incoming HTTP requests to arbitrary URL by configuring basket via web UI or RESTful API.
And from the information given by the settings modal about the Proxy Response checkbox we know this:
Proxies the response from the forward URL back to the client
So it looks like we can configure our basket to forward the requests we send to it to a different URL and get the answer back.
And we also know that we have port 80 filtered.
Could we maybe configure the basket to send our request to itself on port 80 and relay the response back to us?
Foothold
Server-Side Request Forgery
After saving the configuration we get no errors. Now let's see what happens if we send a GET request to our basket.
Now we confirmed that request-baskets is vulnerable to SSRF, and we can now access the web server running on port 80.
User Flag
Looking at the page we notice Maltrail 0.53 is running. Doing a quick google search we find out this version of Maltrail is vulnerable to Unauthenticated OS Command Injection.
Referenece: https://huntr.dev/bounties/be3c5204-fbd9-448d-b97c-96a8d2941e87/
And we also find there is a publicly available exploit made for this vulnerability already!
First we have to reconfigure the basket to forward the request to http://127.0.0.1:8338/login
From here on I setup a netcat listener on port 4444
and ran the exploit against the target.
nc -nvlp 4444
And after a couple of seconds we get a connection back! By navigating to our user's home directory we find the user flag.
System Flag
Now that we got user, we can begin doing some basic system enumeration.
uname -a
id
sudo -l
From sudo -l
we get the following output:
Looking at GTFO Bins, we find this about systemctl:
Trying this out on the target machine:
And we got root! Now to finish this off we can navigate to the root directory and get the flag.
Summary
We started the engagement by running nmap and discovering ports 22 and 55555 open while ports 80 and 8338 were filtered.
Looking at the web server running on port 55555 we find request-baskets, a web service to collect arbitrary HTTP requests and inspect them via RESTful API or simple web UI.
Creating our own baskets and messing around with the settings we discover that it is vulnerable to SSRF, and using this we create a way to interact with the filtered port 80. This leads to exploitation through a bug in the login process of Maltrail which allows us to execute our own commands on the target system and obtain user access on the machine.
Finally, doing basic system enumeration we find that we are allowed to run systemctl status
as sudo with no password, which leads to privilege escalation to root.