WarFi Labs

nmap

network mapping ยท NPSL

The map you draw before anything else: which hosts are alive, which ports are open, and what services sit behind them.

Authorized use only. Run these only on systems you own or have explicit written permission to test. Full notice at the foot of the page.

01How nmap works

Nmap works by sending crafted packets and listening to what comes back. For TCP its default is a SYN scan: it sends a single SYN, the opening of the normal handshake. A SYN/ACK means the port is open, a RST means closed, and silence usually means a firewall is dropping the packet, which nmap calls filtered. Because it never sends the final ACK, the connection is never completed, so the scan is fast and quieter than a full connect. Every feature below is this one question asked in a smarter way: is anyone listening, and who.

02Installing and keeping it current

$ sudo emerge net-analyzer/nmap # Gentoo

$ sudo apt install nmap # Debian / Ubuntu / Kali

$ sudo dnf install nmap # Fedora / RHEL

Nmap version 7.94 ( https://nmap.org ) Platform: x86_64-pc-linux-gnu

» Install from your distro, apt on Debian and Kali, emerge on Gentoo, then check the version. Keep it current: each release ships new version fingerprints and NSE scripts, so an old nmap misnames modern software and misses recent checks. The scripts land in /usr/share/nmap/scripts.

03Your first scan

$ nmap scanme.nmap.org

Starting Nmap 7.94 ( https://nmap.org ) Nmap scan report for scanme.nmap.org (45.33.32.156) Host is up (0.19s latency). Not shown: 996 closed tcp ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http

» No flags needed to begin. A bare scan checks the 1000 most common TCP ports and reports which are open. scanme.nmap.org is a host the nmap project runs for exactly this, learning safely. Everywhere else, scan only what you own or are allowed to test.

04Port states, and what each means

Nmap reports six states, and reading them correctly is half the skill.

» open: a service is listening and answered.

» closed: the host replied, but nothing is listening on that port.

» filtered: no reply; a firewall is dropping packets, and nmap cannot see what, if anything, is behind it.

» unfiltered: reachable, but nmap cannot tell open from closed; seen with ACK scans.

» open|filtered: nmap could not decide; common on UDP and the stealth scans.

» closed|filtered: nmap could not decide between those two; rare, seen with idle scans.

» filtered is the one that trips people up. It does not mean nothing is there, it means a firewall is in the way, and that is itself a finding.

05Specifying targets

$ nmap 10.0.0.1 10.0.0.5 example.com

$ nmap 10.0.0.1-50 10.0.1.0/24

$ nmap -iL hosts.txt --exclude 10.0.1.1

Nmap scan report for 10.0.0.1 Host is up (0.0010s latency). Nmap scan report for example.com (93.184.216.34) Host is up (0.12s latency). Nmap done: 52 IP addresses (2 hosts up) scanned in 3.21s

» Mix single addresses, ranges, CIDR blocks, and hostnames freely on one line. -iL reads a target list from a file, one per line, which is how you scan an inventory. --exclude keeps the gateway or a fragile host out of range.

↑ contents

06Discover live hosts

$ sudo nmap -sn 192.168.1.0/24

Nmap scan report for 192.168.1.1 Host is up (0.0021s latency). MAC Address: 9C:3D:CF:xx:xx:xx (Router vendor) Nmap scan report for 192.168.1.14 Host is up (0.045s latency). Nmap scan report for 192.168.1.37 Host is up (0.011s latency).

» -sn is a ping scan: find hosts, scan no ports. On your own LAN nmap uses ARP, which is why you also get MAC addresses and vendor names. This is your inventory. Run it again a day later and a new MAC is a new device worth asking about.

07When ping is blocked

Many hosts and firewalls drop ICMP pings, so a default discovery wrongly marks them down. Nmap can knock in other ways.

$ sudo nmap -PS22,80,443 target

$ sudo nmap -PA80 target

$ sudo nmap -PU53 target

$ sudo nmap -Pn target

Nmap scan report for 10.0.0.5 Host is up (0.023s latency). Nmap done: 1 IP address (1 host up) scanned in 0.34s

» -PS, -PA, and -PU probe with TCP SYN, TCP ACK, and UDP instead of ICMP, slipping past hosts that ignore pings. When even that fails, or you already know the host is up, -Pn skips discovery and scans anyway. Reach for -Pn when a host looks down but you believe otherwise.

08DNS during a scan

$ nmap -n 10.0.0.0/24

$ nmap -R --dns-servers 1.1.1.1 target

Nmap scan report for gw.lan (10.0.0.1) Host is up (0.0011s latency).

» By default nmap does reverse DNS on live hosts, which is slow across big ranges. -n turns it off for speed. -R forces it even on offline-looking hosts, and --dns-servers points at a resolver you choose, useful when the local one is slow or you want queries to take a particular path.

↑ contents

09Scan types overview

$ sudo nmap -sS target

$ nmap -sT target

$ sudo nmap -sU target

$ sudo nmap -sA target

PORT STATE SERVICE 22/tcp open ssh 80/tcp open http

» -sS is the workhorse but needs root. -sT completes the handshake so it needs no privileges, at the cost of speed and more logging on the target. -sU reaches services that only live on UDP. -sA finds no open ports; it tells you what a firewall filters versus allows.

10The SYN scan

The SYN scan is nmap's default when run as root. It sends a SYN, reads the reply, and never completes the handshake.

$ sudo nmap -sS --reason -p 1-1000 target

PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 64 25/tcp filtered smtp no-response

» --reason adds the evidence behind each verdict: syn-ack means open, reset means closed, no-response means filtered. It turns nmap from a black box into something you can actually learn the network from.

11The TCP connect scan

$ nmap -sT -p 1-1000 target

PORT STATE SERVICE 22/tcp open ssh 443/tcp open https

» -sT asks the operating system to make a full connection, so it needs no root. The tradeoff: the handshake completes, which is slower and lands in the target's logs. Use it when you cannot run as root, for example from a limited shell during a test.

12Scanning UDP services

UDP has no handshake, so nmap sends a packet and infers: a reply means open, an ICMP port-unreachable means closed, and silence means open|filtered. That ambiguity makes UDP scans slow.

$ sudo nmap -sU --top-ports 50 target

PORT STATE SERVICE 53/udp open domain 123/udp open|filtered ntp 161/udp closed snmp

» A full 65535-port UDP scan can run for hours, so start with the top ports. open|filtered is normal, it means no reply came. Pair with -sV to confirm what is really answering on DNS, SNMP, or NTP.

13Choosing which ports

$ nmap -p 22,80,443 target

$ nmap -p- target

$ nmap -F target

$ nmap --top-ports 100 target

PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https

» -p takes a list or range, -p- means all 65535, -F is a fast scan of the top 100, and --top-ports N scans the N most common. The default is the top 1000. Run -F first for a quick picture, then -p- on anything interesting so nothing hides on an odd port.

14FIN, NULL, and Xmas scans

These send unusual flag combinations. By the TCP spec a closed port must reply RST and an open one stays silent, so nmap reads silence as open|filtered. On some firewalls they slip past rules that only watch for SYN.

$ sudo nmap -sF target

$ sudo nmap -sN target

$ sudo nmap -sX target

PORT STATE SERVICE 22/tcp open|filtered ssh 80/tcp open|filtered http

» -sF sends a lone FIN, -sN sends no flags, -sX sets FIN, PSH, and URG, the Xmas tree. Modern Windows replies RST to everything, so these work mainly against stacks that follow the spec strictly. Treat them as situational, not a default.

↑ contents

15Service and version detection

-sV opens each port and reads what it says, then matches the banner and behaviour against nmap's probe database to name the software and version.

$ sudo nmap -sV --version-intensity 9 -p 8080 target

PORT STATE SERVICE VERSION 8080/tcp open http Apache Tomcat 9.0.46

» --version-intensity runs 0 to 9; higher tries more probes and catches stubborn services, slower and noisier. Naming the exact version is what lets you check it against known CVEs next.

16OS detection

-O measures quirks in the target's TCP/IP stack, the window size, the TTL, and the ordering of options, then matches that fingerprint to known systems.

$ sudo nmap -O --osscan-guess target

Running: Linux 5.X OS details: Linux 5.4 - 5.15 Network Distance: 2 hops

» It needs at least one open and one closed port to be confident. --osscan-guess shows nmap's closest matches when unsure. Treat the result as a strong hint, not proof; a firewall or an unusual stack can mislead it.

17The aggressive scan

$ sudo nmap -A target

PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 80/tcp open http nginx 1.18.0 Running: Linux 5.X OS details: Linux 5.4 - 5.15

» -A bundles the common deep options in one flag: version detection, OS detection, the default scripts, and traceroute. It is the fast way to learn a lot about a host, and also the loudest. Use it when stealth does not matter and you want the full picture quickly.

↑ contents

18NSE basics

NSE is nmap's built-in automation: small Lua scripts for discovery, deeper probing, vulnerability checks, brute forcing, and more. They live in /usr/share/nmap/scripts, grouped into categories like safe, default, discovery, auth, vuln, brute, and intrusive.

$ nmap --script "http-title,http-headers" -p 80,443 target

$ nmap --script-help "ssl-*"

| http-title: Welcome to nginx! | http-headers: | Server: nginx/1.18.0

» Run one script, a comma list, or a wildcard. --script-help prints what a script does before you run it. Mind the category: an intrusive script can crash the very service you are testing.

19Default scripts

$ sudo nmap -sC -sV target

PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu | ssh-hostkey: | 3072 SHA256:9c:4f:... (RSA) 80/tcp open http nginx 1.18.0 |_http-title: Welcome to nginx!

» -sC runs the default category, safe and broadly useful checks that pull banners, certificates, HTTP titles, and common misconfigurations. Paired with -sV it is the standard first deep look at a host, and -A includes it automatically.

20Vulnerability checks

$ sudo nmap -sV --script vuln target

| ssl-dh-params: | VULNERABLE: Diffie-Hellman Insufficient Group Strength | http-csrf: Couldn't find any CSRF vulnerabilities.

» The vuln category tests known issues against the versions -sV found. Add the community vulners script to map versions to CVEs at scale. Everything here is a lead to verify by hand; these scripts do produce false positives.

21Authentication and brute force

The brute category tries credential guessing against services like SSH, FTP, and databases. In authorized testing it is the standard way to prove weak or default passwords before an attacker finds them.

$ nmap --script ssh-brute --script-args userdb=users.txt,passdb=pass.txt -p 22 target

PORT STATE SERVICE 22/tcp open ssh | ssh-brute: | Accounts: | admin:password123 - Valid credentials

» Point it at wordlists with --script-args. Two cautions that matter: brute forcing can lock accounts out and will fill the target's logs, so coordinate it, and never run it without written authorization.

22Passing arguments to scripts

$ nmap --script http-enum --script-args http-enum.basepath=/app/ -p 80 target

$ nmap --script "smb-*" --script-args smbusername=guest -p 445 target

| http-enum: | /app/admin/: Possible admin folder | /app/backup.zip: Backup archive

» --script-args feeds options into scripts: paths, credentials, wordlists, timeouts. Check a script's page with --script-help to see which arguments it accepts. This is where a generic scan becomes a targeted one.

↑ contents

23Timing templates

$ sudo nmap -T4 target

Nmap done: 1 IP address (1 host up) scanned in 4.02s

» -T0 to -T5 run from paranoid to insane. -T0 and -T1 are for evading detection and are painfully slow. -T3 is the default. -T4 is a sane, fast choice on a healthy network. -T5 is fastest but drops accuracy on anything congested.

24Fine timing control

$ sudo nmap --min-rate 1000 --max-retries 2 --host-timeout 15m target

Nmap done: 256 IP addresses (12 hosts up) scanned in 18.74s

» When a template is too blunt, tune directly: --min-rate sets a packet-per-second floor, --max-retries caps resends to quiet ports, --host-timeout gives up on a host that drags. --scan-delay does the opposite, spacing packets out to stay under rate-based alarms. Push too hard on a fragile network and you get false filtered results.

↑ contents

25Detecting a firewall

$ sudo nmap -sA -p 1-1000 target

PORT STATE SERVICE 22/tcp unfiltered ssh 80/tcp unfiltered http 25/tcp filtered smtp

» The ACK scan does not find open ports, it finds the firewall. unfiltered means the ACK got through, filtered means a stateful firewall dropped it. Comparing a SYN scan with an ACK scan tells you which closed-looking ports are actually firewalled.

26Evasion techniques

$ sudo nmap -f --mtu 16 target

$ sudo nmap -D RND:5 target

$ sudo nmap --source-port 53 target

PORT STATE SERVICE 80/tcp open http 443/tcp filtered https

» -f and --mtu fragment packets to slip past simple filters. -D adds decoy sources so your real address is harder to pick out of the noise. --source-port 53 or 80 can pass rules that trust those ports. These are for testing a defense to see what it catches.

27The idle (zombie) scan

-sI is nmap's stealthiest scan. It bounces the scan off a third idle host with predictable IP IDs, so the target sees the probes coming from that zombie, not from you.

$ sudo nmap -sI zombie_host target

Idle scan using zombie 192.168.1.50 (incr IP ID) PORT STATE SERVICE 80/tcp open http

» It never sends a packet from your own address to the target, which is why it is famous. It needs a suitable idle host and is slow and finicky. Mostly it is here to understand how IP ID side channels work; it is rarely the practical choice.

↑ contents

28A recon workflow, start to finish

A real engagement is not one command, it is a sequence that narrows from the whole network down to specific services.

1. Discover: sudo nmap -sn on the range to list live hosts.

2. Sweep: a fast port scan across those hosts to see what is open.

3. Deep scan: -sV -sC -p- on the hosts that looked interesting.

4. Enumerate: targeted NSE scripts per service, web, SMB, and so on.

5. Record: -oA at every step so nothing is lost.

» Each step feeds the next. You are turning a whole /24 into these three hosts, these services, these versions, before you ever touch anything deeper.

29Fast sweep, then deep scan

The classic two-stage pattern: find open ports fast across everything, then spend time only where it matters.

$ sudo nmap -p- --min-rate 2000 -oG sweep.txt 10.10.10.5

$ ports=$(grep -oP '\d+/open' sweep.txt | cut -d/ -f1 | paste -sd,)

$ sudo nmap -sV -sC -p "$ports" 10.10.10.5

PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 80/tcp open http Apache 2.4.41 3306/tcp open mysql MySQL 5.7.38

» Stage one finds every open port quickly with a high min-rate. The middle line pulls just those port numbers out of the grepable output. Stage two runs the slow version and script scan against only those ports, which can turn an hour into minutes.

30Enumerating web servers

$ nmap --script "http-enum,http-title,http-headers,http-methods" -p 80,443 target

| http-title: Welcome to nginx! | http-methods: GET HEAD POST OPTIONS | http-enum: | /admin/: Possible admin folder | /backup/: Backup folder

» http-enum walks common paths looking for admin panels, backups, and leftover files; http-methods flags risky verbs like PUT; http-title and http-headers reveal the stack. This is usually the first move once port 80 or 443 is open.

31Enumerating SMB and services

$ sudo nmap --script "smb-os-discovery,smb-enum-shares,smb-security-mode" -p 445 target

| smb-os-discovery: | OS: Windows 10 Pro 19041 | Computer name: WORKSTATION-7 | smb-enum-shares: | \\target\backup (READ)

» SMB on 445 is a rich source on Windows networks: OS and hostname, shared folders and their permissions, and whether signing is enforced. An unauthenticated READ share, like the backup above, is a classic finding. Similar script families exist for ftp-*, ssl-*, dns-*, and snmp-*.

32Handing results to other tools

$ sudo nmap -sV -oX scan.xml target

$ searchsploit --nmap scan.xml

------------------------------------------ Exploit Title | Path ------------------------------------------ OpenSSH 8.2 Username Enum | 45939.py ------------------------------------------

» -oX writes XML that other tools read. searchsploit --nmap maps the versions nmap found to public exploit entries. In Metasploit, db_import scan.xml loads the hosts and services straight into the workspace. Nmap is the front of a pipeline, not the end of it.

↑ contents

33Output, diffing, and reporting

$ sudo nmap -sV -oA weekly 10.0.0.0/24

$ grep ' open ' weekly.gnmap

$ ndiff last-week.xml weekly.xml

22/tcp open ssh 80/tcp open http 3306/tcp open mysql

» -oA writes three files at once: .nmap to read, .xml for tools, .gnmap for grep. The grep pulls a clean list of open services. ndiff compares two XML scans and shows only what changed, a new open port, a vanished host. Scan on a schedule, diff against last time, and change on a network you own stops slipping past you.

↑ contents

Authorized use only

The tools and techniques in these guides are for defending, testing, and understanding systems you own or have explicit written permission to assess. Unauthorized access to computers, networks, accounts, or data is a criminal offense in nearly every jurisdiction, and the penalties are real.

A few of the laws that apply, by way of example:

Wherever you are, the rule is the same: get authorization in writing, stay within the agreed scope, and never touch a system that is not yours to test. If you are unsure whether something is permitted, treat it as not permitted until you have clear authorization.

This is general information, not legal advice.