Nmap, also known as network mapper, is a free and open-source security tool widely known for its powerful network discovery, enumeration and security auditing abilities. Network administrators utilize Nmap to establish a network map and get more information about what’s going on inside the network: which hosts are online, what ports are open, which services are offered, and more.
However, Nmap has evolved to become more than just a port-scanning tool - it’s also used for service monitoring, vulnerability detection and exploitation just to name a few.
The quickest way to get up and running is by installing Nmap through the APT package manager:
sudo apt install nmap
Before we jump into network scanning, it’s important to define and understand the methods that can be used to specify which targets to scan. The simplest way is specifying only one host, without any additional parameters:
Multiple hosts can be specified in subnet or IP range, either from the command line or a file:
nmap 192.168.1.0/24 # Scan a whole subnet nmap 192.168.2.100-200 # Scan IP range nmap 192.168.1.0/24 192.168.2.100-200 # Same as both of the above nmap -iL targets.txt # Scan all IP addresses in text file
It’s also possible to exclude IP addresses from the scan:
nmap --exclude 192.168.6.1.1 192.168.1.0/24 # Can also be subnet or IP range nmap --excludefile targets.txt 192.168.1.0/24 # Exclude hosts present in file
Nmap optimizes port scan speed by first checking if the target is online before attempting to scan any ports. This is called host discovery or ping scanning and is enabled in every scan by default.
To determine target availability, Nmap sends an ICMP echo request (ping), ICMP timestamp request and probes TCP ports 80 and 443. In local networks, only ARP requests are utilized for host discovery.
Running a host-discovery-only scan is possible in case we only want to see which hosts are online:
nmap -sn 192.168.1.0/24
It’s often the case that hosts are configured to reject ICMP packets, in which case no ports are scanned as the target is seen as offline. In this case, we can make use of the pingless scan to skip host discovery and jump straight into port scanning:
nmap -Pn 192.168.6.1
Another great feature of Nmap is operating system detection, which is enabled with the
nmap -O 192.168.6.1
Note that OS detection results are not 100% accurate and may vary depending on what and how many services have been exposed. It’s always best to analyze port scan results and manually determine the OS being used.
Nmap will by default scan only the most common 1,000 TCP ports of any given target, so it’s common to make use of the
-p flag to specify which ports to scan:
nmap -p 80 scanme.nmap.org # Scan only port 80 nmap -p- scanme.nmap.org # Scan all 65535 ports nmap -p 1-100, 445 scanme.nmap.org # Scan ports 1 to 100 and 445
However, keep in mind that this will only scan TCP ports and no network scan is complete without a UDP port scan, which we can enable with the
nmap -sU scanme.nmap.org
Pro tip: use
--open to omit closed ports.
For an even quicker scan we can enable the fast scan mode, which scans only the 100 most common ports:
nmap -F scanme.nmap.org
Nmap recognizes six port states:
- open - an application is listening on this port and actively accepting connections;
- closed - the port is reachable and responds to Nmap’s packets, but there is no application listening;
- filtered - Nmap was unable to reach the target port and as a result, couldn’t determine if the port is open. This occurs when a firewall or another network device is dropping the packets before they reach the target;
- unfiltered - Nmap was able to reach the port but couldn’t determine if it’s open or closed;
- open|filtered - Nmap was unable to determine if the port is open or filtered;
- closed|filtered - Occurs only in IP ID idle scan when Nmap is unable to determine if a port is closed or filtered.
Service and version detection
Well-known and popular services are assigned default port numbers by The Internet Assigned Numbers Authority (IANA), in order to establish standards and avoid interfering port numbers.
Nmap determines which service is running on a port via its
nmap-services registry file containing well-known services and their corresponding port numbers, originally based on IANA’s port list but with minor modifications:
# Fields in this file are: Service name, portnum/protocol, open-frequency, optional comments ftp 21/sctp 0.000000 # File Transfer [Control] | File Transfer Protocol [Control] ftp 21/tcp 0.197667 # File Transfer [Control] ftp 21/udp 0.004844 # File Transfer [Control] ssh 22/sctp 0.000000 # Secure Shell Login | The Secure Shell (SSH) Protocol ssh 22/tcp 0.182286 # Secure Shell Login ssh 22/udp 0.003905 # Secure Shell Login telnet 23/tcp 0.221265 telnet 23/udp 0.006211 [output omitted]
As a result, port scan results may be misleading as an SSH server may easily be configured to listen on port 80/tcp instead of 22/tcp and showing up as HTTP. For more accurate results the service and version detection scan may be enabled with the
nmap -sV <target>
Nmap is now instructed to communicate with the service directly and retrieve more information about the running service and its version (also known as banner grabbing):
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 1.14.0 (Ubuntu)
Service and version detection scans take much longer to complete but offer more detailed and accurate information about the service.
TCP SYN Scan
Nmap offers various port scanning techniques, each of which differ in functionality and what they’re used for. Understanding how the default TCP SYN scan technique works goes a long way towards being able to use and understand other techniques.
TCP SYN scan is based on the TCP 3-way handshake used to establish a connection between client and server. The client initiates the handshake by sending a SYN packet to the server, if the server responds with SYN/ACK, the client responds back with ACK - at which point the handshake is complete and the connection is established.
In TCP SYN scanning, Nmap initiates a 3-way handshake but interrupts the handshake when the server responds with SYN/ACK. This is because Nmap already got a confirmation that the port is reachable when the server replied with SYN/ACK, and there is no need to establish a full connection.
Nmap reports a port as filtered if there is no response from the server after sending a SYN packet, which is most likely due to the firewall dropping the packet.
The server responds with an RST (reset) packet if there is no application listening on the requested port. A reset packet may also be indicative of a firewall configured to reject packets and respond with an RST packet, even though there is an application listening.
Nmap Scripting Engine
The Nmap Scripting Engine (NSE) is a powerful Nmap feature that allows users to write, execute and share Nmap scripts written to automate various tasks, such as:
- Network discovery
- More sophisticated version detection
- Vulnerability detection
- Backdoor detection
- Vulnerability exploitation
Without going into details, it’s worth mentioning that NSE supports four types of scripts depending on which phase they run in and that each NSE script belongs to at least one category - which you can read about here.
Nmap ships with over 500 NSE scripts in a default installation, ready for use. An interesting one seems to be the ssh-auth-methods script. We can guess what it does from its name, but before running it against a target it’s good practice to use the help command to check what the script does, which category it belongs to and how it behaves:
root@kali:~# nmap --script-help=ssh-auth-methods ssh-auth-methods Categories: auth intrusive https://nmap.org/nsedoc/scripts/ssh-auth-methods.html Returns authentication methods that a SSH server supports. This is in the "intrusive" category because it starts an authentication with a username which may be invalid. The abandoned connection will likely be logged.
The script will connect to an SSH server and check what authentication methods it accepts. This is a very useful script to ensure that the servers in your network aren’t accepting password authentication when you only want to support key-based authentication. Let’s run that against an SSH server:
root@kali:~# nmap --script=ssh-auth-methods -p 22 scanme.nmap.org PORT STATE SERVICE 22/tcp open ssh | ssh-auth-methods: | Supported authentication methods: | publickey |_ password
Script output shows that the target SSH server accepts both public key and password authentication.
And of course, since it’s Nmap, we can already guess there’s powerful flexibility and about a million ways we can specify the scripts, but let’s cover the most important methods:
# Load all scripts in discovery and safe category nmap --script discovery,safe <target> # Load all scripts with names starting with ftp- nmap --script "ftp-*" <target> # Load all scripts not belonging in exploit category nmap --script "not exploit" <target>
It’s good practice to save and export all scan results so that they are accessible later and also parsable by a 3rd party software. Nmap supports three major formats when it comes to exporting results:
nmap -oN results scanme.nmap.org # Normal format nmap -oX results scanme.nmap.org # XML format nmap -oG results scanme.nmap.org # Grep-able format nmap -oA results scanme.nmap.org # All of the above
Knowing how to operate Nmap is essential as it gives you more insight on what’s going on inside your network and allows you to monitor different services or even regularly check for security misconfigurations and/or vulnerabilities. Logging scan results is as important as regularly checking your network with Nmap - one doesn’t work without the other!