courses

Network Reconnaissance

Knowing the target before you touch it

This page really takes a strong view of nmap, and attempts to make you as comfortable as possible with the tool. It’s quite often one of the first tools you will pull out when looking at a network target – what services, ports, protocols, etc. are running on the target?

Often the prelude to a packet capture, this does sometimes go in the other direction. If we can hang the target device off a network link we control, it’s possible to tap the link and observe any and all traffic that terminates or originates with the target machine. Ofttimes though, network targets are passively listening, waiting for inbound connections. A packet capture can’t tell you that, but an nmap scan can!

And sure, you absolutely could write your own tools for this. Sometimes that’s even the only way to do what you want – nmap is so well known in the industry that some network stacks identify and ignore the packets it creates. In those cases, you really do need to craft a scanner yourself. In an ideal world, nmap would never work. Fortunately for security researchers, the world is not perfect and nmap works more often than it fails!

nmap

Nmap is a network mapping tool which runs on many different platforms. Below you can see a simple asciinema recording of it’s help documentation (no audio).

As a tool, nmap has operational modes including (but not limited to)

scanning a single host for open TCP ports scanning a single host for open UDP ports scanning a network for active hosts in depth scanning a network Because of the sheer scope of capability, some of the functionality requires root privileges. Use sudo on your Ubuntu VM for any scans that require it (raw socket access for SYN scans, OS detection, etc.).

A simple example, taken from the manpage (man nmap) can be seen below:

Asciinema recording: nmap help output and Example 1 scan of scanme.nmap.org (transcript below)

Text transcript: nmap introduction and Example 1 from the man page</summary>

$ which nmap
/bin/nmap

$ man nmap
NMAP(1)  Nmap Reference Guide

NAME
    nmap - Network exploration tool and security / port scanner

SYNOPSIS
    nmap [Scan Type...] [Options] {target specification}

DESCRIPTION
    Nmap ("Network Mapper") is an open source tool for network exploration
    and security auditing. [...] Nmap uses raw IP packets to determine what
    hosts are available, what services those hosts are offering, what
    operating systems they are running, and other characteristics.

    Example 1. A representative Nmap scan:
        # nmap -A -T4 scanme.nmap.org

$ nmap -A -T4 scanme.nmap.org
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-23 20:00 PST
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.0041s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Not shown: 992 closed ports
PORT      STATE    SERVICE    VERSION
22/tcp    open     ssh        OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux)
80/tcp    open     http       Apache httpd 2.4.7 ((Ubuntu))
[... additional ports ...]

Checks nmap is installed (/bin/nmap), reviews the man nmap page including the canonical nmap -A -T4 scanme.nmap.org example (-A enables OS detection, version detection, script scanning, and traceroute; -T4 sets aggressive timing), then runs that exact example live against Nmap’s public test target. </details>

While the above example is simplistic (and taken from the manpage, as described in the cast), it should give you a sense of the scope of nmap. By the way, try copy/pasting the example given in the cast into a terminal session on your Ubuntu VM.

For the immense documentation, please see the Nmap docs.

Host Discovery

Before port scanning an entire subnet, the smart move is to find out which hosts are actually up. Scanning dead addresses wastes time — especially on large networks.

ARP Ping (most reliable on local networks)

On a local network, ARP is the fastest and most reliable discovery method because every reachable host must respond to ARP — there is no firewall that can silently drop it:

$ sudo nmap -sn -PR 192.168.1.0/24

-sn means “no port scan” (host discovery only). -PR forces ARP ping. The output gives you a clean list of live hosts with their MAC addresses and vendor names.

ICMP Discovery

When ARP isn’t available (e.g., you’re scanning across routers), ICMP echo is the classic fallback:

$ sudo nmap -sn -PE 192.168.1.0/24

Additional ICMP types:

  • -PP — ICMP timestamp request
  • -PM — ICMP address mask request

Some hosts block ICMP echo but respond to the others, so combining them is useful:

$ sudo nmap -sn -PE -PP -PM 192.168.1.0/24

TCP/UDP Discovery

For hosts that block ICMP entirely, TCP and UDP probes can find them:

# TCP SYN to port 443 and TCP ACK to port 80
$ sudo nmap -sn -PS443 -PA80 192.168.1.0/24

# UDP probe to port 53 (DNS)
$ sudo nmap -sn -PU53 192.168.1.0/24

Saving the Host List

Once you have live hosts, save them for follow-on scans rather than repeating discovery:

$ sudo nmap -sn -PR 192.168.1.0/24 -oG - | awk '/Up$/{print $2}' > live_hosts.txt

Then use that list as input:

$ sudo nmap -iL live_hosts.txt [scan options]

Port Scanning Techniques

SYN Scan (-sS) — the default with root

