Host Discovery Techniques
There was a day when finding whether an IP address was registered to an active host was easy. Simply send an ICMP echo request (ping) packet and wait for a response. Firewalls rarely blocked these requests, and the vast majority of hosts obediently responded. Such a response has been required since 1989 by RFC 1122, which clearly states that “Every host MUST implement an ICMP Echo server function that receives Echo Requests and sends corresponding Echo Replies”.
Unfortunately for network explorers, many administrators have
decided that security concerns trump RFC requirements and have blocked
ICMP ping messages.
Example 3.8
uses an ICMP-only Nmap ping scan
against six popular Web sites, but receives only two responses. This
demonstrates that hosts can no longer be assumed unavailable based on
failure to reply to ICMP ping probes. The “-sn
-PE
” options in this example specify an ICMP-only ping
scan. The -R
option tells Nmap to perform
reverse-DNS resolution against all hosts, even down ones.
# nmap -sn -PE -R -v microsoft.com ebay.com citibank.com google.com \
slashdot.org yahoo.com
Starting Nmap ( https://nmap.org )
Host origin2.microsoft.com (207.46.250.252) appears to be down.
Host pages.ebay.com (66.135.192.87) appears to be down.
Host ld1-www.citicorp.com (192.193.195.132) appears to be down.
Host 216.239.57.99 appears to be up.
Host slashdot.org (66.35.250.150) appears to be down.
Host w3.rc.dcn.yahoo.com (216.109.127.30) appears to be up.
Nmap done: 6 IP addresses (2 hosts up) scanned in 3.76 seconds
Fortunately, Nmap offers a wide variety of host discovery
techniques beyond the standard ICMP echo request. They are described
in the following sections. Note that if you specify any of
the -P
options discussed in this section,
they replace the default discovery probes rather
than adding to them.
TCP SYN Ping (-PS<port list>
)
<port list>
The -PS
option sends an empty TCP packet with
the SYN flag set. The default destination port is 80 (configurable at
compile time by changing
DEFAULT_TCP_PROBE_PORT_SPEC
in nmap.h
),
but an alternate port can
be specified as a parameter. A list of ports may be specified
(e.g. -PS22-25,80,113,1050,35000
), in which case
probes will be attempted against each port in parallel.
The SYN flag suggests to the remote system that you are attempting to establish a connection. Normally the destination port will be closed, and a RST (reset) packet will be sent back. If the port happens to be open, the target will take the second step of a TCP three-way-handshake by responding with a SYN/ACK TCP packet. The machine running Nmap then tears down the nascent connection by responding with a RST rather than sending an ACK packet which would complete the three-way-handshake and establish a full connection.[10]
Nmap does not care whether the port is open or closed. Either the RST or SYN/ACK response discussed previously tell Nmap that the host is available and responsive.
On Unix boxes, only the privileged user root
is generally able to send and receive
raw TCP packets.
For unprivileged users, a workaround is automatically employed whereby the
connect
system call is initiated against each target port. This has
the effect of sending a SYN packet to the target host, in an attempt
to establish a connection. If connect
returns with a quick success
or an ECONNREFUSED failure, the underlying TCP stack must have
received a SYN/ACK or RST and the host is marked available. If the
connection attempt is left hanging until a timeout is reached, the
host is marked as down.
This workaround is also used for IPv6
connections, as raw IPv6 packet building support is not yet available
in Nmap.
Example 3.8 failed to detect four out of six machines because they did not respond to ICMP echo requests. Repeating the experiment using a SYN probe to port 80 (HTTP) garners responses from all six, as shown in Example 3.9.
# nmap -sn -PS80 -R -v microsoft.com ebay.com citibank.com google.com \
slashdot.org yahoo.com
Starting Nmap ( https://nmap.org )
Host origin2.microsoft.com (207.46.249.252) appears to be up.
Host pages.ebay.com (66.135.192.87) appears to be up.
Host ld1-www.citicorp.com (192.193.195.132) appears to be up.
Host 216.239.57.99 appears to be up.
Host slashdot.org (66.35.250.150) appears to be up.
Host w3.rc.dcn.yahoo.com (216.109.127.30) appears to be up.
Nmap done: 6 IP addresses (6 hosts up) scanned in 0.48 seconds
In addition to detecting all six machines, the second run is much faster. It takes less than half a second because the machines are scanned in parallel and the scan never times out waiting for a response. This test is not entirely fair because these are all popular web servers and thus can be expected to listen on TCP port 80. However, it still demonstrates the point that different types of hosts respond to different probe types. Nmap supports the usage of many scan types in parallel to enable effective scanning of diverse networks.
TCP ACK Ping (-PA<port list>
)
<port list>
The TCP ACK ping is quite similar to the SYN ping. The difference, as you could likely guess, is that the TCP ACK flag is set instead of the SYN flag. Such an ACK packet purports to be acknowledging data over an established TCP connection, but no such connection exists. So remote hosts should always respond with a RST packet, disclosing their existence in the process.
The -PA
option uses the same default port as the SYN
probe (80) and can also take a list of destination ports in the same
format.
If an unprivileged user tries this, or an IPv6 target is
specified, the connect
workaround discussed previously is used.
This workaround is imperfect because connect
is actually sending a
SYN packet rather than an ACK.
The reason for offering both SYN and ACK ping probes is to
maximize the chances of bypassing firewalls. Many administrators
configure routers and other simple firewalls to block incoming
SYN packets except for those destined for public services like the
company web site or mail server. This prevents other incoming
connections to the organization, while allowing users to make
unobstructed outgoing connections to the Internet. This non-stateful
approach takes up few resources on the firewall/router and is widely
supported by hardware and software filters. As just one example of
the prevalence of this method, the Linux
Netfilter/iptables firewall
software offers the --syn
convenience option, which
the man page describes as follows.
Only match TCP packets with the SYN bit set and the ACK and RST bits cleared. Such packets are used to request TCP connection initiation; for example, blocking such packets coming in an interface will prevent incoming TCP connections, but outgoing TCP connections will be unaffected. It is equivalent to --tcp-flags SYN,RST,ACK SYN.
When firewall rules such as this are in place, SYN ping probes (-PS
) are likely to be blocked when sent to closed target ports. In such cases, the ACK probe excels by cutting right through these rules.
Another common type of firewall uses stateful rules that drop unexpected packets. This feature was initially found mostly on high-end firewalls, though it has become much more common over the years. The Linux Netfilter/iptables system supports this through the --state
option, which categorizes packets based on connection state as described in the following man page excerpt:
Possible states are INVALID meaning that the packet is associated with no known connection, ESTABLISHED meaning that the packet is associated with a connection which has seen packets in both directions, NEW meaning that the packet has started a new connection, or otherwise associated with a connection which has not seen packets in both directions, and RELATED meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error.
The ACK probe is unlikely to work against firewalls taking this approach, as such an unexpected packet will be classified in the INVALID state and probably dropped. Example 3.10 shows an attempted ACK ping against Microsoft. Their stateful firewall drops the packet, leading Nmap to wrongly conclude that the host is down. The SYN probe has a much better chance of working in such cases. This raises the question of which technique to use when the firewall rules of the target networks are unknown or inconsistent. The proper answer is usually both. Nmap can send SYN and ACK probes to many ports in parallel, as well as performing other host discovery techniques at the same time. This is further discussed in the section called “Putting It All Together: Host Discovery Strategies”.
# nmap -sn -PA www.microsoft.com
Starting Nmap ( https://nmap.org )
Warning: Hostname www.microsoft.com resolves to 5 IPs. Using 207.46.192.254.
Note: Host seems down. If it is really up, but blocking ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 2.22 seconds
UDP Ping (-PU<port list>
)
<port list>
Another host discovery option is the UDP ping, which sends a UDP
packet to the given ports.
The port list takes the same format as with the
previously discussed -PS
and -PA
options. If no ports are specified, the default is 40,125. This default can be
configured at compile-time by changing
DEFAULT_UDP_PROBE_PORT_SPEC
in nmap.h
.
A highly uncommon port is used by default because sending to
open ports is often undesirable for this particular scan type.
For most ports, the packet will be empty,
though for a few common ports like 53 and 161, a protocol-specific
payload will be sent that is more likely to get a
response.
The
--data-length
option sends a fixed-length random payload for all ports.
Upon hitting a closed port on the target machine, the UDP probe should elicit an ICMP port unreachable packet in return. This signifies to Nmap that the machine is up and available. Many other types of ICMP errors, such as host/network unreachables or TTL exceeded are indicative of a down or unreachable host. A lack of response is also interpreted this way. If an open port is reached, most services simply ignore the empty packet and fail to return any response. This is why the default probe port is 40,125, which is highly unlikely to be in use. A few services, such as the Character Generator (chargen) protocol, will respond to an empty UDP packet, and thus disclose to Nmap that the machine is available. Custom payloads, for the ports that have them, make it more likely that a probe will get a response.
The primary advantage of this scan type is that it bypasses firewalls and filters that only screen TCP. For example, I once owned a Linksys BEFW11S4 wireless broadband router. The external interface of this device filtered all TCP ports by default, but UDP probes would still elicit port unreachable messages and thus give away the device.
ICMP Ping Types (-PE
, -PP
, and -PM
)
In addition to the unusual TCP and UDP host discovery types
discussed previously, Nmap can send the standard packets sent by the
ubiquitous ping program. Nmap sends an
ICMP type 8 (echo request) packet to the target IP addresses, expecting a type
0 (echo reply) in return from available hosts. As noted at the
beginning of this chapter, many hosts and firewalls now block these
packets, rather than responding as required by RFC 1122. For this
reason, ICMP-only scans are rarely reliable enough against unknown
targets over the Internet. But for system administrators monitoring
an internal network, this can be a practical and efficient approach.
Use the -PE
option to enable this echo request
behavior.
While echo request is the standard ICMP ping query, Nmap does
not stop there. The ICMP standards
(RFC 792
and
RFC 950)
also
specify timestamp request, information request, and address mask
request packets as codes 13, 15, and 17, respectively. While the
ostensible purpose for these queries is to learn information such as
address masks and current times, they can easily be used for host
discovery. Nmap does
not currently implement information request packets, as they are not
widely supported (RFC 1122 insists that “a host SHOULD NOT
implement these messages”). Timestamp and address mask queries
can be sent with the -PP
and -PM
options, respectively. A timestamp reply (ICMP code 14) or address
mask reply (code 18) discloses that the host is available. These two
queries can be valuable when administrators specifically block echo request
packets, but forget that other ICMP queries can be used for the same
purpose.
IP Protocol Ping (-PO<protocol list>
)
<protocol list>
The newest host discovery option is the IP protocol ping, which
sends IP packets with the specified protocol number set in their IP
header. The protocol list takes the same format as do port lists in
the previously discussed TCP and UDP host discovery options. If no
protocols are specified, the default is to send multiple IP packets
for ICMP (protocol 1), IGMP (protocol 2), and IP-in-IP (protocol 4).
The default protocols can be configured at compile-time by changing
DEFAULT_PROTO_PROBE_PORT_SPEC
in nmap.h
.
Note
that for the ICMP, IGMP, TCP (protocol 6), and UDP (protocol
17),
the packets are sent with the proper protocol headers while other
protocols are sent with no additional data beyond the IP header
(unless the
--data-length
option is specified).
This host discovery method looks for either responses using the same protocol as a probe, or ICMP protocol unreachable messages which signify that the given protocol isn't supported by the destination host. Either type of response signifies that the target host is alive.
ARP Scan (-PR
)
One of the most common Nmap usage scenarios is to scan an ethernet LAN. On most LANs, especially
those using private address ranges granted by RFC 1918, the vast majority
of IP addresses are unused at any given time. When Nmap tries to send
a raw IP packet such as an ICMP echo request, the operating system
must determine the destination hardware (ARP) address corresponding to
the target IP so that it can address the ethernet frame properly.
This requires it to issue a series of ARP requests. This is shown in
Example 3.11, where a ping scan
is attempted against a local ethernet host. The
--send-ip
option tells Nmap to send IP level packets (rather
than raw ethernet) even though it is a local network. Wireshark output
of the three ARP requests and their timing has been pasted into the
session.
# nmap -n -sn --send-ip 192.168.33.37
Starting Nmap ( https://nmap.org )
0.000000 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37?
0.999836 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37?
1.999684 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37?
Note: Host seems down. If it is really up, but blocking ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 2.04 seconds
This example took more than two seconds to finish because the (Linux) OS sent three ARP requests, one second apart, before giving up on the host. Given that ARP replies usually come within a couple milliseconds, multi-second waits are excessive. Decreasing this timeout period is no priority for OS vendors because the vast majority of packets are sent to hosts that actually exist. Nmap, on the other hand, must send packets to 16 million IPs when given a target such as 10.0.0.0/8. A two second wait for each becomes a huge delay even though many targets are pinged in parallel.
There is another problem with raw IP ping scans on LANs. When a
destination host is found to be unresponsive as in the previous
example, the source host generally adds an incomplete entry for that
destination IP in its kernel ARP table. ARP table space is finite,
and some operating systems react badly when it fills up. When Nmap is
used in raw IP mode (--send-ip
), Nmap sometimes has
to wait several minutes for ARP cache entries to expire before it can
continue with host discovery.
ARP scanning resolves both problems by putting Nmap in control. Nmap issues the raw ARP requests and handles retransmission and timeout periods at its own discretion. The system ARP cache is bypassed. Example 3.12 shows the difference. This ARP scan takes just over a tenth of the time taken by its IP equivalent.
# nmap -n -sn -PR --packet-trace --send-eth 192.168.33.37
Starting Nmap ( https://nmap.org )
SENT (0.0060s) ARP who-has 192.168.33.37 tell 192.168.0.100
SENT (0.1180s) ARP who-has 192.168.33.37 tell 192.168.0.100
Note: Host seems down. If it is really up, but blocking ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 0.23 seconds
In Example 3.12, neither
the -PR
or --send-eth
options have
any effect. This is because ARP is the default scan type when
scanning ethernet hosts that Nmap detects are on a local ethernet
network. This includes traditional wired ethernet as well as 802.11 wireless networks. Not only is ARP scanning more efficient as discussed above, it is also
more accurate. Hosts frequently block IP-based ping packets, but they
generally cannot block ARP requests or responses and still communicate
on the network. Even if different ping types (such as
-PE
or -PS
) are specified, Nmap uses
ARP instead for any of the targets which are on the same LAN.
If you absolutely don't want to do an ARP scan, specify
--send-ip
as shown in Example 3.11, “Raw IP ping scan of an offline target”.
Giving Nmap control to send raw ethernet frames also allows Nmap
to control the source MAC address. If you have the only PowerBook in
the room at a security conference and a massive ARP scan is initiated
from a MAC address registered to Apple, heads may turn in your
direction. You can spoof your MAC address with the
--spoof-mac
option, as discussed in the section called “MAC Address Spoofing”.
Default Combination
If none of these host discovery techniques are chosen, Nmap uses
a default which is equivalent to the -PE -PS443 -PA80 -PP
arguments for Windows or privileged (root) Unix users. Attentive
readers know that this means an ICMP echo request, a TCP SYN packet, a
TCP ACK packet, and an ICMP timestamp request are sent to each machine. An exception to this is
that an ARP scan is used for any targets which are on a local ethernet
network. For unprivileged Unix shell users, the default is equivalent
to -PS80,443
(a TCP connect
call against ports 80 and 443 of the
target hosts). For security auditing, I recommend using a more
comprehensive set of ping types, such as those discussed in the section called “Designing the ideal combinations of probes”.
[10] The RST packet is sent by the kernel of the machine running Nmap in response to the unexpected SYN/ACK, not by Nmap itself.