EASY LINUX
CAP
📅 March 09, 2026 ⏱ 6 min read
IDOR PCAP Linux Capabilities
Target IP
10.10.10.245
OS
Linux
Difficulty
Easy
Platform
HackTheBox

Recon

Three ports came back open — FTP, SSH, and an HTTP service running gunicorn. The web app on port 80 identified itself as a "Security Dashboard," which was immediately the most interesting thing on the box.

$ nmap -sC -sV -oN nmap/initial 10.10.10.245
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2
80/tcp open  http    gunicorn
# Service info: gunicorn confirms a Python web app behind it
  

FTP on 21 is worth keeping in mind — vsftpd without explicit TLS configured means any captured auth is plaintext. I noted that and moved to the web app first.

Enumeration

The web app presents a network security dashboard after login. The most interesting feature is "Security Snapshot (5 Second)" — it runs a packet capture for five seconds and then shows you stats and a download link. The download URL pattern is /data/1, which is my capture ID.

I changed the ID to /data/0. The server handed me a PCAP without any access check — classic IDOR. The file at ID 0 is a capture taken when the server first started up, which means it contains whatever traffic hit the box at boot time.

Key Finding
The /data/<id> endpoint performs no ownership check — decrementing the ID to 0 returns a PCAP captured at server startup belonging to a different session.

Analyzing the PCAP

I opened the file in Wireshark and filtered on ftp. Two packets stood out immediately:

# Wireshark display filter: ftp
Request: USER nathan
Request: PASS Buck3tH4TF0RM3!
# Plaintext FTP authentication captured at server startup
  

The credentials were right there — nathan / Buck3tH4TF0RM3!. FTP sends everything in the clear, so any packet capture that includes an authentication sequence will expose the password verbatim.

Foothold

I tried the captured credentials against SSH rather than FTP — SSH is far more useful for an interactive shell, and people reuse passwords across services constantly.

$ ssh nathan@10.10.10.245
nathan@10.10.10.245's password: Buck3tH4TF0RM3!

nathan@cap:~$
# Shell as nathan — password reuse from FTP to SSH
  

Direct shell as nathan. User flag is sitting in /home/nathan/user.txt.

Privilege Escalation

Standard Linux privesc checklist: sudo rights, SUID binaries, cron jobs, writable paths, and — often skipped — Linux capabilities. I ran getcap first since it's quick and frequently rewarding on HTB boxes.

$ getcap -r / 2>/dev/null
/usr/bin/python3.8 = cap_setuid+ep
  

That's the entire privesc right there. cap_setuid lets the process call setuid(0) to set its effective UID to root without needing the SUID bit set on the binary. The ep flag means the capability is both permitted and effective — it applies immediately on execution.

Linux Capability Abuse — cap_setuid

Unlike SUID, Linux capabilities are fine-grained privileges attached to a binary. cap_setuid+ep on the Python interpreter means I can call os.setuid(0) from Python and the kernel will allow it, because the process has the required capability. This gives me the same result as a SUID Python binary — arbitrary UID switching to root.

$ python3 -c "import os; os.setuid(0); os.system('/bin/bash')"
root@cap:~#
# os.setuid(0) succeeds because of cap_setuid+ep — root shell
  

Root shell. One line. /root/root.txt is readable.

Flags

User Flag
/home/nathan/user.txt
Root Flag
/root/root.txt

Lessons Learned

Defender Note
Audit Linux capabilities with getcap -r / regularly. cap_setuid on any interpreter (Python, Perl, Ruby) is essentially a root backdoor. Remove the capability with setcap -r /usr/bin/python3.8 and enforce FTP over TLS or migrate to SFTP entirely.
← Back to Blog