Discovery and Scanning with Nmap

An attacker wants to learn your network layout, especially how it's connected to the internet and its internal parts. This info can show weaknesses or the location of devices. Nmap, a free tool for network mapping and port scanning, can help with this. It works on Windows, macOS, and Linux.

Sweeping for Network Mapping

To map a network, you first send packets to each address and check for responses. If you get a reply, it means the address is in use. Nmap usually pings each address before scanning its ports, but you can change this. Using the -Pn flag makes Nmap skip the ping and start the port scan directly.

By default, Nmap sends four packets to each address: an ICMP Echo Request, a TCP SYN to port 443, a TCP ACK to port 80 (if running as root), and an ICMP Timestamp request. If Nmap isn’t running as root, it only sends TCP SYN packets to ports 80 and 443. If any packet gets a reply, Nmap considers the address active and proceeds with scanning.

Nmap can work without root access, but some features won’t be available. For the best results, run Nmap as root.

Nmap Host Discovery

sec504@slingshot:~$ sudo nmap -sn 192.168.1.1-254
Starting Nmap 7.60 ( https://nmap.org ) at 2021-07-03 14:58 UTC
Nmap scan report for 192.168.1.1
Host is up (0.0081s latency).
Nmap scan report for 192.168.1.10
Host is up (0.0065s latency).
Nmap scan report for 192.168.1.27
Host is up (0.010s latency).
Nmap scan report for 192.168.1.34
Host is up (0.91s latency).
Nmap scan report for 192.168.1.70
Host is up (0.0040s latency).
...
Nmap done: 254 IP addresses (20 hosts up) scanned in 18.00 seconds

The example here shows Nmap’s host discovery output. Using -sn disables port scanning, focusing only on finding hosts. The results list hosts that responded to Nmap’s tests and their response times. For best results, run Nmap as root to perform all tests.

Port Scanning

IP moves data on the internet, including where it’s coming from and where it’s going. TCP and UDP use IP to send their messages. TCP ensures messages arrive in order and retries if needed. UDP tries its best to deliver messages but doesn’t guarantee order or delivery.

Ports are like doors to your system. Open ports show attackers where they can get in. Port scanners help attackers find these doors and see what services are available to target.

TCP and UDP Ports

There are 65,536 TCP and 65,536 UDP ports. Common services use specific port numbers, and IANA keeps the latest port list. For example:

  • TCP 80 usually indicates a web server

  • TCP 445 usually indicates Windows Server Message Block (SMB)

  • UDP 53 usually indicates a DNS server

Each open port offers a potential way into a system.

Traffic with port 0 is always invalid because TCP port 0 is not used. Packets with port 0 should be discarded.

Nmap Scan Types

Ping or ARP

-sn

Disable port scan for host discovery; use ARP if on same LAN

TCP connect

-sT

TCP port scan using conventional TCP connections

TCP SYN

-sS

TCP port scan using half-open TCP connections

UDP

-sU

UDP port scan (often unreliable)

Version

-sV

Combine with other scans to identify services through active probes

Nmap allows for conducting several types of scans:

  • Ping sweeps find hosts without checking their ports by using the -sn option. On the same LAN, Nmap uses ARP (for IPv4) or IP Neighbor Discovery (for IPv6) to find systems. If not on the same LAN, Nmap sends multiple packets for host discovery. Ping sweeps help list systems before doing more scans.

  • TCP connect scans: Try to connect to a port using -sT, then close the connection if the port is open. This is the default scan used by Nmap without root access.

  • TCP SYN scans: Send a TCP packet with the SYN flag to check if a port is open (if you get an ACK) or closed (if you get an RST). This scan doesn’t close the connection properly, so it’s less likely to be logged or detected. It’s the default scan in Nmap when run as root.

  • UDP scanning: Scans UDP services with -sU. Nmap sends empty packets to most ports, but uses specific data for some, like ports 53 (DNS), 111 (portmapper), and 161 (SNMP). UDP scans can be unreliable and may misidentify the status of services.

  • Version scanning: Nmap's -sV option does a version scan, giving details about the software version or extra info on a service running on a found port.

Nmap can scan IPv6 addresses too by using the -6 option. It works with all scan types like connect, SYN, and UDP.

Let's do the nmap exercise in Lightning Labs.

1) By default, Nmap will scan a target system using a list of the top 1000 most common ports. Let's take a look.

Scan the target system at 10.20.20.5 using Nmap: sudo nmap 10.20.20.5.

sudo nmap 10.20.20.5

Notice how Nmap indicates 998 closed tcp ports, showing two ports open. This is a clue that Nmap does not scan all 65,535 ports by default.

2) Nmap can specify a range of ports with the -p argument, indicating the starting and ending ports, separated by a hyphen.

Return to the previous command and add -p 1-65535 to scan all TCP ports.

sudo nmap 10.20.20.5 -p 1-65535

