November 5, 2026
Beating an IDS at Its Own Game: What I Learned Scanning Quietly
A few sessions ago I wrote about getting my first root shell on an HTB box. This time, the challenge wasn’t getting in — it was staying…
By Xmastaheer
3 min read
A few sessions ago I wrote about getting my first root shell on an HTB box. This time, the challenge wasn't getting in — it was staying invisible while I looked around.
HTB Academy's "Network Enumeration with Nmap" module is the third stop on the CPTS path, and it's the first time the course explicitly asked me to think like someone being watched, not just someone scanning a box with nobody paying attention.
The setup
The final lab gave me a target protected by a simulated IDS/IPS system. The twist: there was a public status page — /status.php — showing exactly how many alerts I'd triggered so far, out of a maximum before getting banned. When I checked it mid-exercise, it already read 50 out of 75. Not a lot of room left to work with.
That single detail changed everything about how I approached the rest of the box. No default -sS -sC -sV blast across all 65,535 ports. No aggressive timing templates. Every scan had to earn its place.
Scanning like you're trying not to be noticed
The module had already covered why this works, not just how. A regular SYN scan sends packets and waits for a reply — fine, until an IDS starts pattern-matching the traffic and flags it. The fix wasn't complicated: slow down. -T1 and -T2 timing templates, --max-retries 1 instead of the default ten, and deliberately scanning a short list of likely ports instead of sweeping everything.
It felt counterintuitive at first — I kept wanting to just run a full port sweep and get it over with. But a full -p- scan under -T1 timing would have taken the better part of an hour, and more importantly, it would've been exactly the kind of loud, obvious behavior the whole exercise was testing me to avoid.
A flag hiding in a DNS banner
A quiet UDP scan on port 53 turned up something unexpected sitting right in the version field:
53/udp open domain (unknown banner: HTB{...})53/udp open domain (unknown banner: HTB{...})This tied directly back to something the module taught earlier — DNS servers can be queried for their own version string (version.bind), and if an administrator hasn't locked that down, it leaks straight to anyone who asks. In this case, it had been deliberately left exposed to teach exactly that lesson. One flag down, with barely a whisper of scanning traffic.
The part where I got stuck
Then came the real test. A targeted scan across the usual suspects — SSH, HTTP, SMB, IMAP, POP3 — showed only two services actually reachable. Everything else came back filtered. Not closed. Filtered. Which meant something was there, just hidden behind a firewall rule actively dropping my packets.
I tried the obvious things. Direct netcat connections — timed out. Raw rsync client — timed out. ACK scans to map the firewall rules — still filtered. I spent a genuinely frustrating stretch of time trying increasingly specific ports (MySQL, PostgreSQL, NFS, rsync) based on a hint about the client needing a service for "large amounts of data," convinced I was missing some exotic protocol.
I wasn't. I was overcomplicating it.
The technique that actually worked
Buried in the module's own reading was the answer I'd walked straight past: many firewalls implicitly trust traffic that looks like it's coming from a DNS server, because blocking it would break ordinary internet access for everyone behind that firewall. Which means if you source your own scan traffic from port 53, instead of a random high port, some of those firewall rules simply don't apply to you.
nmap -nv --source-port 53 <target_ip>nmap -nv --source-port 53 <target_ip>One scan, sourced from port 53 instead of nmap's default random port, and a service that nine separate direct-connection attempts had failed to even see suddenly appeared:
50000/tcp open ibm-db250000/tcp open ibm-db2A direct connection, same trick applied:
nc -nv -p 53 <target_ip> 50000nc -nv -p 53 <target_ip> 50000And there it was — the final flag, sitting in a banner on a port that had been completely invisible until I stopped trying to force my way in and instead borrowed the one piece of traffic the firewall already trusted.
What actually stuck with me
The technical trick is genuinely useful and I'll use it again. But the bigger lesson is softer than that: when I hit a wall, my instinct was to escalate — try more ports, more protocols, more aggressive scans. The actual answer was already sitting in material I'd read an hour earlier. I just hadn't connected it to the problem in front of me yet.
That's going to keep happening throughout this path, I suspect. CPTS doesn't seem interested in testing whether I can memorize fifty tools. It seems a lot more interested in whether I slow down enough to actually use the three or four tools I already have, correctly.
Writeup with the full command history, including the dead ends, is on GitHub: https://github.com/TaheerAbdullah10
Next up: Footprinting, and starting to build real comfort with enumerating specific services rather than just finding them.