Here is a comprehensive Nmap methodology structured for attacking boxes on CTF platforms like TryHackMe and HackTheBox. A consistent workflow is essential to ensure you don’t miss critical entry points and maintain efficiency during your enumeration.
Before diving into deep enumeration, you need a quick overview of what is open.
-
Step I: You should be able to simply copy the commands into a terminal emulator and hit ENTER, instead of having to take the error-prone approach of modifying each one every time just to set up the correct target IP address.
- Command:
export RHOST="<IP_ADDRESS>"
- Command:
-
Step II: Identify the surface area. Do not attempt service enumeration yet; just find the open ports.
- Command:
sudo nmap -sS -sU -p T:1-65535,U:--top-ports 100 --min-rate=1000 -T4 $RHOST -v --reason -oA ${RHOST}_discovery-sS: Because you added -sU, you must explicitly tell Nmap to also perform the TCP SYN scan (-sS). If you only use -sU, it will only scan UDP ports.-sU: This is the flag that tells Nmap to perform a UDP scan. It is highly useful because some boxes hide critical services on UDP ports, such as SNMP.-p T:1-65535,U:--top-ports 100: This is a critical optimization for Phase 1. Instead of scanning all 65,535 UDP ports (which would ruin the "rapid" nature of this phase and could take hours), this specifies scanning all 65,535 TCP ports (T:) but restricts the UDP scan (U:) to only the 100 most common UDP ports. *--min-rate=1000: Speeds up the scan by sending a minimum of 1000 packets per second.--min-rate=1000 & -T4: You still keep the aggressive timing template and minimum packet rate to force the scan to proceed quickly.-T4: Set timing template (higher is faster)-v: Increase verbosity level (use -vv or more for greater effect)--reason: Display the reason a port is in a particular state-oA ${RHOST}_discovery: Outputs results files in the .nmap, .gnmap and .xml formats for further analysis and tool chaining.
- Command:
Once you have the list of open ports, focus your resources on those specific targets.
-
Step I: Create a new environment variable named RHOST_OPEN_PORTS that's assigned to a string consisting of a comma-separated list of open ports discoved in Phase 1. This list will be passed to the enumeration command afterwards.
- Command:
export RHOST_OPEN_PORTS=$(grep "open" discovery_$RHOST.gnmap | awk -F" " '{print $4}' | cut -d "/" -f 1 | tr '\n' ',' | sed 's/,$//')
- Command:
-
Step II: Discover vulnerabilities like null sessions, SMB shares, or HTTP headers, and determine service/version information.
- Command:
sudo nmap -p $RHOST_OPEN_PORTS -sC -sV -oA ${$RHOST}_initial_scan $RHOST-p: Only scan the ports discovered in Phase 1 (e.g., 80, 443, 22, 445).-sC: Runs default Nmap scripts.-sV: Probes open ports to determine service/version information.-oA ${$RHOST}_initial_scan: Outputs results files in the .nmap, .gnmap and .xml formats for further analysis and tool chaining.
- Command:
If the standard scripts don't yield an immediate path forward, leverage the Nmap Scripting Engine (NSE) for specific services.
-
Step I: Check for known CVEs or deep-dive into the configuration of running services, saving all specialized script outputs to clearly named files tied to the specific target.
-
Common Scenarios:
- SMB:
nmap --script smb-enum* -p 139,445 -oA ${$RHOST}_smb_enum $RHOST - HTTP:
nmap --script http-enum -p 80,443 -oA ${$RHOST}_http_enum $RHOST - FTP:
nmap --script ftp-anon -p 21 -oA ${$RHOST}_ftp_enum $RHOST
- SMB:
-
Step II: Since you already created the $RHOST_OPEN_PORTS variable in Phase 2, you can actually pass that directly into a vulnerability scan to check every open port for known CVEs simultaneously:
-
Command:
sudo nmap -sV --script vuln -p $RHOST_OPEN_PORTS -oA ${$RHOST}_vuln_scan $RHOST- This is an incredibly powerful command for CTFs. Because $RHOST_OPEN_PORTS ensures Nmap only interacts with ports that are actually open, this heavy vulnerability scan will finish much faster than if you ran it blindly against the whole machine!
-
Command:
sudo nmap -sV --script nmap-vulners -p $RHOST_OPEN_PORTS -oA ${$RHOST}_vulners_scan $RHOST- This is arguably the most popular custom NSE script. It takes the service versions Nmap discovers and automatically queries the Vulners.com API to see if any known Common Vulnerabilities and Exposures (CVEs) match those exact versions.
-
Command:
sudo nmap -sV --script vulscan/vulscan.nse -p $RHOST_OPEN_PORTS -oA ${$RHOST}_vulscan_scan $RHOST- Similar to vulners, but instead of querying an API over the internet, vulscan turns Nmap into a completely offline vulnerability scanner. It queries local databases (like Exploit-DB, SecurityFocus, and CVE dictionaries) stored directly on your machine.
-
- Bypass Ping Blocks: Often, boxes on THM/HTB are configured to drop ICMP (ping) requests. Use the
-Pnflag to tell Nmap to treat the host as "up" even if it doesn't respond to pings. - UDP Scanning: While rare, some boxes hide critical services on UDP ports (like SNMP). If you are truly stuck, a targeted UDP scan (
-sU) can sometimes be the "aha!" moment. - Organized Documentation: Always keep a log. Using the
-oAflag is good, but piping your findings into a tool like Obsidian or a dedicated Notebook ensures you don't lose track of version numbers or potential CVE strings. - Limit Your Scope: Don't over-scan. Running massive, noisy scans against a target during a live competition can sometimes cause instability or lead to detection if you are playing in a simulated corporate environment. Stick to what you need.