Host Discovery with Nmap

February 13, 2018

I’d originally planned to start my Nmap adventure a bit further in, but realized partway through post #1 that it should actually be post #2. I failed to appreciate the importance of the discovery phase.

Phases of an Nmap Scan

Before we get into the good stuff, let’s take a moment to get to know the phases of an Nmap scan.

  1. Script pre-scanning: Only applies when -sC or --script is used and a script needs it.
  2. Target enumeration: Targets are resolved to an IPv4 or IPv6 address. -sL -n will cause this to just print the list of targets.
  3. Host discovery (ping!): Uses various techniques to discover hosts. Using -sn -n will cause the scan to terminate after this phase. -Pn will skip this phase.
  4. Reverse-DNS resolution: Reverse DNS lookups for all alive hosts. Can be skipped with -n or done for all hosts, even down ones, using -R.
  5. Port scanning: Probes sent to ports. Ports are assigned open, open|filtered, closed, or filtered status. Skipped with -sn.
  6. Version detection: If -sV was specified, Nmap will attempt to fingerprint the service.
  7. OS detection: If -O was specified, Nmap will attempt to identify the target’s operating system.
  8. Traceroute: If --traceroute was specified, Nmap will traceroute the target and perform reverse DNS lookups on each hop.
  9. Script scanning: If --script was specified, Nmap will perform its scripty magic.
  10. Output: Display output to screen, or write to file (-oA, -oG, -oX).

The most important thing to understand here is that if a host is not identified in the discovery phase (step 3), no further actions will be performed on it. Seems obvious when you write it out, but underscores the important of getting the discovery phase right. Which is what we’re now going to discuss.

Default Host Discovery Settings

A basic Nmap ping scan looks like this: nmap -sn <targets>. Expanded, this is actually nmap -PE -PP -PR -PS443 -PA80.

What does this do, exactly?

Nmap Internet Host Discovery

Nmap’s options here are pretty solid; I think they were designed with external scans in mind. The -PA and -PS scans each check open TCP ports, but depending on firewall configuration one may work better than the other. You may want to double up on these (-PA80,443 -PS80,443).

Nmap Internal Host Discovery

Using Nmap’s default discovery settings, if the remote host has ICMP enabled (-PE, -PP), is on the local subnet (-PR), or is listening on ports 80 or 443 (-PS, -PA), we’ll get a response. ICMP is disabled by default on many host-based firewalls/IPS but we’ve got a few other options to compensate for that.

Let’s see what ports domain-joined Windows 10 system is listening to by default:


So in its default state, Nmap would totally miss this host unless it was on the same subnet where the ARP ping would pick it up. It would miss pretty much every other Windows host in their default state as well.

That is less than ideal.

Assuming we’re scanning hosts beyond the local subnet, what we really want in our discovery phase is a good guess at the kind of ports we’re going to find in the environment.

Here’s a good start:

Target Type TCP Ports
Windows 80, 135, 443, 445, 3389, 5985
Linux & Network Devices 21, 22, 23, 80, 443

The above list is based mostly on personal experience doing port scans and should detect most hosts. If you’re scanning a remote network and can’t afford to miss a few hosts, read on.

The Nuclear Option(s)

If you cannot miss a host and are willing to wait, you’ve got two options:

  1. -Pn - Skip discovery phase and assume all hosts in the target range are up.
  2. -PS1-65535 - Perform a SYN ping on all ports to all hosts in the target range.

I got tired of waiting for these two to complete in my lab against a /24. I suspect the first option will be faster since the second effectively opens a connection on all 65535 ports on every host in the scope, while the second will only scan the ports you tell it to using -p.

A Less Direct Approach

Depending on the information available to you, a less direct approach may be possible. If you’ve got access to a DNS server that will have PTR records for your targets, you can just query that directly for records without touching your target.

This sort of scan is also helpful if you’re trying to validate your scope and/or if you’re just lazy and want to turn a subnet into a list of IPs.

nmap -sL --dns-server <IP>

The --dns-server parameter is optional; if your host OS is already configured to use a DNS server with the appropriate records, you can just leave that part off.