NMAP Tips: RTFM?

NMAP TL;DR

It's a tool used for portscanning and this post will explore some of the common and useful flags that can be used while scanning to pick up usful information about targets.

What Is NMAP?

Nmap or Network mapper is an open source tool for network discovery and security analysis. It is used by many people in different job roles, from system administrators to penetration testers to developers and everyone inbetween. The primary uses are network discovery and analysis.

Nmap uses raw IP packets to determine what hosts are available on a network,it can also be used to identify what services (application name and version), operating system verions, what filters/firewalls are in use, and dozens of other characteristics.

Nmap runs on all major computer operating systems, and official binary packages are available for Linux, Windows, and Mac OS X. Typically nmap is used on the command line by calling nmap however there is also a GUI available in the form of zenmap.

In addition to the core tooling the nmap suite also includes a netcat-like tool on steroids(ncat), scan results comparison (Ndiff), and a packet generation and response analysis tool (Nping).

Port Scanning?

Port scanning is the act systematically scanning a computer's ports/services. Since a port is a place where information goes in and out of a computer, port scanning identifies openings into a computer. Port scanning has legitimate uses in managing networks, system administration and other network based tasks. However it can also be malicious in nature if someone is looking for a weakened access point to break into a system.

Typically it is one of the first techniques used to identify weaknesses or footholds into a network. One thing to note though is that the act of port scanning does fall under active recon and will send traffic to a target rather than passive scanning using things like OSINT.

Port States

Before we dive into the different flags, it is worth understanding that when scanning a port can have three states and depending on the scan type will depend on why the state has been returned. The main three are:

  • Open: Open means that an application or service is listening for connections or traffic on the on the target system.
  • Closed: Closed ports have no application listening on them. Ports are classified as unfiltered when they are responsive to Nmap's probes, but Nmap cannot determine whether they are open or closed.
  • Filtered: Filtered means that a firewall, filter, or other network obstacle is blocking the port so that Nmap cannot tell whether it is open or closed.

Nmap reports other state combinations such as open|filtered and closed|filtered when it cannot determine which of the two states describe a port.

Some Common Commands

Nmap is one of the most used tools when carrying out infrastructure-like engagements. As such there are many different flags and command combinations that can be used to identify weaknesses and interesting information about hosts. The following sets of commands can be used to scan different types of hosts, each flag is explained and has been tuned for maximum performance.

Basic Scanning Options

There are three fairly commmon flags used in nmap for types of scanning, these are TCP connect scans, SYN & UDP. The flags for thes are shown below and a brief explanation of how they work is included too:

  • -sT: TCP connect scan is the default TCP scan type when SYN scan is not an option. This is selected when a user doesn't have elevate priveleges on a machine and therefore does not have permission to send raw packets or is scanning IPv6 networks. Instead of writing raw packets as most other scan types do, Nmap asks the underlying operating system to establish a connection with the target machine and port by issuing the connect system call and a TCP three way handshake. This is the same high-level system call that web browsers, P2P clients, and most other network-enabled applications use to establish a connection.
  • -sS: This flag is a SYN scan and it is the default, most popular scan option when using nmap. It can be performed quickly, scanning thousands of ports per second on a fast network or modern network. SYN scaning is relatively unobtrusive and stealthy, since it does not complete the TCP handshake, rather it sends syn and waits for a syn-ack response. Based on the response the port will then come back as either open, closed or filtered:
Probe Response Assigned State
TCP SYN/ACK response open
TCP RST response closed
No response received or ICMP unreachable errors filtered
  • -sU: UDP scan works by sending a UDP packet to every targeted port. For most ports, this packet will be empty (no payload), but for a few of the more common ports a protocol-specific payload will be sent. Based on the response, or lack thereof, the port is assigned to one of four states as detailed in the table below:
Probe Response Assigned State
Any UDP response from target port open
No response received after retransmission open|filtered
ICMP port unreachable error (type 3, code 3) closed
Other ICMP unreachable errors (type 3, code 1, 2, 9, 10, or 13) filtered
  • -sV: Version scan, this will probe specific services and try to identifiy what version of a particular application or service is running on that port.
  • -O: OS Scan, this will send additional probes in order to determine what operating system the host is likely running.

Probing (-P<x>)

There are so many different options when it comes to probing a service however here are some of the specifics when it comes to probing things.

  • -Pn: Don't ping the host, assume it's up - this is useful for hosts that don't respond to or block ping requests.
  • -PB: Default probing, scan port 80,443 and send an ICMP to the target.
  • -PE: Use a default ICMP echo request to probe a target
  • -PP: Use an ICMP timestamp request
  • -PM: Use an ICMP network request

