Moving beyond T4 – Deconstructing Nmap Tuning
By Red Siege | July 6, 2022
Nmap -T4 -iL targets.txt
This is a very common scan string that many people use to get initial recon done on assessments and, to be honest, on a /24 you’re probably good to go and will get decent results in a reasonable amount of time with this method. There are cases where you will either have little time, a LOT of IP addresses to get through, or both. The most I’ve seen recently is five /16 address spaces and about twenty /24 spaces to scan in about three days. This requires a different approach that I’m going to walk through. I have seen this technique used all the way up to several /8 address spaces with good results. For the screenshots in this post, I used Shodan to search for a random list of fewer than 100 IP addresses to test my process. There were 77 IPs in my input file after sorting out duplicates.
Much of this approach was learned from one of my past colleagues, , on previous assessments and honed through usage across many differing environments over my career. This command is used as a part of a two-step process to discover hosts first and then perform full port scans against the identified hosts to get a full picture. Also, note that this scan method is in no way stealthy OR does it attempt avoid detection. This is intended to get results as fast as possible.
An example Nmap discovery command used against /16 ranges and larger was:
Nmap -Pn -n -sS -p 21-23,25,53,111,137,139,445,80,443,3389,5900,8080,8443 --min-rtt-timeout 30ms --max-rtt-timeout 100ms --max-retries 0 --max-scan-delay 0 --min-hostgroup 1024 -oA output --min-rate 5500 -vvv --open -iL inputfile
This command looks intimidating, but I’ll deconstruct each chunk and explain both why I chose it and the effects that I observed while using it.
-Pn: skipping host discovery seems like an odd thing to do when scanning a ton of hosts, but in my experience, it takes longer to run through this discovery and Nmap’s standard method of performing discovery than it does to just run a tuned scan on all IPs to see what you find.
-n: DNS resolution turned off – In my experience of running a massive scan against those /16s with 1024 hosts per round, I was finding a delay of about 10 minutes per round to get DNS resolution done. Multiplied over the MANY rounds that Nmap would have to run to cover a single /16, 1024 hosts at a time, it would have cost me hours of additional scanning. I can run DNS lookups when I get a live host list and not lose quite as much time.
-p: The ports list here was developed and weeded down to find LIVE (Up) HOSTS. Just that, not vulnerabilities, not sweet hacks, just live hosts. I’ve found that Linux hosts are very likely to either have FTP, DNS, SSH, Telnet, or a common web port open. On the other side I’ve found that Windows hosts generally have either SMB, RDP, or web ports open. VNC just grabs some of those weird one offs that you might otherwise miss. Again, in my experience, this gets a very good percentage of overall hosts. In my beginning example, the customer said I should find around 12,500 hosts and I found 12,367 hosts with open ports. I’d say that’s pretty good in an overall space of over 16M IP addresses. In the screenshot below, I was running just the ports list against my sample of 77 hosts.
–min-rtt-timeout and –max-rtt-timeout: These flags can be a bit tricky. A good rule of thumb is to run a quick ping (as shown below) if you can or figure out average network response times using another suitable method. Once you have an average ICMP echo time, you can add 25ms for –min-rtt-timeout and 100ms for –max-rtt-timeout. Based on the screenshot below, with an average of about 250ms ping time, I can set minimum at 275ms and maximum at 350ms. These numbers are an estimated starting point. It is possible that you may be able to shorten the times a bit if the results are still looking good. However, when you lower the round-trip times, make sure to keep an eye on the scan to determine if the results are what you expect. Common indications of trouble are a scan running much more slowly tan past attempts or much fewer hosts discovered. It should be apparent soon after kicking off a scan. If this happens; cancel the scan, adjust, and try again. Quick iteration of scans is a part of this method.
–max-retries: How many times do you want Nmap to retry sending a packet? At most I do 1, but usually I do 0. I’ve never found that multiple retries get me better results and they add to overall execution time quickly.
–max-scan-delay: Another basic and common flag for delay between packets. Since we’re going FAST, set that flag to 0.
–min-hostgroup: This flag can help speed things up but only to a point. I like to set this to 128 almost all the time, but on very large scans I’ll go to 512 or 1024 to try and grab larger groups. However, I keep an eye on processing speed and if I see scans starting to bog down, I’ll back off to a lower host group. This seems to depend on the host running the scan.
–min-rate: !!!DANGER!!! This is where I stomp on the gas, but it can be dangerous depending on the network you’re on and can lead to network saturation if you’re not careful. Sneak up on a high packet rate carefully. Start with a low number and ramp up either until the scan is going as fast as necessary or there are negative effects. On a previous /16 scan I reached a max rate of 5500 which was as far as I was willing to push and no issues arose. However, I was resident on the local network and running on a pretty beefy host. Your mileage my vary.
The end result of all of my tuning is that I was able to accurately scan a /16 in around 15 minutes total, which is a pretty good result for over 65,000 IPs. In my example set of 77 hosts for this post, I lowered my scan time from around six and a half hours at a T4 scan to under six seconds for my tuned scan, which is also a significant improvement.
My final scan string for the example:
nmap -vvv -Pn -n -sS -p 21-23,25,53,111,137,139,445,80,443,3389,5900,8080,8443 --min-rtt-timeout 275ms --max-rtt-timeout 350ms --max-retries 0 --max-scan-delay 0 --min-hostgroup 128 -iL AllIPs.txt -oA Tuned
Although my sample is a small range of hosts, it’s apparent how execution time could add up over thousands or hundreds of thousands of hosts. The next step in a live test would be to create a file of up hosts using grep and cut.
grep "Status: Up" Tuned.gnmap | cut -d " " -f2 | tee UpHosts.txt
Once that file is created I would change the ports specification in the Nmap command from the narrow list to -p- (to check ports 1-65535) and adjust -min-rtt-timeout and –max-rtt-timout if necessary for speed or impact on the network. Once these adjustments are made a full port scan is kicked off to find open non-standard ports and gain additional coverage of the live hosts. This full port scan should run quickly as no empty IP space should be included.
A full port scan string example would look like this.
nmap -vvv -Pn -sS -p- --min-rtt-timeout 275ms --max-rtt-timeout 350ms --max-retries 1 --max-scan-delay 0 --min-hostgroup 128 -iL UpHosts.txt -oA Tuned_FullPort
To sum up, while timing templates are an easy place to start with Nmap and provide some flexibility, manual tuning can help to get accurate results as fast as possible and get to the fun of actually hacking against your targets.
Alex Norman has over 20 years of experience in IT and security including nearly 10 years as a penetration tester across Fortune 500 companies, cloud environments, and all levels of government systems. Prior to information security he worked for 10 years as a web developer. Additionally he frequently volunteers at industry conferences including serving as Co-director for BSidesDC for 5 years.
Related StoriesView More
By Red Siege | March 4, 2024
By Alex Reid, Current Red Siege Intern A long-time tactic of threat actors and offensive security professionals alike, tampering with LSASS.exe in order to recover credentials remains a highly […]Learn More
By Red Siege | February 15, 2024
By: Justin Palk, Senior Security Consultant SSH is an incredibly valuable tool for penetration testing. It provides us with a secure channel for administering machines, remotely executing tools, transferring […]Learn More
By Red Siege | January 22, 2024
By: Alex Reid, Current Red Siege Intern Introduction This blog post accompanies the release of an open source tool called GraphStrike which can be found here. Those familiar with my […]Learn More