Host discovery with nmap

Published: 2014-08-12
Last Updated: 2014-08-12 12:27:30 UTC
by Adrien de Beaupre (Version: 1)
2 comment(s)

I enjoy performing penetration tests, I also enjoy teaching how to do penetration testing correctly. Next time up is SANS Sec560 network penetration testing in Albuquerque, NM. When I am teaching one of the points I make is to make good use of your tools. You really want to know which tools is appropriate for which parts of the engagement methodology and test plan. You also want to be familiar with the features and quirks of each tool in your kit. Most people are familiar with nmap as a port scanner, and often some of the other features such as service versioning and operating system fingerprinting. What I would like to talk about today are some of the features of nmap that work well together. One of the tasks in a penetration test or a vulnerability assessment is to identify which hosts are likely alive and responsive. Security testing involves sending stimulus, monitoring, and seeing responses. In this case we typically use nmap to send the stimulus, tcpdump to perform the monitoring, and the responses will tell us which hosts are responding to the packets nmap is sending.

Nmap is most often used to perform a ping sweep with its default series of packets. This option was -sP and is now -sn.

'nmap -sn -iL targets nmap-default-ping'

With root privileges this will send ICMP ech request (ping), a TCP SYN packet to port 443, a TCP ACK packet to port 80, and an ICMP timestamp request. This is efficient and in many cases is sufficient to identify those hosts that are responsive. In the case of a relatively flat internal network this is often the case.  

Tcpdump shows us that 4 packets were sent, 4 responses were also seen.

17:08:37.469613 IP > ICMP echo request, id 44412, seq 0, length 8
17:08:37.469641 IP > Flags [S], seq 4035393928, win 1024, options [mss 1460], length 0
17:08:37.469658 IP > Flags [.], ack 4035393928, win 1024, length 0
17:08:37.469664 IP > ICMP time stamp query id 30952 seq 0, length 20
17:08:37.541827 IP > ICMP echo reply, id 44412, seq 0, length 8
17:08:37.541841 IP > Flags [R.], seq 0, ack 4035393929, win 0, length 0
17:08:37.541868 IP > Flags [R], seq 4035393928, win 0, length 0
17:08:37.541968 IP > ICMP time stamp reply id 30952 seq 0: org 00:00:00.000, recv 21:00:18.026, xmit 21:00:18.026, length 20

( is

The problem with only sending these 4 packets as the means to do hosts discovery is that it may miss many test cases, and is therefore less accurate. This is an issue in many pentests where we need to balance accuracy against efficient use of our time. Scanning an arbitrary /19 and we see the following results:

Nmap done: 8192 IP addresses (5668 hosts up) scanned in 24.31 seconds
           Raw packets sent: 26981 (968.952KB) | Rcvd: 5954 (176.168KB)

Now consider the following:
 'nmap -sn -PS -PA -PU -PY -PE -PP -PM -PO -n -vv --reason --packet-trace --traceroute -iL targets -oA nmap-full-sweep'
Nmap done: 8192 IP addresses (5676 hosts up) scanned in 438.24 seconds
           Raw packets sent: 80075 (2.518MB) | Rcvd: 94752 (4.014MB)

The --reason option tells us which stimulus the hosts responded to. --paket-trace outputs to the screen the packets flying back and forth, giving us a visual indicator to see if the tests are running correctly. The second scan sends 3 different ICMP packets, TCP, UDP, SCTP, and some raw IP packets. The only other tool I often run along with nmap is ike-scan to identify VPN devices that do not respond to any other packets. From the nmap man page:             
-sn: Ping Scan - disable port scan
-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping

We gained an additional 8 hosts identified as being responsive, however we sent over 3 times the packets and it took much much longer. The second scan is arguably much more accurate, and certainly is a much more impressive command line! Putting together the tools we can construct a nice bash script to run tcpdump and nmap against a target list. The script checks to see if has root privilege, sets up some variables, creats a scan log, runs tcpdump, runs nmap, then stops tcpdump.  

Adrien de Beaupre Inc.

Check out BSides Ottawa, our CfP is still open! Con is 5-6 September
I will be teaching SANS Sec560, Network Penetration Testing next in Albuquerque, NM!


Begin script:

#Usage: targetfilename
# Modified 10 August 2014, Adrien de Beaupre
# Check to see if we have root privileges, exit if not.
if [[ $EUID -ne 0 ]]; then
        echo "$0 must be run as root"
        exit 1
# Check to see if we have a filename as one argument, exit if not.
# Number of arguments we want
if [ $# -ne $GOODARGS ]; then
        echo "Usage: `basename $0` {targetfilename}"
        exit 1
# Check to see if target file exists, exit if not
if [ ! -f $1 ]; then
        echo "Target file \"`basename $1`\" does not exist"
        exit 1
# Declare variables
# Target file
TARGETS=`cat $1`
# Timestamp variable
NOW=$(date +%F-%s)
# Tcpdump program to run variable
# Run the tcpdump program
$TCPDUMP -n -v -i eth0 -w tcpdump-discovery.$NOW.$1.dump 2>/dev/null &
# Variable for the process ID
# Start discovery scan, create or append to scanlog
echo -e 'Discovery scan start:' $HOST | tee -a scanlog
date >> scanlog
# Nmap discovery
nmap -sn -PS -PA -PU -PY -PE -PP -PM -PO -n -vv --reason --packet-trace --traceroute -iL $1 -oA $1-discovery-nmap-$NOW
# Wait two seconds before killing sniffer
sleep 2
# Kill the tcpdump program by PID
echo -e 'Tcpdump stopped:' $HOST | tee -a scanlog
date >> scanlog
kill $PID

2 comment(s)


Thanks for this great writeup! Very educational.
hi there,
wouldn't it be a good idea to first scan with the simple "-sn" option and then scan the rest of "unresponsive" systems with the long commandline (nmap -sn -PS -PA -PU -PY -PE -PP -PM -PO...) options to identify further systems?
it would decrease the ammount of pakets sent through the wire, the fw's and the rest of the peripherie...


Diary Archives