Default Timing Options (-Tx)

Sometimes when tuning a scan you might want to have certain options set to speed up or slow down scanning depending on if you want to be noisy or stealthy!

  • -T5: Insane; Very aggressive timing options, gotta go fast! This will likely crash unstable networks so shy away from it, in some instances it will also miss open ports due to the level of aggression.
  • -T4: Aggressive; Assumes a stable network, may overwhelm some networks if not setup to cope.
  • -T3: Normal; A dynamic timing mode which is based on how responsive the target is.
  • -T2: Polite; Slows down to consume less bandwidth, runs roughly ten times slower than a normal scan.
  • -T1: Sneaky; Quite slow, used to evade IDS and stay quiet on a network
  • -T0: Paranoid; Very slow, used to evade IDS and stay almost silent on a network.

In addition to these options you can fine tune a scan even more with the particular settings most people use these options to speed nmap up, but they can also be useful for slowing Nmap down. Often people will do that to evade IDS systems, reduce network load, or even improve accuracy if network conditions are so bad that even nmap's conservative default is too aggressive., these flags are detailed in the following table:

Function Flags
Size of the group of hosts to be scanned concurrently --min-hostgroup, --max-hostgroup
Number of scanning probes to be launched in parallel --min-parallelism, --max-parallelism
Timeout values for probes --min-rtt-timeout, --max-rtt-timeout, --initial-rtt-timeout
Maximum number of probe retransmissions allowed --max-retries
Maximum time before giving up on an entire host --host-timeout
Control the delay inserted between each probe against an individual host --scan-delay, --max-scan-delay
Rate of probe packets sent per second --min-rate, --max-rate
Defeat RST packet response rate by target hosts --defeat-rst-ratelimit

Outputs

Viewing the output in realtime can be useful however parsing the information afterwards and feeding it into other tools is 10x more useful. Enter the different output options from nmap, saving to a file of one sort or another.

There's a few options to output to but mainly these are xml,gnmap & nmap and have the flags; -oX, -oG, -oN but there is also an easter egg output in 1337 speak which is -oS.

  • -oX: This instructs nmap to give the output in XML format for parsing later.
    • Basic example: nmap 10.0.0.1 -oX outFile
  • -oG: To do the same thing for a grepable file, -oG can be used. If I wanted to pull up the text from that file, I can use: grep HTTPS output.gnmap. This will search that file for the phrase HTTPS and output the result.
    • Basic example: nmap 10.0.0.1 -oG outFile
  • -oN: .nmap output will be the same as what is shown in realtime when you're running a scan, it allows you to quickly identify open ports or the bigger picture about a target.
    • Basic example: nmap 10.0.0.1 -oN outFile
  • -oS: This option serves no real value over the past three however will output the results in a leet speak format for a bit of fun.
  • -oA: Lastly to output to all the formats previously mentioned ( .nmap, .gnmap, .xml ) just give it a name and you're away.
    • Basic example: nmap 10.0.0.1 -oA outFile

Another useful output type is to view stats on the running scan. An example would be: nmap –stats-every 25s 10.0.0.1 to show me the statistical information every 25 seconds during a scan. You can use s for seconds, m for minutes, or h for hours for this scan. This can be done to reduce the amount of info filling up a screen.

Scanning a single host for top 1000 open ports

nmap -sT <host> --top-ports 1000 -oA TCP-Top-1k

This command essentially does the following:

  • nmap : This is the name of the tool in use, nmap
  • -sT : This flag tells nmap to do a full TCP Connect scan against the target.
  • <host> : This is where the host goes either domain(blog.zsec.uk) or IP address(1.1.1.1)
  • --top-ports 1000 : This tells nmap to scan the top 1000 ports which are:
1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389

if you're interested.

  • -oA : Output the results to .gnmap,.nmap & .xml
  • TCP-Top-1k : Name of output file

Some Options I Use

nmap -sSV -p- --min-parallelism 64 --min-hostgroup 16 --max-hostgroup 64 --max-retries 3 -Pn -n -iL input_hosts.txt -oA output --verson-all  --reason

The different flags in this command do the following:

  • -sSV: This conducts a syn scan with version checks included.
  • -p-: Tells nmap to scan all 65535 ports (1 - 65535), if you want to include port 0 you'll need to do -p 0-65535.
  • --min-parallelism 64: Launch 64 parallel tasks to probe the target.
  • --min-hostgroup 16: Scan a minimum of 16 hosts at one time and...
  • --max-hostgroup 64: ... a maximum amount of 64 hosts.
  • --max-retries 3: The amount of times to retry probing a port before moving onto the next service.
  • -Pn: Skip ping scans, assume the host is up.
  • -n: Skip dns resolution, usually select this when not interested in reverse dns or wanting a quicker scan :-).
  • -iL input_hosts.txt: Take an input file containing target hosts.
  • -oA output: Output the results to .gnmap,.nmap & .xml for parsing later and analysing.
  • --verson-all: Do extended version checks against the host to find out services running.
  • --reason: Detail the reason why a port is determined as open, filtered or closed.