This time Nmap scanned all 65,535 ports, revealing an open port we didn't see before: 5301.

3) We can use a port range shorthand to specify all ports: -p-.

sudo nmap 10.20.20.5 -p-

4) Nmap can also use a list of ports with -p, separated by commas. Return to the previous command and change the previous -p argument to indicate the three open TCP ports -p 22,53,5301.

sudo nmap 10.20.20.5 -p 22,53,5301

5) The previous port range didn't reveal anything new, but it's useful to explicitly specify target ports when adding other scan types.

We don't know what service is listening on TCP/5301 other than hacl-gs which is the registered service name high availability cluster services. However, we an use a Nmap version scan to interrogate the service further.

Repeat the previous command, this time adding -sV to perform a version scan.

sudo nmap 10.20.20.5 -p 22,53,5301 -sV

The version scan reveals additional information about each service in a new Nmap output column labeled VERSION.

Here we learn that TCP/5301 is actually a nginx web server, not hacl-gs. An admin is running the web server on a non-standard port, maybe to evade detection.

6) Nmap's output is displayed on your console, but you can also save the results to a file.

Scan all ports on the target system 10.20.20.5, using -oN scanresult.txt to save the scan results: sudo nmap -p- 10.20.20.5 -oN scanresult.txt.

sudo nmap -p- 10.20.20.5 -oN scanresult.txt

7) Nmap supports other output file formats as well. Return to the previous Nmap command then add -oG scanresult.gnmap to the command line.

sudo nmap -p- 10.20.20.5 -oN scanresult.txt -oG scanresult.gnmap

Nmap's grepable output is intended for use when scanning lots of systems, allowing you to search for listening ports quickly.

8) Consider a case where you scan lots of hosts, and you want to find out which ones listen on TCP port 5301. Run grep 5301 scanresult.gnmap.

grep 5301 scanresult.gnmap

Nmap's output isn't pretty here, but it identifies the host where port 5301 is listening quickly.

9) Nmap supports saving the scan results in an XML file format as well. Add -oX scanresult.xml to the previous command line.

sudo nmap -p- 10.20.20.5 -oN scanresult.txt -oG scanresult.gnmap -oX scanresult.xml

10) You can save the Nmap output in all three file formats automatically. Run sudo nmap -p- 10.20.20.5 -oA scanresultall.

sudo nmap -p- 10.20.20.5 -oA scanresultall

Nmap makes it easy to save the scan results in several file formats. It's often easier to run Nmap with -oA instead of choosing one or more output file types, and you can remove the files you don't want to save later.

Nmap NSE Scripts

Nmap Scripting Engine: Identify Host Information, Vulnerabilities

Nmap NSE ArgumentFunction

-sC

Use default scripts to evaluate the target

--script all

Run all scripts against target (can lead to DoS)

--script-updatedb

Update the NSE scripts (requires internet access)

--script banner

Run the named script (banner) against the target(s)

--script-help "http*"

Get help for the named script(s) (use wildcard * alone for all scripts)

--script "http*"

Run all the scripts beginning with http against the target(s)

--script "smb*"

Run all the scripts beginning with smb against the target(s)

Nmap also supports the Nmap Scripting Engine (NSE), which uses Lua scripts to analyze scan results and find more info or vulnerabilities on a target. Using the -sC option runs default scripts for extra details, and other script categories include auth, discovery, safe, and vuln.

Some NSE scripts need arguments, which you can find in the script's help info. Use --script-args with the argument name, an equal sign, and the value. Separate multiple arguments with commas.

sudo nmap -p 5301 -sV 10.20.20.5 --script http-headers -oA target-host-secheaders

When using Nmap NSE scripts, always include the -sV option for version scanning. Without it, Nmap might misidentify services, like thinking port 5301 is hacl-gs instead of HTTP, and skip the right script. Using -sV helps run the correct script.

Lab 2.2: Nmap

Let's start by runing nmap scan as an Uprivileged User without any extra options.

nmap 127.0.0.1

The output shows three open TCP ports, with Nmap listing the port numbers, their status, and a short description of the service. Nmap scans the 1,000 most common ports instead of all 65,535 ports.

By default, Nmap does a full TCP connect scan when not run as root, completing the three-way handshake for each open port.

Nmap shows why it thinks a port is open. In UDP scans, if no response is received, it labels the port as "Open|Filtered," meaning it could be open or filtered. If a firewall blocks a packet, Nmap marks the port as "Filtered."

Let's check why Nmap gave its results by running the scan again with nmap --reason.

nmap --reason 127.0.0.1

In this output, we see that Nmap discloses that it received a SYN/ACK for each of the open TCP ports.

Next, let's use sudo to run Nmap as root and scan again.

sudo nmap --reason 127.0.0.1

When we run Nmap as root, it uses a different scan method called TCP SYN instead of TCP connect. This method sends a half-open connection. Both methods show similar results, but root access allows Nmap to perform an initial ping test that non-root can't do.