Sends a SYN, waits for SYN-ACK (open) or RST (closed), then sends RST rather than completing the handshake. Fast, relatively stealthy (no completed connection logged by most application-layer daemons):

$ sudo nmap -sS 192.168.1.10

TCP Connect Scan (-sT) — no root required

Completes the full three-way handshake. Slower and more visible in logs, but works without elevated privileges:

$ nmap -sT 192.168.1.10

UDP Scan (-sU)

UDP is slower and less reliable — closed ports return ICMP port-unreachable, open ones often return nothing. Combine with --top-ports to keep it manageable:

$ sudo nmap -sU --top-ports 100 192.168.1.10

ACK Scan (-sA) — firewall mapping

ACK packets should always get a RST back from any reachable host, regardless of whether the port is open. If you get no response, a stateful firewall is filtering the packet. Use this to map firewall rules, not open ports:

$ sudo nmap -sA 192.168.1.10

Specifying Ports

Syntax Meaning
-p 22,80,443 specific ports
-p 1-1024 range
-p 20-25,80,443,8080-8090 mixed
-p- all 65535 ports
--top-ports 100 most common 100 ports
-F fast mode (top 100)

Service and Version Detection

Knowing a port is open is one thing; knowing what is listening is far more useful. Version detection sends protocol-specific probes and matches responses against nmap’s service database:

$ sudo nmap -sV 192.168.1.10

The --version-intensity option (0–9, default 7) trades accuracy for speed. Intensity 0 uses only the most likely probes; 9 tries everything:

$ sudo nmap -sV --version-intensity 5 192.168.1.10

OS Detection

OS fingerprinting works by sending a series of probes and comparing the TCP/IP stack responses against a database of known signatures:

$ sudo nmap -O 192.168.1.10

If nmap isn’t confident, --osscan-guess lets it report its best guess anyway:

$ sudo nmap -O --osscan-guess 192.168.1.10

OS detection requires at least one open and one closed TCP port to work reliably. If it can’t find both, results may be poor.

Nmap Scripting Engine (NSE)

NSE is where nmap transitions from a port scanner to a full reconnaissance platform. Scripts are written in Lua and organized into categories: auth, broadcast, brute, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, vuln.

Running script categories

# Run all "safe" + "discovery" scripts
$ sudo nmap --script="safe and discovery" 192.168.1.10

# Run the default set (same as -sC)
$ sudo nmap -sC 192.168.1.10

Useful scripts for local network recon

Script What it does
smb-os-discovery Pulls OS, hostname, domain, workgroup via SMB
smb-enum-shares Lists SMB shares
nbstat NetBIOS name table — quick Windows host identification
dns-brute Brute-forces subdomains against a DNS server
http-title Grabs the <title> from HTTP responses
http-headers Shows HTTP response headers
ssl-cert Dumps the TLS certificate (hostname, expiry, issuer)
ssh-hostkey Retrieves SSH host keys and fingerprints
snmp-info Queries SNMP for system info (community string: public)

Example — quick SMB recon sweep of the local subnet:

$ sudo nmap -p 139,445 --script="smb-os-discovery,smb-enum-shares,nbstat" -iL live_hosts.txt

Example — web server recon:

$ sudo nmap -p 80,443,8080,8443 --script="http-title,http-headers,ssl-cert" 192.168.1.0/24

Output Formats

Always save your scan results. You’ll want to refer back to them, diff runs over time, or feed them into other tools.

Flag Format Use case
-oN Normal (human-readable) Reading in a terminal
-oX XML Parsing with scripts, importing to Metasploit/Faraday
-oG Grepable Quick grep/awk pipelines
-oS Script kiddie s|\<rIpt kIddi3 — novelty only
-oA <base> All three at once Recommended default for any real scan
$ sudo nmap -sV -O -oA scan_results 192.168.1.0/24
# creates scan_results.nmap, scan_results.xml, scan_results.gnmap

Timing and Performance

Timing templates (-T0 through -T5) balance speed against accuracy and detectability:

Template Name When to use
-T0 Paranoid IDS evasion — extremely slow, serial
-T1 Sneaky IDS evasion — slow
-T2 Polite Reduces load on target network
-T3 Normal Default
-T4 Aggressive Fast networks, lab environments
-T5 Insane Very fast networks — may miss results

For local VM lab work, -T4 is a reasonable choice. For anything resembling a production network, stick with -T3 or lower.

A Practical Local Recon Workflow

Putting it all together — a methodical approach to surveying an unknown local network:

Step 1: Discover live hosts

$ sudo nmap -sn -PR -oG - 192.168.1.0/24 | awk '/Up$/{print $2}' > live_hosts.txt
$ wc -l live_hosts.txt   # sanity check

Step 2: Quick port survey of live hosts

$ sudo nmap -sS --top-ports 1000 -T4 -iL live_hosts.txt -oA quick_scan

