Port Scanning with Nmap
Having built a solid understanding of port scanning fundamentals,
let’s now learn about Nmap.
Nmap is one of the most popular, versatile, and robust
port scanners available.
It has been actively developed for over two decades and offers numerous features
beyond port scanning.
Before exploring some port scanning examples,
we should understand the footprint that each Nmap scan leaves on the wire
and the scanned hosts.
A default Nmap TCP scan will scan the 1000 most popular ports on a given machine.
Before we start running scans blindly,
let’s examine the amount of traffic sent by this type of scan.
We’ll scan one of the lab machines while monitoring the amount of traffic sent
to the target host using iptables.
We will use several iptables options.
First, let’s use the -I option to insert a new rule into a given chain.
We can use -s to specify a source IP address,
-d to specify a destination IP address, and -j to ACCEPT the traffic.
These examples include both the INPUT and OUTPUT chains,
followed by the rule number.
Finally, we’ll use the -Z option to zero the packet
and byte counters in all chains.
Next, let’s generate some traffic using nmap:
The scan completed and revealed a few open ports.
Now let’s review some iptables statistics to get a clearer idea of how much traffic
our scan generated.
We can use the -v option to add some verbosity to our output,
-n to enable numeric output,
and -L to list the rules present in all chains.
According to the output,
this default 1000-port scan generated around 63 KB of traffic.
Let’s use iptables -Z to zero the packet and byte counters in all chains again,
and run another nmap scan, this time using -p to specify all TCP ports.
A similar local port scan explicitly probing all 65,535 ports
generated about 4 MB of traffic - a significantly higher amount.
However, this full port scan has discovered more ports
than the default TCP scan found.
Our results imply that a full Nmap scan of a class C network would result in sending
over 1000 MB of traffic to the network.
Ideally, a full TCP and UDP port scan of every single target machine would provide
the most accurate information about exposed network services.
However, we clearly need to balance any traffic restrictions,
such as a slow uplink, with discovering additional open ports and services
via a more exhaustive scan.
This is especially true for larger networks.
Having learned about Nmap’s basic use,
we’ll now explore some of Nmap’s various scanning techniques.
The most popular Nmap scanning technique is SYN, or “stealth” scanning.
SYN scanning is a TCP port scanning method that involves sending SYN packets
to various ports on a target machine without completing a TCP handshake.
If a TCP port is open, a SYN-ACK should be sent back from the target machine,
informing us that the port is open.
At this point, the port scanner does not bother to send the final ACK
to complete the three-way handshake.
Because the three-way handshake is never completed,
the information is not passed to the application layer and as a result,
will not appear in any application logs.
A SYN scan is also faster and more efficient because
fewer packets are sent and received.
The next Nmap scanning method we’ll explore is named TCP Connect Scanning,
which, as the name suggests, performs a full TCP connection.
When a user running nmap does not have raw socket privileges,
Nmap will default to the TCP connect scan technique.
Since an Nmap TCP connect scan makes use of the Berkeley sockets API to perform
the three-way handshake, it does not require elevated privileges.
However, because Nmap has to wait for the connection to complete before the API
will return the status of the connection, a TCP connect scan takes much longer
to complete than a SYN scan.
We may occasionally need to perform a connect scan using nmap,
such as when scanning via certain types of proxies.
We can use the -sT option to start a connect scan.
The output shows that the connect scan resulted in a few open services
that are only active on the Windows-based host,
especially Domain Controllers, as we’ll cover shortly.
One major takeaway, even from this simple scan,
is that we can already infer the underlying OS and role of the target host.
Having reviewed the most common Nmap TCP scanning techniques,
let’s learn about UDP Scanning.
When performing a UDP scan, Nmap will use a combination of two different methods
to determine if a port is open or closed.
For most ports, it will use the standard “ICMP port unreachable” method
by sending an empty packet to a given port.
However, for common ports, such as port 161, which is used by SNMP,
it will send a protocolspecific SNMP packet in an attempt to get a response
from an application bound to that port.
To perform a UDP scan, we’ll use the -sU option,
with sudo required to access raw sockets.
The UDP scan can also be used in conjunction with a TCP SYN scan
to build a more complete picture of our target.
Our joint TCP and UDP scan revealed additional open UDP ports,
further disclosing which services are running on the target host.
We can now extend what we have learned from a single host and apply it
to a full network range through Network Sweeping.
To deal with large volumes of hosts, or to otherwise try to conserve network traffic,
we can attempt to probe targets using Network Sweeping techniques in which
we begin with broad scans, then use more specific scans against hosts of interest.
When performing a network sweep with Nmap using the -sn option,
the host discovery process consists of more than just sending
an ICMP echo request.
Nmap also sends a TCP SYN packet to port 443,
a TCP ACK packet to port 80,
and an ICMP timestamp request to verify whether a host is available.
Searching for live machines using the grep command on a standard nmap output
can be cumbersome.
Instead, let’s use Nmap’s “greppable” output parameter, -oG,
to save these results in a more manageable format.
We can also sweep for specific TCP or UDP ports across the network,
probing for more common services and ports in an attempt to locate systems
that may be useful or have known vulnerabilities.
This scan tends to be more accurate than a ping sweep.
To save time and network resources, we can also scan multiple IPs,
probing for a short list of common ports.
For example, let’s conduct a TCP connect scan for the top 20 TCP ports
with the --top-ports option,
and enable OS version detection, script scanning, and traceroute with -A.
The top 20 nmap ports are determined using the nmap-services file,
which uses a simple format of three whitespace-separated columns.
The first is the name of the service,
the second contains the port number and protocol,
and the third is the “port frequency” which is based on how often the port
was found open during periodic research scans of the internet.
Everything after the third column is ignored,
but is typically used for comments.
At this point, we could conduct a more exhaustive scan
against individual machines that are service-rich or are otherwise interesting.
There are many different ways we can be creative with our scanning
to conserve bandwidth or lower our profile,
as well as interesting host discovery techniques that are worth
further research.
We have now scanned hosts that revealed a few services,
so we can guess the nature of the target’s operating system.
Luckily for us, Nmap is shipped with an OS Fingerprinting option.
Let’s consider a simple nmap OS fingerprint scan.
OS fingerprinting can be enabled with the -O option.
This feature attempts to guess the target’s operating system by inspecting
returned packets.
This works because operating systems often use slightly different implementations
of the TCP/IP stack, and these slight variances create a fingerprint
that Nmap can often identify.
Nmap will inspect the traffic received from the target machine and attempt to
match the fingerprint to a known list.
By default, Nmap will display the detected OS only if the retrieved fingerprint
is very accurate.
Since we want to get a rough idea of the target OS,
we’ll include the --osscan-guess option
to force Nmap to print the guessed result even if is not fully accurate.
The response suggests that the underlying operating system is running Windows.
Once we have recognized the underlying operating system,
we can go further and identify services running on specific ports by inspecting
service banners with -sV,
as well as running various OS and service enumeration scripts
against the target with -A.
Banner grabbing significantly impacts the amount of traffic used as well as
the speed of our scan.
We should always be mindful of the options we use with nmap
and how they affect our scans.
Now that we have covered Nmap’s major features,
we’ll focus on specific Nmap scripts encompassed by the Nmap Scripting Engine.
We can use the NSE to launch user-created scripts in order to automate
various scanning tasks.
These scripts perform a broad range of functions including DNS enumeration,
brute force attacks, and even vulnerability identification.
The http-headers script, for example, attempts to connect to the HTTP service
on a target system and determine the supported headers.
To view more information about a script, we can use the --script-help option,
which displays a description of the script and a URL where we can find more in-depth
information, such as the script arguments and usage examples.
When internet access is not available, much of this information can also be found
in the NSE script file itself.
It’s worth our time to explore the various NSE scripts,
as many of them are helpful and time-saving.
Having learned how to perform port scanning from Kali,
let’s explore how can we apply the same concepts from a Windows host.
If we are conducting initial network enumeration from a Windows laptop
with no internet access, we are prevented from installing any extra tools that might
help us, like the Windows Nmap version.
In such a limited scenario,
we are forced to pursue the ‘living off the land’ strategy.
Luckily, there are a few helpful built-in PowerShell functions we can use.
The Test-NetConnection function checks if an IP responds to ICMP and whether
a specified TCP port on the target host is open.
For instance, from the Windows 11 client,
we can verify if the SMB port 445 is open on a domain controller as follows.
The returned value in the TcpTestSucceeded parameter indicates that port 445 is open.
We can further script the whole process in order to scan the first 1,024 ports
on the Domain Controller with a PowerShell one-liner.
We started with a foreach loop that runs through the first 1,024 ports and assigns
the incremental integer value to the $port variable.
Then, it performs a Test-NetConnection TCP connection against the target IP
on that specific port, and if the connection is successful,
it prompts a log message that includes the open TCP port.
We’ve covered just the starting point of PowerShell’s abilities,
which can be further extended to match the traditional Nmap features.