Nmap is an incredibly powerful, open-source network scanning and mapping tool that can be used to determine what hosts are available on a network, what services those hosts are running, what operating system they're running, if there is any filtering or firewalls in use, and much more. It's used by system and network admins for various tasks such as monitoring host or service uptime, managing service upgrades, and network inventory. And while it's great for these type of administrative tasks, it's also used heavily by security auditors and pentesters for enumerating a network. It's these users that we'll focus on in this article.
What is "enumeration"
Enumeration is simply the process of gathering as much information as possible about your target. It's one of the first, and most important, steps in a penetration test. For this reason, Nmap is one of the first tools a pentester needs to learn. Using Nmap, you can identify which hosts are active on a network, which operating systems those hosts are running, which services are running on those hosts and on which ports, and what versions of the software are running for those services. Using this information, you can begin researching potential vulnerabilities on the running software, and attempt to locate exploits that you may be able to use against the targets.
It's important to note that enumeration is not a one-time task during a pentest. It's something you'll do over and over again as you exploit vulnerabilities and gain access to new parts of a network. Nmap automates this very tedious work, but it can be an intimidating tool for new users, so lets take a look at the basics of how you might use Nmap in a penetration test.
The Nmap Syntax
At the most basic level, the Nmap syntax looks something like this:
nmap [Scan Type...] [Options] {target specification}
Where Scan Type
is a flag that tells Nmap which type of scan you want to run, and Options
allow you to specify other specific behaviors you want Nmap to use during the scan, such as specifying the ports you want to scan, or where you want the output directed. The target specification
tells Nmap what target(s) you want to scan. This can be specified as an IP address (10.10.10.10
), as a hostname (example.com
), or as a range of IP addresses using CIDR notation (192.168.10.0/24
) or octet range addressing (192.168.3-5,7.1
). Multiple targets can be specified, and can use any combination of the specification styles. This can get confusing if you're not familiar with network addressing, so check out the Nmap reference guide on target specification if you need more guidance.
Basic Network Scanning
Depending on the scope of your test, one of the first scans you might want to run is a simple network scan, or ping scan. If you're working with a range of IP addresses, you'll want to start out by mapping the network and identifying which IP addresses have an active host that you could target further. Nmap is very powerful, but it can also be quite slow depending on the type of scan you're running. We don't want to jump straight into port scanning before we even know if a host is active, so we'll start with a scan that is often referred to as a "ping sweep". This type of scan, initiated with the -sn
flag, will send ICMP ping packets to each host in the target range and report which hosts respond. For example, if we want to check all of the hosts in the 192.168.0.x
network we would use the command
nmap -sn 192.168.0.1-254
Alternatively, we could achieve the same results using CIDR notation
nmap -sn 192.168.0.0/24
The -sn
flag tells Nmap that we want to skip port scanning for this run. There are a lot of other options available for host scanning, but this is the simplest form. For more information on the other options available, check out the host discovery section of the reference guide.
Port Scanning
Now that we know which hosts are responding, we're ready to start scanning to see which ports are open. There are three basic scan types that are used most often for a port scan. We won't go into great detail on how each of them work here, but here's a quick overview of each:
1. TCP Connect Scan -sT
In this type of scan, Nmap will attempt to connect to each port using the standard TCP three-way handshake. If the port responds with the SYN/ACK packet, then the port is marked as open, and Nmap completes the handshake. On the other hand, if the port responds with an RST packet, Nmap will record the port as closed an move on. A major drawback with this type of scan is that it's common for firewalls to simply drop incoming TCP requests, and not send any response at all. In this case, Nmap would mark the port as filtered. An even bigger issue is if the firewall is configured to respond to TCP requests with an RST packet, even if the port is actually open. This is fairly easy to implement and can cause erroneous scan results. For this reason, you may want to run several different types of scans during enumeration to get the most accurate results possible. For example, if we wanted to run a TCP scan against a host at 10.10.63.97
we would use the command
nmap -sT 10.10.63.97
Since we didn't specify which ports to scan, Nmap will default to the top 1,000 ports for that protocol. Our output might look something like this
From our results we can see that there are five ports open on this host, and get some basic information about the service running on each.
2. Syn Scan -sS
The Syn Scan is also sometimes known as a "Stealth Scan" or a "Half-Open Scan". This is the default scan used by Nmap and is the most popular because it's not as easy to detect as the TCP scan, and provides a reliable differentiation between open, closed and filtered ports. With a Syn scan, Nmap still uses the TCP protocol, but rather than completing the three-way handshake, it will send an RST packet once the server responds with a SYN/ACK packet. This is considered a stealthier scan because by not completing the handshake, we may avoid our scan being logged in some systems. It also makes the scan much faster, since Nmap doesn't need to worry about completing the full three-way handshake. One important note about Syn Scans is that they must be run a user with sudo
privileges. So, if we want to run a scan against 10.10.63.97
, as we did with the TCP Scan we would use the command
nmap -sS 10.10.63.97
And we see results very similar to the TCP scan
3. UDP Scan -sU
The final type of port scan we'll talk about is the UDP Scan. This type of scan is different from the others because it utilizes the UDP protocol instead of the TCP protocol. While TCP is far more prevalent, there are still a lot of services that run on UDP and vulnerabilities in these services are quite common. There are several drawbacks to the UDP scan, one of the main ones being that it is significantly slower than the other types of scans. Even so, it's a good practice to include this type of scan in your enumeration, since it could identify open ports that weren't reported by the other types of scans. Again targeting the server at 10.10.63.97
, we would use the following command to run a UDP scan
nmap -sU 10.10.63.97
And our results may look something like this
There are several other types of scans available in Nmap such as the NULL, FIN and Xmas scans. They aren't as common as the main three discussed here, but they may provide some benefits in specific situations, such as a need to avoid firewall protections. For more information on the types of scans available in Nmap check out the port scanning techniques section of the reference guide.
Service and OS Version Discovery
While the simple scans above can help us identify which ports are open, and provide some basic information about services running on the host, it's not quite enough for us to begin researching vulnerabilities. For that we need to add a couple of options flags to our commands.
First off, we'll start with attempting to discover the operating system that's running on the host. This is achieved with the -O
option. Using this option, Nmap will use TCP/IP stack fingerprinting to try to identify the OS. For this we would use the command
nmap -sS -O 10.10.76.119
As you can see from the results, we're still getting the basic scan information identifying open ports, but below that we also get details about the operating system that Nmap believes the server is running. In this case, Linux 3.13. Now we've got something to work with. Using this OS information, we can search Exploit DB for potential vulnerabilities.
From this search we can see that the OS running on the host has several potential local privilege escalation vulnerabilities.
This is great, but privilege escalation vulnerabilities don't do us a lot of good until we get a foothold on the server. Next, let's try to get some more information on the services that the host is running. We'll do this with the -sV
option.
nmap -sS -sV 10.10.76.119
Now we can see a lot more details about the services running on the host. For instance, we already knew that ssh
was running on port 22
, but we now know that it's running running OpenSSH version 7.2p2. Let's take this information back to Exploit DB.
Okay, it looks like this version of OpenSSH may have a username enumeration vulnerability. We'll keep doing the same thing for all of the identified services. Even if we can't use an exploit right away, we'll make a note of it. We may be able to come back and use it later on in our tests. Check out the reference pages for OS detection and service and version detection for more details on these options.
Wrapping Up
This just barely scratches the surface of Nmap's capabilities. There is so much more to this tool, especially once you get into the scripting engine (but I'll save that for a future article). If you want to try out these skills check out sites like TryHackMe or HackTheBox where you can find servers that you can practice on. For now, you should have enough knowledge to get started with network enumeration in your pentests. Good luck!