Step 3: Deep dive — version detection + OS + default scripts

$ sudo nmap -sS -sU -sV -O -sC -p $(grep 'open' quick_scan.gnmap | grep -oP '\d+/open' | cut -d/ -f1 | sort -un | tr '\n' ',') -iL live_hosts.txt -oA deep_scan

Or more simply, -A bundles OS detection, version detection, script scanning, and traceroute:

$ sudo nmap -A -iL live_hosts.txt -oA deep_scan

Step 4: Targeted script scanning on interesting services

# If SMB hosts appeared:
$ sudo nmap -p 139,445 --script="smb-os-discovery,smb-enum-shares" -iL live_hosts.txt

# If web servers appeared:
$ sudo nmap -p 80,443 --script="http-title,http-headers,ssl-cert" -iL live_hosts.txt

Step 5: Review and document

$ grep 'open' deep_scan.gnmap    # quick summary of all open ports
$ cat deep_scan.nmap             # full human-readable output

Things to try yourself!

  1. Simple scans against scanme.nmap.org (nmap’s official test target — scanning it is explicitly permitted):
    1. Take a look at the nmap man page (man nmap), and then perform the following scans:
      • a TCP connect scan (-sT) of ports 20-100, 130-150, and 400-500
      • a UDP scan of the top 100 ports
      • an OS detection scan with aggressive guessing
      • an IP protocol scan (-sO)
    2. Try at least 2 output formats. Save results with -oA scanme_results. Personally, I find the -oS output amusing.
  2. Local network host discovery:
    1. Run an ARP ping sweep of your VM’s subnet (-sn -PR). How many hosts respond? What MAC vendor prefixes do you see?
    2. Compare the ARP results to an ICMP sweep (-sn -PE). Any differences? Why might hosts appear in one but not the other?
    3. Save the live host list to a file and use it as input (-iL) for all subsequent scans.
  3. Port scanning your local subnet (use your live hosts file from above):
    1. Run a SYN scan (-sS) of the top 1000 ports. What services are visible?
    2. Run a UDP scan (-sU) of the top 100 ports. Compare to TCP — what’s different?
    3. Try the TARGET SPECIFICATION options from the manpage:
      • combine CIDR notation with --exclude
      • try a different timing template and note the time difference
  4. Service and OS detection:
    1. Run -sV against your live hosts. What service banners do you get?
    2. Run -O --osscan-guess. How accurate is nmap’s OS detection against your VMs?
    3. Run -A (the “kitchen sink” flag) and compare the output to the individual flags above.
  5. NSE scripts:
    1. Run --script="default" (or equivalently -sC) against your live hosts. What additional information appears?
    2. If any hosts have ports 139 or 445 open, run the SMB scripts (smb-os-discovery, smb-enum-shares).
    3. If any hosts have port 80 or 443 open, run http-title and ssl-cert.
  6. Full local recon workflow: Follow the workflow in the Practical Local Recon Workflow section above against your VM subnet. Save all output with -oA. My subnet took about 3 minutes end-to-end with -T4 — YMMV.

I’ll be going over these exercises in class, but I would encourage you to try them on your own first. If you get stuck, please reach out for assistance! I’m happy to help. I’ll be recording a screen capture as usual, but will also post an asciinema link below.

Key takeaways

  • nmap is usually the first tool out: it answers what hosts, ports, services, and OSes are here? — questions a passive packet capture can’t, since listeners are silent until contacted.
  • Discover before you scan: find live hosts first (-sn), preferring ARP ping (-PR) on a local segment because every reachable host must answer ARP; fall back to ICMP/TCP/UDP probes across routers. Save the list and reuse it with -iL.
  • Pick the scan to the privilege and goal: -sS SYN (fast, default with root), -sT connect (no root, more visible), -sU UDP (slow), -sA ACK (maps firewall filtering, not open ports).
  • Go past “open” with -sV (service/version), -O (OS fingerprint, needs one open + one closed port), and the NSE Lua scripts (-sC/--script=) that turn nmap into a recon platform.
  • Always save output (-oA writes normal/XML/grepable at once) and tune timing (-T4 for labs, -T3 or lower for production) — timing also governs detectability.
  • nmap is active and noisy — only scan hosts you own or are authorized to test (scanme.nmap.org is the sanctioned practice target). When stacks fingerprint and drop nmap’s packets, hand-crafted probes (see Scapy) are the fallback.

References


Related course pages: Capturing traffic with tcpdump · Analyzing traffic with Wireshark · Introduction to Networking · Defensive measures: firewalls and IDS

🛠️ Maintenance note: the asciinema cast shows Nmap 7.80 scanning scanme.nmap.org in 2020 — the live output (ports, versions, current Nmap release) drifts over time, so treat it as illustrative and re-run against the current version each term. NSE script names and categories evolve; the linked NSE docs are authoritative.