6 weeks of pentesting: what I still didn't know
The quiz that wrecked me
I got cocky. Six weeks of daily pentesting, every TryHackMe module done, PortSwigger started. I felt ready. So I built myself a 45-question quiz covering everything I'd touched: Linux, Bash, networking, Nmap, offensive Python, Burp Suite.
31/45. 69%.
I stared at the score for a good ten seconds. I was expecting 80, maybe 85. Not this. And the frustrating part is I didn't feel like I'd learned nothing. I just... learned things wrong. Half-known concepts that crumbled the moment you poked at them.
Where it fell apart
The quiz slapped me in three very specific places.
Networking, week 3. I was mixing up filtered and closed in Nmap. When asked to list the 10 most common ports, I could get maybe 7 or 8. And I was absolutely convinced that * * * in traceroute meant "connection dead." Spoiler: it doesn't.
Offensive Python, week 5. My port scanner worked. But why the Semaphore? No real idea. Something about "limiting connections." I couldn't explain what actually breaks if you remove it. Same deal with hashlib: I was typing the encode → hash → hexdigest pipeline out of habit without understanding each step.
Burp Suite, week 6. I could use Proxy and Repeater just fine. But if someone asked me in an interview "what's the difference between Intruder and Decoder," I would've stumbled. And IDOR... I kept saying "it's a vulnerability in the URL." Which is wrong. More on that later.
Filtered vs closed, or how I got it wrong for three weeks
Sounds dumb when you say it out loud. But this is THE classic trap when you're starting out with Nmap.
closed means the port answered. It sent back a RST packet. It's telling you "yeah I'm here, but nobody's home." The port exists, there's just nothing listening on it.
filtered means dead silence. Nothing comes back. Probably a firewall ate your packet and didn't bother responding. Nmap has no idea whether the port is open or closed. All it knows is it got nothing back.
Here's why that matters: closed is information. filtered is the absence of information. Big difference when you're running a scan and trying to decide what to dig into first.
The traceroute stars
Another thing I had wrong. When traceroute shows * * * on a hop, I was sure the network was dead at that point. That packets couldn't go further.
Except no. The router at that hop just decided not to reply to ICMP TTL Exceeded messages. That's it. The packet keeps going, and often the next hops respond just fine. ISPs disable this on their routers all the time, it means nothing.
I could've figured this out in two seconds by checking whether the hops after it responded. But nope, I'd decided it meant "broken" and moved on.
10 ports, from memory, now
I "knew" them. Air quotes. I'd seen them come up in scans, I vaguely knew 22 was SSH and 80 was HTTP. But all 10 at once, in order, no thinking? Nah.
| Port | Service |
|---|---|
| 21 | FTP |
| 22 | SSH |
| 23 | Telnet |
| 25 | SMTP |
| 53 | DNS |
| 80 | HTTP |
| 443 | HTTPS |
| 445 | SMB |
| 3389 | RDP |
| 3306 | MySQL |
I drilled them. No magic trick. Just repetition. Tested myself every morning before starting a module. After four days I could rattle them off without thinking. This is the kind of stuff you don't learn by reading a course. You learn it by forcing yourself to spit it back out.
Rewriting the port scanner bare-handed
To lock in the Python stuff, I did something that turned out to be weirdly effective: I rewrote my port scanner from scratch. Not tweaking the old one. Blank file, go.
First try, I forgot the Semaphore. Script blew up with Too many open files after about 200 ports. Same exact error as when I first wrote it three weeks earlier. Except this time I understood why in about one second. Without the Semaphore the script opens hundreds of sockets at once and the OS shuts you down.
For hashlib, I wrote the pipeline on a whiteboard until it stuck:
string → .encode() → hashlib.md5() → .hexdigest() → readable hash
encode() because hashlib works on bytes, not strings. hexdigest() because raw hash output is unreadable binary. Every step has a reason, and now I can explain them without checking the docs.
Burp: being able to name what you use
My issue with Burp wasn't that I couldn't use it. It's that I couldn't talk about it precisely. Using Repeater, sure. Explaining it to someone? Different story.
So here it is, plain:
Proxy sits between your browser and the server, intercepting traffic in real time. Starting point for everything.
Repeater lets you grab a captured request, tweak it by hand, and resend it. One send, one response, you analyze. Manual testing.
Intruder does the same thing but automated, swapping in different payloads each time. Fuzzing, brute forcing, that kind of thing.
Decoder is just an encoding/decoding tool. Base64, URL encoding, hex. Nothing fancy.
Site Map shows you everything Burp discovered during your session: pages, endpoints, parameters, all laid out as a tree.
So Repeater vs Intruder? Repeater is you doing it by hand. Intruder is automated. That's it.
IDOR is not in the URL
This one stung a bit. I kept saying "the vulnerability is in the URL" because well, you exploit IDOR by changing an identifier in the URL. Like /api/files/1.txt, you swap it to /api/files/2.txt and grab someone else's file.
But the vulnerability isn't in the URL. The URL is just the attack vector. The actual flaw is that the server gets your request and hands over the file without checking whether you're allowed to see it. It's a server-side authorization problem.
The client exploits. The server is vulnerable. When you're writing a pentest report, that distinction matters a lot. You don't write "the URL is vulnerable." That doesn't mean anything.
What I'm taking from this
Finishing a module doesn't mean you've mastered the topic. There's a huge gap between "I've seen this before" and "I can explain it off the top of my head." The quiz made that gap impossible to ignore.
What actually worked for me:
- Testing myself honestly, not just rereading my notes
- Pinpointing the exact gaps (not "networking is fuzzy" but "I confuse filtered and closed")
- Working on each weak spot specifically, one at a time
- Checking it actually stuck: drills, rewrites, labs with no notes open
69% isn't a bad score. It's a diagnosis. The stuff I got wrong that week is exactly what I drilled the week after. And now if someone asks me the difference between filtered and closed, I won't hesitate for a second.