Probing a specific service for more information and looking for known issues:

sudo nmap -sSV --version-all -p 11211 --min-parallelism 64 --script=vuln 10.0.0.1 -Pn -n 

The addition of the --script=vuln and specifc port tells nmap to only probe the port 11211 and tell me any vulnerable services it knows about running on that port. Additionally -sC can be used to scan a target and probe with common scripts. More information on the scripting engine can be found below.

One final one-liner I use a lot is to get the output of a subnet mask, something like:

nmap -sL -n 10.10.10.1/24 | grep report | cut -d " " -f 5 >>  ips.txt

This will simply print all of the hosts in the range given as individual IP addresses, very useful when you don't have a subnet calc on hand or want unique ips for other tools!

Going Further

So going beyond normal scans, nmap does a lot more. It is capable of scanning IPv6 networks, has an inbuilt vulnerability scanning engine and can even be tuned to evade filtering. The next few subsections explain the different flags and features that can be leveraged to do these things.

Scanning IPv6

I've covered scanning IPv6 before in my post about pwning ipv6 things which you can read here. However as a quick input the -6 or --ipv6 flags will instruct nmap that you're scanning an IPv6 address. Typically using something like:

sudo nmap -6 -sSV -p- -iL targets.txt -oA example_IPv6 --version-all --max-retries 3 -T4 -Pn -n --reason –vvv 

Will work no problem, the breakdown of this command is as follows:

  • -6: tells nmap that the targets are IPv6 hosts
  • -sSV: instructs nmap to carry out a syn half-open scan & a version scan
  • -p-: notes to scan all 65535 ports
  • -iL: This flag tells nmap to load targets from a file path, loads from the current folder.
  • -oA: notes the output to be in all three formats that nmap supports; XML, nmap & greppable nmap output.
  • --version-all: Sends additional version probes to attempt to discover the version of software running on each open port.
  • --max-retries: Notes the maximum amount of retries nmap will do per port
  • -T4: Adds additional timing options to nmap tuning the parallel processes and other timeout settings
  • -Pn: Instructs nmap to assume the host is up and not to send ICMP packets to the target.
  • -n: Tells nmap not to carry out DNS resolution of targets.
  • --reason: Tells nmap to show the reason why a port is determined as open or closed based upon response.
  • -vvv: This increases the verbosity of scan output.

Of course, you must use IPv6 syntax if you specify an address rather than a hostname. An address might look like 3ffe:7501:4819:2000:210:f3ff:fe03:14d0, so hostnames are recommended.

NSE - Nmap Scripting Engine

Most people reading this will have heard of metasploit framework(MSF), however a few may not realise that nmap has it's own vuln scanning ability built in. It's not a repacement for MSF but it has got some great features.

The NSE is a framework that runs code written in the programming language Lua with specific flags that the engine can parse. Lua is a lightweight, fast, and interpreted programming language.

I could write a whole article on itsown covering the NSE side of nmap as it is so vast and includes many many many different options. Here are a few basic ones to get you started:

  • -sC: This flag performs a script scan using the default set of scripts. It is equivalent to --script=default.
  • --script=vuln: This will run a select set of scripts looking for vulnerable software, read through the scripts it will run before running against a target to prevent unwanted outages.
  • --script=safe: This will instruct nmap to only run scripts it deems safe against the target, these are bundled to gether with the intention of information gathering rather than exploiting issues.

A full list of the main NSE scripts built into nmap can be found on the nmap site here.

Evading Filtering

