Nmap is a network utility tool which is used to enumerate hosts in the network , perform reconnaissance or information gathering , vulnerability detection , exploitation and much more. I consider it a swiss army of a network penetration tester. Information gathering is the key to a vulnerability assessment and penetration testing engagement. The more we know about the system the more we can abuse various attack vectors. Through this post I will guide you through how nmap works and how it can be used to perform vulnerability assessment and penetration testing.
Host Discovery
Discovering the target host(s) is the first step towards network reconnaissance. There are multiple ways through which we can determine if the hosts are alive or not.
Single IP Scan
To scan a single ip we simply give one ip as follows:
sudo nmap -sn 192.168.254.10
-sn means disable port scanning
Multiple IP Scan
- By giving the range (Sequential IP addresses:
sudo nmap -sn 192.168.254.10-50
Here , it says there are two hosts up. It scanned all the hosts from 192.168.254.10 to 192.168.254.50 inclusive.
2. By giving the all ip addresses as an input from the file:
sudo nmap -sn -iL ips.txt
Here , -iL flag is used to import ips from the text file named ips.txt
3. By giving a CIDR range:
sudo nmap -sn 192.168.254.1/24
Here, we have assigned a CIDR /24 which means it scans all the way from 192.168.254.1 to 192.168.254.255
How does host discovery scan work?
When performing a host discovery scan we have seen that we used -sn flag. By default when we use -sn flag it does a few things under the hood. We can use –reason flag to see why nmap flagged the given host as up.
sudo nmap -sn 192.168.254.254 --reason
The highlighted part says that it received an arp-response which is the very reason why nmap flagged this host as up. When we are in a local network nmap sends arp requests before it can send other types of requests for host discovery. Let’s verify this by disabling arp requests.For this we use –disable-arp-ping flag.
sudo nmap -sn 192.168.254.254 --disable-arp-ping --reason
The highlighted part says it received reset instead of arp-response. It means that it probed a port but the port responded with a reset packet indicating that the host is up. We will get on to this more on port scanning. But for now what we have to infer is it sends a probe request. But to which port? Let’s sniff the traffic and see.
For this we run above command and use tcpdump to see the traffic.
The highlighted parts indicate that nmap has issued a probe request to port 443 and the target device responded with a tcp reset flag indicating that the port is closed and the host is up. If you observe closely then you can see that nmap has also sent ICMP echo request , timestamp query and ACK probe request to port 80. With this what we can confirm is nmap host discovery scan sends arp requests , icmp echo requests and probe requests to port 80 and 443.
In the screenshot above we have issued –reason flag. The highlighted part shows why nmap flagged this host as up. You can also see that it gives arp-response. By default when we are in a local network then nmap sends arp requests although there are other things it does(Let’s forget it for now). Now , let’s try disabling arp and see what it shows. For this, we issue the following command.
We can see that it now says echo-reply instead of arp-response. Also , you can see that ttl is 128. It means that the packets can traverse through 128 hops in total. TTL can be used to determine the target operating system. 128 ttl means the target host is probably windows. If you see numbers somewhere around 64 then it is probably linux and if you see numbers around 255 then the target might be some cisco devices.
So , in short if you want to scan the target network to find alive hosts simply use the following command.
sudo nmap -sn 192.168.100.1/24 --reason -n (replace the ip)
-n disables DNS resolution making the discovery a bit faster
Sometimes ICMP and other packets are firewalled in the network. In such cases there are other ways through which we can determine if the target host is up. This can be achieved by scanning a few common tcp and udp ports. Following ports can be probed to see if the host is up. It might not give 100% of the result 100% of the time but it’s worth a shot.
80 – http
443 – https
21 – ftp
23 – telnet
3389 – rdp
110 – pop3
22 – ssh
25 – smtp
The command below can be used
sudo nmap -Pn -PS 21,22,23,25,80,443,110,3389 192.168.191.1/24 -n
-Pn means disable ping scan
-PS means start tcp syn scan(more on this in the port scanning section)
-n means disable DNS lookup
If you see any ports open or closed then that host is likely to be up as it responded to our probe requests.
Filtering the Output
When doing a host discovery scan it shows a lot of output which is not needed. We can save nmap results in a file and filter out output which is not needed.
Let’s run the following command
We can now filter out the needed thing by using the following command
sudo nmap -sn 192.168.1.66/24 -vvv -n -oN output.txt
It saves the output in a file output.txt which looks like
We can now filter out the needed thing by using the following command
cat output.txt | grep -i up -B 1 | grep -i report | awk '{print $5}'
As you can see it now shows only the hosts which are up. You can tweak the commands as per your need to print out the mac address and other details as needed.
Port Scanning
After finding the total number of hosts in the given network we need to find out which ports are open and enumerate services accordingly. Depending upon the situations nmap can flag the given port as either of the following states :
OPEN – the connection has succeeded
CLOSED – the packet received has a rst flag set.
FILTERED – the port is either open or close. Either no response is returned or there are some errors
UNFILTERED – it only happens when doing an acknowledgement scan but nmap failed to determine if the port is open or close
OPEN | FILTERED – firewall may filter the port
CLOSED | FILTERED – it occurs when ip idle scan is used and nmap fails to determine if the port is open or close
Single Port Scan
sudo nmap -p 53 192.168.1.254
-p takes port(s) numbers separated with a comma
As you can see the port is closed. Now, lets run the same command again but this time we capture the request in tcpdump to see what it does behind the hood.
sudo tcpdump any host 192.168.1.254
It shows a lot of stuff like arp requests and all which is performed by nmap by default when scanning ports. Let’s disable those using –disable-arp-ping (disables arp request) , -n (disables dns resolution) , -Pn (disables ICMP requests) and capture the traffic again.
sudo nmap -p 53 192.168.1.254 --disable-arp-ping -n -Pn
Let’s look at the first line of the highlighted part. It has sent a tcp SYN packet to port 53 of target IP. You can see it tcpdump shows it as ‘domain’ which is the service equivalence of port 53 just like http in port 80. [S] indicates that it is a SYN packet. Likewise, in the second line you can see that the target host has responded with a RST ack flag indicating that the port is closed.
Nmap has an option –packet-trace which can be used to see what packets are being sent by nmap instead of running tcpdump separately. One benefit of using –packet-trace over tcpdump or wireshark is that it can capture nmap specific packets.
Let’s run the above command again with –packet-trace flag.
sudo nmap -p 53 192.168.1.254 --disable-arp-ping -n -Pn --packet-trace
So, by default nmap sends TCP SYN packets to determine the port states if no argument is specified.
Note : We need to issue nmap commands as sudo otherwise nmap falls back to other scanning techniques.
Multiple Port Scan
sudo nmap -p 22,53 192.168.1.254 --disable-arp-ping -n -Pn
Full Port Scan
To scan for full port we specify -p- flag
sudo nmap -p- 192.168.1.71 --disable-arp-ping -n -Pn
which is equivalent to providing -sS flag. But nmap should be run as root to happen so if not then it falls back to using tcp scan -sT.
Top Port Scan
Nmap has a list of top ports and we can specify –top-ports flag to scan the mentioned number of ports. For e.g if we specify –top-ports=100 then it scans for top 100 ports. By default if we run nmap without any argument then it scans the top 1000 ports.
sudo nmap --top-ports=100 192.168.1.69
It says that all the ports scanned are closed.
Let’s try with the top 1000 ports in another ip address.
sudo nmap --top-ports=1000 192.168.1.254
Now, it finds three ports are filtered. Nmap flags the given port as filtered if the target host does not respond to the probe request or the firewall rejects the packet. Let’s try to analyze.
We scan for one filtered port and another closed port.
sudo nmap -p 80 192.168.1.254 --disable-arp-ping -n -Pn --packet-trace
Here it says that ‘Port 80 in unreachable’.
Let’s try to run the same scan but in a different port.
sudo nmap -p 81 192.168.1.254 --disable-arp-ping -n -Pn --packet-trace
Now, the target port has responded with RST ACK packet indicating that the port is closed. If we are to compare those two results then we can be pretty sure that firewall is in place rejecting the packets for some ports as seen in the screenshot above.
UDP Port Scan
We can specify -sU flag to scan for UDP ports.
sudo nmap -sU -p 53 192.168.1.254 --disable-arp-ping -n -Pn --packet-trace
nmap targetip then it is equivalent to nmap -sT targetip –top-ports=1000
If run with sudo then sudo nmap target ip is equivalent to sudo nmap -sS targetip –top-ports=1000
TCP SYN scan does not complete three way tcp handshake. SYN , SYN-ACK
If it receives SYN-ACK then it flags the port as open if it receives RST then it flags the port as closed.
sudo nmap -sS host --top-ports=1000
Saving the output
Nmap can save the results output in different formats like default nmap format , XML format, grepable nmap format etc.
Normal output has an extension of .nmap (We specify -oN filename)
Greppable output has an extension of .gnmap(We specify -oG filename)
XML output has an extension of .xml(We specify -oX filename)
We can specify -oA to output in all formats. Let’s have a quick look into one of the formats.
sudo nmap -sU -p 53 192.168.1.254 --disable-arp-ping -n -Pn -oX udp-scan.xml
It saves the output in xml format which can be parsed by XML parser.
There is a tool named xsltproc which can convert the given XML file into a readable html format.
We simply use the following command:
xsltproc udp-scan.xml >> udp-scan.html
Similarly, we can save the output in other different formats.
That’s it for today’s post. I will cover the service enumeration , nmap scripting engine and much more in nmap part II.