October 20, 2026
Cap β HTB Walkthrough (or: how a stray pcap handed me root)
Hey, welcome in. i am a pentester by day, still-rooting-boxes-for-fun by night. This is my first proper lab writeup, so consider this theβ¦

By Lawrencegeoffrey
5 min read
Hey, welcome in. i am a pentester by day, still-rooting-boxes-for-fun by night. This is my first proper lab writeup, so consider this the opening entry in what I'm hoping turns into a running series. Today's victim is Cap, an easy-rated Linux box on Hack The Box, and I'm walking the whole thing start to finish: recon through root.
Fair warning, "easy" doesn't mean "forgettable." Cap chains together two bugs that show up constantly in actual paid engagements β not just CTF land β so even if you've rooted forty boxes already, this one's worth doing for the muscle memory alone.
I'll drop a hint or two before I hand over the answer, in case you want to poke at it yourself first. They'll look like this:
Hint_ A nudge, not the whole answer._
Alright. Let's go.
The Machine
Easy-rated Linux box, two realistic vuln classes stacked into one short chain: a web-layer access control flaw, and an OS-level privesc path that's invisible if you don't know exactly where to look.
Target: 10.129.135.183
Initial Scan
First rule of showing up to any box: find out what's actually answering the door.
nmap -p- -sS -T4 10.129.135.183nmap -p- -sS -T4 10.129.135.183
Fig 1 β full nmap scan, three open ports looking very unbothered
-p- scans all 65,535 ports instead of nmap's default top-1000 β slower, but nothing slips through. -sS is a SYN scan, -T4 speeds the timing up because this is a lab and nobody's listening for stealth.
Result: 21 (FTP), 22 (SSH), 80 (HTTP). Small attack surface β a website, a file transfer service, and a shell I can't touch yet without creds. Website it is.
Inspecting the Website β Finding the IDOR
Hint_ If a URL ends in a number, that number is an invitation._
The site's a dashboard for a user named Nathan, complete with a "Security Snapshot" section offering downloadable pcap files, served off URLs like:
10.129.135.183/data/0
10.129.135.183/data/110.129.135.183/data/0
10.129.135.183/data/1
Fig 2β /data/1, suspiciously empty
Fig 3β /data/0, actual packets inside
See the problem? No session check, no ownership check β just an integer sitting in the URL, politely waiting for someone to change it. That's a textbook IDOR (Insecure Direct Object Reference): the server trusts whatever reference the client hands it, with zero checks on whether that client should actually see it.
IDOR lives under OWASP's Broken Access Control category β the #1 spot on the 2021 Top 10 β and it is everywhere in real assessments, usually hiding on API endpoints or download features that look exactly like this one.
So what's a pcap, anyway? A packet capture β a raw recording of everything that crossed the wire. Whether you can actually read it depends entirely on whether the protocol inside bothered to encrypt anything.
Analyzing the Pcap β Credentials in the Clear
FTP doesn't encrypt. That's not a Cap-specific oversight, that's just FTP being FTP since forever.
Cracking open 0 (1).pcap in Wireshark and filtering for FTP traffic hands over the login exchange with zero resistance:
Fig 4 β Wireshark, FTP PASS packet, password sitting right there in plain text
Username Nathan from the dashboard, password straight out of the packet. A full credential pair, handed over for free, because the app captured real traffic and then let anyone download it.
If this had been FTPS or SFTP instead, that pcap would've been dead weight. The actual lesson isn't "learn Wireshark" β it's that plaintext protocols have no business carrying real credentials. Full stop.
Initial Access
SSH was sitting open the entire time, just waiting on something valid to throw at it:
ssh nathan@10.129.135.183ssh nathan@10.129.135.183Straight in. user.txt was sitting in the home directory, no further digging required.
Fig 5 β SSH login, welcome banner and all
Fig 6 β user.txt β flag blurred, HTB's rules, not negotiable
Tried su root with the same password on the off chance of reuse β no dice. So root needs an actual path, not a lucky guess.
Privilege Escalation
Hint_ Linux capabilities are SUID's more precise sibling. One command, one very specific superpower._
Instead of reaching for automated tooling, I checked capabilities by hand:
getcap -r / 2>/dev/nullgetcap -r / 2>/dev/nullMost of what comes back is boring and expected β ping, traceroute, the GStreamer helper, all legitimately needing raw network access. One line isn't boring:
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eipCapabilities, but what do they actually mean? Think of them as SUID with a scalpel instead of a sledgehammer β instead of "this whole binary runs as root," it's "this binary gets exactly one privileged power." Here, that power is cap_setuid: the ability to change a process's UID, including setting it straight to 0. Normally that's a root-only move. This one Python binary gets an exception.
That's enough to win. If Python can set its own UID to root, a three-line script run through that exact binary becomes a root shell:
python
import os
os.setuid(0)
os.system("/bin/bash")import os
os.setuid(0)
os.system("/bin/bash")
Fig 7 β root shell, root.txt β flag blurred again
Small gotcha worth flagging: running cd ~ right after popping root still dropped me back in /home/nathan, because $HOME was inherited from before the UID change and never got reset β even with effective UID 0. cd /root sidesteps it.
Why This Actually Matters
Easy to write these off as CTF puzzles with no bearing on real work. They're not.
IDOR rarely looks this clean in production β usually it's a UUID instead of a sequential integer, or buried in a JSON body instead of sitting in the URL β but the flaw underneath is identical. Any endpoint taking an ID as a parameter deserves this test.
Loose capabilities are a growing finding as environments move away from classic SUID toward capability-based permissions, often without anyone fully grasping what they just granted. getcap -r / 2>/dev/null costs nothing and should be standard on every Linux privesc checklist β automated scanners miss this class of misconfig more than you'd think.
Neither of these needed a CVE or custom tooling. Just enumeration, and actually reading the output instead of skimming past it.
Conclusion
Nothing exotic about Cap's exploitation path, but it's a genuinely good teaching box β a Broken Access Control bug leaking creds, followed by a privesc that's trivial once you know to check, and invisible if you don't.
If you're newer to this: make getcap -r / 2>/dev/null a reflex on every Linux box, and get in the habit of poking any numbered URL parameter you see. Both take seconds. Both pay off more than CVE-chasing ever will.