Here are some options that you might not know about that will help you in evading firewall blockages;

  • -sA: TCP ACK Scan, this can be leveraged to find out if there is a firewall in place based on the response. It is always a good idea to send ACK packets rather than the SYN because if there is any active firewall working on the remote system then the firewall cannot create a log, since firewalls treat ACK packet as the response of the SYN packet.

  • -f: This option tells nmap to use fragmentation and the scan will use tiny fragmented IP packets. The idea behind this is to split up the TCP header over several packets to make it harder for packet filters, intrusion detection systems, and other annoyances to detect what you are doing. This is all find and well but be careful with this, as some programs have trouble handling these tiny packets and could cause an impact on the application or service.

  • --mtu 24 : This flag can be used to set a specific MTU (Maximum Transmission Unit) to the packet. This is similar to packet fragmentation explained above. In the example given I have used the number 24 so the nmap will create 24-byte packets causing a confusion to the firewall. Bear in mind that the MTU number must be a multiple of 8 (8,16,24,32 etc).

  • -D RND:10: This flag indicates the random number of decoy packets to send with each request, in an attempt to bypass network filtering or firewalls. You can instruct Nmap to spoof packets from other hosts. In the firewall logs it will be not only our IP address but also and the IP addresses of the decoys so it will be much harder to determine which system initiated the scanning.There are two options that you can use in this type of scan:

nmap -D RND:10 10.0.0.1 (Generates a random number of decoys)
nmap -D decoy1,decoy2,decoy3 etc. (Manually specify the IP addresses of the decoys)

It's also worth noting that the hosts being used as decoys must be online in order this technique to work.Also using many decoys can cause network congestion.

  • --source-port 80: One surprisingly common misconfiguration is to trust traffic based only on the source port number. This flag can be used to change source port to throw off the scent of scanning. Simply provide a port number, and Nmap will send packets from that port where possible. Nmap must use different port numbers for certain OS detection tests to work properly. Most TCP scans, including SYN scan, support the option completely, as does UDP scan.

  • --data-length 1337: Append Random Data to Packet for systems that use traffic shaping and other deep analysis.

  • --spoof-mac Dell/Apple/3Com: This flag can be used to spoof the mac address of your scanning machine, this can be useful to bypass network access control that is based on the mac address of systems connected into the network.

There are of course more options that can be leveraged to evade and bypass IDS/IPS/Firewalls however the above should be a good starter.

Other Tooling with NMAP

Port scanning is great but nmap also has a suite of other tools that can be used, here's a quick overview on how to use them and some common options to try.

  • ncat: Ncat is a re-invented version of netcat, it offers many more features over the standard netcat. It leverages both TCP and UDP for communication and was designed to be a reliable back-end tool to instantly provide network connectivity to other applications and users. It also works with both IPv4 and IPv6. In addition to this it also offers SSL support and proxying.
  • ndiff: Ndiff is a tool to carry out a comparison of Nmap scans. It takes two nmap xml output files and shows the differences between them.
  • nping: Nping is used for network packet generation, response analysis and response time measurement. It can generate raw network packets for various protocols. While Nping can be used as a simple ping utility to detect active hosts, it can also be used as a raw packet generator for network stack stress testing, ARP poisoning, Denial of Service attacks, route tracing and many more!

Statically Compiling

Here is a short explanation on how to compile nmap statically.

Version of nmap used: https://nmap.org/dist/nmap-7.70.tar.bz2

First set up the environment (''-fPIC'' is needed, for static compilation):


    export CFLAGS="-march=core2 -O2 -fomit-frame-pointer -pipe -fPIC"
    export CXXFLAGS="-march=core2 -O2 -fomit-frame-pointer -pipe -fPIC"

Then run ./configure with minimal options:

    ./configure --without-subversion --without-liblua --without-zenmap --with-pcre=/usr --with-libpcap=included --with-libdnet=included --without-ndiff --without-nmap-update --without-ncat --without-liblua --without-nping --without-openssl

And compile - this will mostly work:

    make -j4 static

The final compilation step fails - the actual error is:

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../x86_64-unknown-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.4/../../../../lib/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie

Making it Work

Hacking the Makefile, to make the compilation ''mostly'' static:

  1. Change the LIBS = -lnsock -lnbase -lpcre line 54 to:
    LIBS =  -lnsock -lnbase $(LIBPCAPDIR)/libpcap.a $(OPENSSL_LIBS) libnetutil/libnetutil.a $(top_srcdir)/libdnet-stripped/src/.libs/libdnet.a  $(top_srcdir)/liblinear/liblinear.a -ldl
  1. Change the $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) line 122 (under "Compiling nmap") to:

    $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) /usr/lib/libpcre.a

And re-run the final compilation step:

make

This succeeds, and we have:


    $ ldd nmap | cut -d '(' -f1
    	linux-vdso.so.1 
    	libdl.so.2 => /usr/lib/libdl.so.2 
    	libstdc++.so.6 => /usr/lib/libstdc++.so.6 
    	libm.so.6 => /usr/lib/libm.so.6 
    	libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 
    	libc.so.6 => /usr/lib/libc.so.6 
    	/lib64/ld-linux-x86-64.so.2

This is as ''static'' as the executable can be made, with glibc - those are all links to glibc's libraries.