Nmap's half-open scan creates fewer logs but is more noticeable on the network. To make Nmap use a full TCP connect scan as root, use the -sT option.

Let's run the scan again, but this time we will use the -p argument to check ports from 1 to 1024.

sudo nmap --reason -p 1-1024 127.0.0.1

The scan shows no open ports, which matches the earlier result. We can use the -p option to scan specific ports, like web servers (80, 443, 8000, 8080) or SMB servers (135, 139, 445), to focus our scan.

To scan all TCP ports, let's use -p 1-65535 or -p- in Nmap. This will check all 65535 ports on the Slingshot Linux host.

sudo nmap --reason -p- 127.0.0.1

When scanning all TCP ports, we found two extra services on ports TCP/5433 and TCP/5443 that earlier scans missed because Nmap only checks the top 1000 ports by default.

Nmap uses its own list to match ports with services, but this can be inaccurate. To get better details about what's running on a port, we can use a version detection scan (Banner Grabbing). Nmap connects to each service and tries to gather more information by interacting with it.

sudo nmap -sV --reason -p 5433,5443,9001,9002 127.0.0.1

Adding version detection to the Nmap scan changes how it identifies open port services:

  • TCP/5433 is characterizes as a PostgreSQL database server version 9.6.0

  • TCP/5443 is characterized as a SSL/HTTP service running Thin httpd (a lightweight web server)

  • TCP/9001 is characterized as an nginx web server version 1.14.0 running on Ubuntu

  • TCP/9002 is also characterized as an nginx web server version 1.14.0 running on Ubuntu

The version scan helps us identify TCP/5443, TCP/9001, and TCP/9002 as web servers. We can then use Nmap to run web enumeration scripts on these servers.

We can obtain help information for a specific category of scripts using the --script-help command line argument.

nmap --script-help "http*" | grep "^http-"

To get help for a script,we can use --script-help and then the script name.

nmap --script-help http-git

The Nmap http-git script looks for Git info on a web server, which might show old passwords or other sensitive details about the web app.

Let's run the http-git script on the Slingshot Linux port 9001 web server using the Nmap --script argument.

sudo nmap -p 9001 --script http-git 127.0.0.1

Nmap doesn’t show results from the http-git script because it doesn’t recognize web servers on non-standard ports.

NOTE: It is essential for Nmap to properly characterize the target service to apply the correct scripts.

Let's repeat the scan again, this time adding the -sV argument:

sudo nmap -sV -p 9001 --script http-git 127.0.0.1

The http-git script shows that the Nginx server on TCP/9001 has a Git repo at ssh://git@github.com-wiki/joswr1ght/SANS-504-Student-Wiki.

Nmap's -A option provides detailed info by detecting the OS, versions, running scripts, and traceroute results. It’s more informative than basic scans. Let’s use it now.

sudo nmap -A -p 5433,5443,9001,9002 127.0.0.1

Nmap gives port info, service versions (like Nginx 1.14.0), and checks which commands and details (like HTTP page titles) the services support.

In this lab, we saw how Nmap helps find active devices and services on a network. It also lets users gather more details with version scanning and NSE scripts. These features help understand the network setup and prepare for attacks.

Nmap is a strong tool but can be confusing at first. It only scans the top 1000 ports by default and doesn’t do much to find hosts before scanning. Learning how Nmap works helps us get better scan results and find vulnerabilities. By practicing with Nmap, we get better at using it effectively.

Bonus Lab

We have another Linux machine on the local 172.30.0.0 network. The Slingshot Linux VM is at 172.30.0.1, and the target is in the range 172.30.0.2-254.

1) What is the IP address of the target system?

Let's run Nmap with the -sn option to check which hosts are reachable.

nmap -sn 172.30.0.2-254

Answer: 172.30.0.20

2) Which TCP ports listening on the target system using a TCP connect scan?

Let's scan all TCP ports on host 172.30.0.20 using the -sT argument (connect scan).

sudo nmap -sT -p- 172.30.0.20

Answer: 21, 80, 38080, 38081, and 55558

Let's run nmap on open ports, but add the -sV option.

sudo nmap -sV -p21,80,38080,38081,55558 172.30.0.20

Comparing Nmap Scan Results with ndiff

Let's use ndiff from Nmap to quickly compare scan results. It's useful for spotting new services or hosts by comparing different scans, like a baseline with daily or weekly scans.

First, let's run an Nmap scan, saving the results in an XML.

nmap 127.0.0.1 -oX baseline.xml

Let's start the SSH service, run the scan again, and save the results as newscan.xml.

sudo service ssh start
nmap 127.0.0.1 -oX newscan.xml

Finally, let's compare the two XML using the ndiff utility:

ndiff baseline.xml newscan.xml

ndiff shows the second scan has an extra TCP port (port 22 for SSH). This means there's a new service running, so analysts need to check why this port was added.

Last updated