Nmap can be divided into the following scanning techniques:

  1. Host discovery

  2. Port scanning

  3. Service enumeration/detection

  4. OS detection

  5. Scriptable interaction with a target service (Nmap Scripting Engine) Scanning Options

-sn # Disables port scanning
-Pn # Disables ICMP echo requests
-n # Disables DNS resolution 
-PE # Ping scan by using ICMP echo requests against target

--packet-trace # shows all packets sent/received
--reason # reason for a specific result
--disable-arp-ping # disables ARP ping requests
--top-ports=<num> # scans specifed top ports that have been defined as most frequent

-p- # scan all ports
-p22-110 # scan ports between 22-110
-p22,25 #scans only specified ports
-F # top 100 ports

-sS # TCP SYN-scan
-sA # TCP ACK-scan
-sU # UDP scan
-sV # version scan
-sC # script scan
-O # OS detection
-A # OS/service detection, traceroute

-D RND:S # number of random decoys used to scan target
-e # network int for scan
-s # source ip for scan
-g # source port for scan
--dns-server <ns> # dns resolution using a specified name server 

Output Options

-oA file # stores results in all avail fmts with name
-oN file # stores results in normal fmt with name
-oG file # stores results in grepable fmt with name
-oX file # stores results in xml fmt with name of file

Performance Options

---max-retries <num> # set num of retries for scans on ports
--stats-every=5s # display scan status every 5s
-v or -vv # verbose output
--initial-rtt-timeout 50ms # sets specified time value as RTT timeout
--max-rtt-timeout 100ms # sets time value as max RTT timeout
--min-rate 300 # num of packets sent simultaneously
--T <0-5> # specifies specific timing template


nmap <scan types> <options> <target>

  -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
  -sU: UDP Scan
  -sN/sF/sX: TCP Null, FIN, and Xmas scans
  --scanflags <flags>: Customize TCP scan flags
  -sI <zombie host[:probeport]>: Idle scan
  -sO: IP protocol scan
  -b <FTP relay host>: FTP bounce scan

TCP-SYN scan -sS

  • Default setting: Most popular method

  • Sends 1 packet with SYN flag: Never completes handshake: Results in no full TCP connection to scanned port

    • If target sends SYN-ACK packet back to scanned port: Detected as open

    • If packet receives RST: Port is closed

    • No packet received? Filtered

  • Depending on firewall config, certain packets may be dropped/ignored

sudo nmap -sS localhost
22/tcp   open  ssh
80/tcp   open  http
5432/tcp open  postgresql
5901/tcp open  vnc-1

Host Discovery

  • ICMP echo requests Most effective host discovery method Scan Network Range

  • Works only if firewalls of hosts allow it

sudo nmap -sn -oA tnet | grep for | cut -d" " -f5

-sn # disables port scanning
-oA name # stores results in all fmts

Scan IP List: Not uncommon to have an IP list to test: Option of working with lists avail

cat hosts.lst

If we use the same scanning technique on the predefined list, the command will look like this:

sudo nmap -sn -oA tnet -iL hosts.lst | grep for | cut -d" " -f5

-iL # performs defined scans against targets in hosts.lst list

#scan multiple IPs
sudo nmap -sn -oA tnet| grep for | cut -d" " -f5

If addresses are next to each other, we can define the range in the respective octet.
sudo nmap -sn -oA tnet| grep for | cut -d" " -f5
  • -sn Disable port scan

  • -PE Auto ping scan with ICMP Echo Requests

    • We usually expect ICMP reply if pinging host is live

    • Previous scans didn't do that because nmap would send an ARP ping resulting in ARP reply Can confirm with --packet-trace

sudo nmap -sn -oA host -PE --packet-trace 

SENT (0.0074s) ARP who-has tell
RCVD (0.0309s) ARP reply is-at DE:AD:00:00:BE:EF
Nmap scan report for
Host is up (0.023s latency).

-PE # ping scan by using ICMP echo requests
--packet-trace # all packets sent/received
--reason # another way to determine our target is 'alive' 
  • nmap does detect whether a host is alive/dead through arp request/reply alone

  • --disable-arp-ping we can disable arp pings

sudo nmap -sn -oA host -PE --packet-trace --disable-arp-ping 

SENT (0.0107s) ICMP [ > Echo request (type=8/code=0) id=13607 seq=0] IP [ttl=255 id=23541 iplen=28 ]
RCVD (0.0152s) ICMP [ > Echo reply (type=0/code=0) id=13607 seq=0] IP [ttl=128 id=40622 iplen=28 ]
Nmap scan report for
Host is up (0.086s latency).

Host and Port Scanning 6 different states for a scanned port we can obtain:

