Hack The Box: Cap

Jump Ahead: EnumUserRootResources


To solve this machine, we begin by enumerating open ports – finding ports 21, 22, and 80 open. On the webserver, we are able to exploit an Insecure Direct Object Reference (IDOR) vulnerability to obtain system credentials as the nathan user. Using the credentials, we are able to SSH into the machine, and read user.txt. Through automated, local enumeration, we learn a system package is incorrectly configured to allow setuid. Using this knowledge, we are able to exploit the package to get a shell as root – gaining access to root.txt.


Like all machines, we begin by enumerating open ports – finding ports 21, 22, and 80 open.

$ sudo nmap -v -p- $RHOST
$ sudo nmap -p21,22,80 -sV -A -oA enum/nmap/tcp-scripts $RHOST
# Nmap 7.91 scan initiated Sat Jun  5 19:45:34 2021 as: nmap -p21,22,80 -sV -A -oA enum/nmap/tcp-scripts
Nmap scan report for
Host is up (0.047s latency).

21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
|   256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
|_  256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
80/tcp open  http    gunicorn
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 404 NOT FOUND
|     Server: gunicorn
|     Date: Sun, 06 Jun 2021 00:45:49 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 232
|     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|     <title>404 Not Found</title>
|     <h1>Not Found</h1>
|     <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Sun, 06 Jun 2021 00:45:44 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 19386
|     <!DOCTYPE html>
|     <html class="no-js" lang="en">
|     <head>
|     <meta charset="utf-8">
|     <meta http-equiv="x-ua-compatible" content="ie=edge">
|     <title>Security Dashboard</title>
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <link rel="shortcut icon" type="image/png" href="/static/images/icon/favicon.ico">
|     <link rel="stylesheet" href="/static/css/bootstrap.min.css">
|     <link rel="stylesheet" href="/static/css/font-awesome.min.css">
|     <link rel="stylesheet" href="/static/css/themify-icons.css">
|     <link rel="stylesheet" href="/static/css/metisMenu.css">
|     <link rel="stylesheet" href="/static/css/owl.carousel.min.css">
|     <link rel="stylesheet" href="/static/css/slicknav.min.css">
|     <!-- amchar
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Sun, 06 Jun 2021 00:45:44 GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Allow: HEAD, GET, OPTIONS
|     Content-Length: 0
|   RTSPRequest: 
|     HTTP/1.1 400 Bad Request
|     Connection: close
|     Content-Type: text/html
|     Content-Length: 196
|     <html>
|     <head>
|     <title>Bad Request</title>
|     </head>
|     <body>
|     <h1><p>Bad Request</p></h1>
|     Invalid HTTP Version &#x27;Invalid HTTP Version: &#x27;RTSP/1.0&#x27;&#x27;
|     </body>
|_    </html>
|_http-server-header: gunicorn
|_http-title: Security Dashboard
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 :
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), 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).
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
1   43.24 ms
2   43.29 ms

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jun  5 19:47:59 2021 -- 1 IP address (1 host up) scanned in 144.90 seconds

From the results, nothing immediately stands out. Since FTP is running, we attempt to log in anonymously, however, this is disabled. Next, we enumerate port 80 using tools like gobuster and nikto. Unfortunately, these tools do not yield any useful results. Going to the webserver in a browser, we are presented with a website that appears to host several local network tools.

Clicking on the different links, we learn the “Security Snapshot” page generates a pcap, the “IP Config” page shows the machine network interfaces, and the “Network Status” page prints a dump of netstat.

Getting User

Since we did not find any further results from our automated tools, we decide to dig deeper into the web pages. Reflecting back on the “Security Snapshot” page, we generated a pcap, the URL path was /data/1. This suggests a possible Insecure Direct Object Reference (IDOR) vulnerability may exist, if there is no authorization checks around the request. To test this, we can change this number, and monitor the results. In the case the object is invalid, we are redirected to the dashboard, however, when we set the number to “0”, we are given a valid capture file that we are able to download.

After we download the capture file, we open it in a packet analysis tool, such as Wireshark. To help hunt for interesting information, we open the “Statistics” menu, and launch the Protocol Hierarchy window. In it, we see there are FTP packets that were captured.

Since FTP is a clear-text protocol, we know there may be credentials captured that we can get. To check this, we set the display filter to “ftp”. Once we set the filter, within the first few packets, we see credentials for the nathan user.

As FTP on a linux machine is generally connected to a user account, we attempt the use the credentials to log in via SSH. Doing so, we get a shell as nathan, and find user.txt in his home folder.

Getting Root

Since we now have local access to the machine as the nathan user, we begin our local enumeration. Since we have credentials, we start by running sudo -l to check if we are able to run any commands as another user. Unfortunately, this didn’t work, so we move on. As the webserver is not hosting a database, nor are credentials of any sort used, we decide to launch linpeas to automate the enumeration for us. Looking through the results, we notice /usr/bin/python3.8 has the setuid capability set.

This capability allows us to change the user ID of the python process. This means that we are able to execute python commands as any user, as long as we know their user ID. Since we know root‘s user ID is “0”, we should be able to use python to get a shell as root. To do this, we launch python, import the “os” module, change the user id, and execute bash. Once we do that, we now have a shell as root, and can now read root.txt.

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!