open # Connection to port established: Can be TCP/UDP/SCTP
closed # TCP indicates packet received contains RST flag: Can determine if target live/not
filtered # Can't correctly ID if port is open/closed because no-response/error code 
unfiltered # Only occurs during TCP-ACK scan: Port is accessible, but can't determine if open/closed
open\|filtered # No response for specific port: A firewall/packet filter may protect port
closed\|filtered # Only in IP ID idle scan: Impossible to determine if port closed/filtered by a firewall

Discovering Open TCP Ports

  • -sS Default: Nmap scans top 1000 TCP ports with SYN scan

  • Set only to default when run as root: Socket perms required to create raw TCP packets

  • -sT Otherwise TCP scan performed by default

    • If we don't define ports/scanning methods, params set automatically We can define ports:

  • One by one -p 22,25,80,139,445

  • Range -p 22-445

  • Top ports --top-ports=10

  • Scanning all ports -p-

  • By defining a fast port scan -F Trace Packets

sudo nmap -p 21 --packet-trace -Pn -n --disable-arp-ping

SENT (0.0429s) TCP > S ttl=56 id=57322 iplen=44  seq=1699105818 win=1024 <mss 1460>
RCVD (0.0573s) TCP > RA ttl=64 id=0 iplen=40  seq=0 win=0
Nmap scan report for

21/tcp closed ftp
MAC Address: DE:AD:00:00:BE:EF (Intel Corporate)

--packet-trace # shows all packets sent/received
-n # disables dns resolution
  • SENT: sent a TCP packet with SYN to target

  • RCVD: Target responds with TCP packet containing RST/ACK flags (RA)

    • Used to acknowledge receipt of TCP packet (ACK) and to end TCP session (RST) Connect Scan -sT

  • Uses TCP 3-way handshake to determine if a port is open/closed

  • Sends SYN packet to port/waits for response

    • Open if port responds with SYN-ACK

    • Closed if it responds with RST

  • Most accurate way to determine the state of a port: Most stealthy

  • Doesn't leave unfinished connections/unsent packets on target host

    • Makes it less likely to be detected by IDS/IPS

  • Useful to map network/not disturb services behind

  • Useful when host has a firewall that drops packets but allows outgoing

  • A connect scan can bypass a firewall/accurately determine the state of target ports

    • Slower than other scan types

    • Requires scanner to wait for a response from target after each packet sent

sudo nmap -p 443 --packet-trace --disable-arp-ping -Pn -n --reason -sT 

CONN (0.0385s) TCP localhost > => Operation now in progress
CONN (0.0396s) TCP localhost > => Connected
Nmap scan report for

443/tcp open  https   syn-ack

Filtered Ports

  • Firewalls have certain rules set to handle specific connections

    • Packets can be dropped/rejected: nmap receives no response from target

    • --max-retries Default: Set to 1: nmap will resend request to determine if previous packet was mishandled

  • Example:

    • Firewall drops TCP packets sent

    • We scan port 139: Shown as filtered

  • To track how sent packets handled:

    • -Pn Deactivate ICMP echo requests

    • -n DNS resolution

    • --disable-arp-ping

sudo nmap -p 139 --packet-trace -n --disable-arp-ping -Pn

SENT (0.0381s) TCP > S ttl=47 id=14523 iplen=44  seq=4175236769 win=1024 <mss 1460>
SENT (1.0411s) TCP > S ttl=45 id=7372 iplen=44  seq=4175171232 win=1024 <mss 1460>
Nmap scan report for

139/tcp filtered netbios-ssn

Open UDP Ports -sU

  • UDP is stateless: Doesn't require 3-way handshake

  • No acknowledgment

    • Timeout much longer, making it slower than TCP scans -sS

sudo nmap -F -sU

Host is up (0.059s latency).
Not shown: 95 closed ports
68/udp   open|filtered dhcpc
137/udp  open          netbios-ns
5353/udp open          zeroconf

-F # scan 100 top ports
-sU # udp scan
  • We often don't get a response back: nmap sends empty datagrams to scanned UDP ports

  • We don't receive a response: Can't determine if packet arrived or not

    • We only get a response if the app is configured to do so

sudo nmap -sU -Pn -n --disable-arp-ping --packet-trace -p 137 --reason 

SENT (0.0367s) UDP > ttl=57 id=9122 iplen=78
RCVD (0.0398s) UDP > ttl=64 id=13222 iplen=257

137/udp open  netbios-ns udp-response ttl 64

--reason # displays why a port is in a particular state
-Pn # disables ICMP echo requests
-n # disables dns resolution

ICMP response with error code 3? Port closed

Saving Results 3 formats:

  1. -oN Normal: .nmap

  2. oG Greppable: .gnmap

  3. -oX .xml -oA Specify option to save results in all formats

  • If no path given: Stores in dir scanning in

sudo nmap -p- -oA target

Style sheets

  • With XML we can create HTML reports

  • To convert stored results from XML to HTML, we can use a tool xsltproc

xsltproc target.xml -o target.html

Banner Grabbing:

sudo tcpdump -i eth0 host and
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

# tcpdump - Intercepted traffic 
18:28:07.255151 IP > Flags [S.], seq 1130574379, ack 1798872234, win 
18:28:07.319306 IP > Flags [P.], seq 1:36, ack 1, win 510, options [nop,nop,TS val 1800383985 ecr 331260304], length 35: SMTP: 220 inlane ESMTP Postfix (Ubuntu)

# NC
nc -nv 25
Connection to port 25 [tcp/*] succeeded!
220 inlane ESMTP Postfix (Ubuntu)

Nmap Scripting Engine

  • Can create scripts in LUA for interaction with certain services 14 categories of scripts

auth # determine auth creds 
broadcast # host discovery by broadcasting/automatically adding to remaining scans
discovery # accessible services
fuzzer # id vulns/unexpected packet handling by sending diff fields
intrusive # could negatively affect target
malware # checks if some malware infects target
safe # don't perform intrusive/destructive access

# ways to define desired scripts 
sudo nmap <target> -sC # default scripts
sudo nmap <target> --script <category> # specific category script
sudo nmap <target> --script <script-name>,<script-name>,... # defined

#specifying scripts 
sudo nmap -p 25 --script banner,smtp-commands

25/tcp open  smtp
|_banner: 220 inlane ESMTP Postfix (Ubuntu)

-A # Aggressive option: Scans with multiple options -sV, -O, --traceroute and default NSE scripts -sC

Performance Timeouts

  • RTT - ROUND-TRIP-TIME When Nmap sends a packet, it takes some time to receive a response from the port

    • --min-RTT-timeout Nmap starts with a high timeout of 100ms

# default 
sudo nmap -F
Nmap done: 256 IP addresses (10 hosts up) scanned in 39.44 seconds

# optimized RTT 
sudo nmap -F --initial-rtt-timeout 50ms --max-rtt-timeout 100ms
Nmap done: 256 IP addresses (8 hosts up) scanned in 12.29 seconds

-F # scans top 100 ports
--intial-rtt-timeout 50ms # sets time value as RTT timeout
--max-rtt-timeout 100s # sets time value as max RTT timeout

Max Retries

  • --max--retries Another way to increase speed is to specify a retry rate of sent packets

  • Default retry rate: 10

    • If nmap doesn't receive a response: It won't send any more packets to the port/skips it

# default 
sudo nmap -F | grep "/tcp" | wc -l
#Reduced retries 
sudo nmap -F --max-retries 0 | grep "/tcp" | wc -l

Rates If we know the bandwidth, we can work with the rate of packets sent: Speeds up scans

  • --min-rate <num> Tell nmap to simultaneously send a specified number of packets

sudo nmap -F -oN tnet.default
Nmap done: 256 IP addresses (10 hosts up) scanned in 29.83 seconds

sudo nmap -F -oN tnet.minrate300 --min-rate 300
Nmap done: 256 IP addresses (10 hosts up) scanned in 8.67 seconds

-F # top 100 ports
-oN tnet.minrate300 # saves results in normal fmts starting specified name
--min-rate 300 # sets min number of packets sent per second 

Timing 6 timing templates -T <0-5>

  • Values 0-5 determine the aggressiveness of scans

  • Can have negative effects if too aggressive and security systems may block

  • Default timing template: -T 3

-T 0 # paranoid
-T 1 # sneaky
-T 2 # polite
-T 3 # normal
-T 4 # aggressive
-T 5 # insane

# default scan 
sudo nmap -F -oN tnet.default 
Nmap done: 256 IP addresses (10 hosts up) scanned in 32.44 seconds

# insane Scan
sudo nmap -F -oN tnet.T5 -T 5
Nmap done: 256 IP addresses (10 hosts up) scanned in 18.07 seconds

-T 5 # specifies insane timing template 

Default Scan - Found Open Ports
cat tnet.default | grep "/tcp" | wc -l

Insane Scan - Found Open Ports
cat tnet.T5 | grep "/tcp" | wc -l

Firewall and IDS/IPS Evasion Determine Firewalls and Their Rules

  • We already know when a port is filtered, it can have several reasons

  • Firewalls have certain rules set to handle specific connections

  • Packets can be dropped/rejected: Dropped packets ignored/no response returned

  • Rejected packets: Returned RST flag: Contain diff types of ICMP error codes Such errors can be:

- Net Unreachable
- Net Prohibited
- Host Unreachable
- Host Prohibited
- Port Unreachable
- Proto Unreachable

-sA TCP ACK scan method is harder to filter for firewalls and IDS/IPS systems than regular SYN -sS/connect scans sT

  • They only send TCP packets with ACK flag

  • When a port is closed/open: Host must respond with RST

  • Packets with ACK are often passed by firewalls because they can't determine if the connection was external/internal Detect IDS/IPS

  • Unlike firewalls: IDS/IPS systems is more difficult because they are passive traffic monitoring

  • IDS: Examine all connections between hosts

  • IPS: Take measures config by admin to prevent potential attacks automatically

    • IPS serves as a complement to IDS Decoys

  • Cases where admins block specific subnets from diff regions

  • Prevents any access

  • -D Decoy scanning method

    • nmap generates various random IP's in the IP header to disguise the origin of the packet sent

    • We can generate random RND a specific number for example: 5 of IP's separated by a colon :

    • Our real IP is randomly placed between the generated ones

      • Decoys must be alive

# scan using decoys=
sudo nmap -p 80 -sS -Pn -n --disable-arp-ping --packet-trace -D RND:5

SENT (0.0378s) TCP > S ttl=42 id=29822 iplen=44  seq=3687542010 win=1024 <mss 1460>
SENT (0.0378s) TCP > S ttl=59 id=29822 iplen=44  seq=3687542010 win=1024 <mss 1460>
SENT (0.0379s) TCP > S ttl=37 id=29822 iplen=44  seq=3687542010 win=1024 <mss 1460>

80/tcp open  http
  • Spoofed packets are often filtered out by ISPs/routers

  • We can also specify our VPS servers' IP's/use them in combination with IP ID manipulation in headers

  • Another scenario: Only individual subnets would not have access to server's specific services

    • Can manually specify source IP -S to test if we get better results

    • Decoys can be used for SYN, ACK, ICMP scans and OS detection

# Testing firewall rule 
moo@htb[/htb]$ sudo nmap -n -Pn -p445 -O

445/tcp filtered microsoft-ds
MAC Address: DE:AD:00:00:BE:EF (Intel Corporate)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop

# Scan by Using Different Source IP
sudo nmap -n -Pn -p 445 -O -S -e tun0

445/tcp open  microsoft-ds
MAC Address: DE:AD:00:00:BE:EF (Intel Corporate)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 2.6.32 (96%), Linux 3.2 - 4.9 (96%), Linux 2.6.32 - 3.10 (96%), Linux 3.4 - 3.10 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Synology DiskStation Manager 5.2-5644 (94%), Linux 2.6.32 - 2.6.35 (94%), Linux 2.6.32 - 3.5 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

-n # disable dns resolution
-Pn # disable icmp echo requests
-O # OS detection
-S # scans target using diff source IP
-e tun0 # sends all requests through specified int

DNS Proxying

  • Default: nmap performs reverse DNS resolution unless otherwise specified

  • DNS queries passed in most cases because the given web server is supposed to be found/visited

  • Made over UDP port 53

  • TCP port 53: Previously only used for Zone transfers between DNS servers/data xfer larger than 512 bytes

  • This is changing due to IPv6/DNSSEC

--dns-server <ns>,<ns>

  • Method of specifying our own DNS: Could be fundamental if in a DMZ: Demilitarized Zone

  • Company DNS servers are usually more trusted than those from the Internet

# SYN-scan of a filtered port
sudo nmap -p50000 -sS -Pn -n --disable-arp-ping --packet-trace

SENT (0.0417s) TCP > S ttl=41 id=21939 iplen=44  seq=736533153 win=1024 <mss 1460>
SENT (1.0481s) TCP > S ttl=46 id=6446 iplen=44  seq=736598688 win=1024 <mss 1460>

50000/tcp filtered ibm-db2

# SYN-Scan From DNS Port
sudo nmap -p50000 -sS -Pn -n --disable-arp-ping --packet-trace --source-port 53

SENT (0.0482s) TCP > S ttl=58 id=27470 iplen=44  seq=4003923435 win=1024 <mss 1460>
RCVD (0.0608s) TCP > SA ttl=64 id=0 iplen=44  seq=540635485 win=64240 <mss 1460>

50000/tcp open  ibm-db2

--source-port 53 # performs scans on specified source port
# Connect to filtered port 
ncat -nv --source-port 53 50000
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Connected to
220 ProFTPd

Last updated