Ethical Hacking
Nmap Scanning
If there is one tool that every pen tester knows inside out, it is Nmap. It has been the standard for network scanning since 1997, and despite the industry producing dozens of alternatives since then, nothing has meaningfully replaced it. This lesson teaches you how it actually works — not just which flags to copy and paste.
Nmap is a conversation, not just a scan
Most people think of Nmap as a tool that tells you which ports are open. That is true, but it undersells what is actually happening. Nmap works by initiating specific types of network conversations with a target system and interpreting the responses — or the absence of responses — to draw conclusions about what is running and how it is configured.
When Nmap sends a packet to a port and gets a specific response back, it knows that port is open and a service is listening. When it sends a packet and gets a different type of response, it knows the port is closed but the host is alive. When it sends a packet and gets nothing back, that could mean the port is filtered by a firewall — or that the host does not exist. The nuance in interpreting those three outcomes is where the skill actually lives.
Understanding this matters because different scan types provoke different responses, generate different amounts of network traffic, and leave different traces in logs. Choosing the right scan type for an engagement is not a technical detail — it directly affects whether the target's security team detects you before you have finished the reconnaissance phase.
The three port states Nmap reports
Before touching a single flag, it helps to understand what Nmap is actually telling you when it reports on a port. There are three possible states — and the difference between them changes how you approach the next phase of an engagement significantly.
Open
A service is actively listening on this port and accepting connections. This is what you are looking for — an open port is a potential entry point. Each one tells you there is a service running that can be probed further for vulnerabilities.
Closed
The host is reachable and responding, but nothing is listening on this port right now. Closed ports still confirm the host is alive and accessible, and a closed port today could become open tomorrow if a service is installed or started. Worth noting in the documentation.
Filtered
Nmap sent the probe but received no response — or received an ICMP unreachable message. This usually means a firewall is dropping packets to this port. The port could be open with a service behind it, or it could be closed — you cannot tell from a filtered result alone. Filtered ports often require a different scan type to investigate further.
Scan types — choosing the right approach for the situation
Nmap has several scan types that work at different layers of the TCP/IP stack and generate different levels of network noise. The choice between them is a real decision with real consequences — not a technicality.
| Flag | Scan type | Behaviour and when to use it | Noise level |
|---|---|---|---|
| -sS | SYN scan | Sends a SYN packet, waits for a response, then sends RST instead of completing the handshake. Fast, reliable, and leaves minimal traces in application logs. Requires root privileges. Default scan type on Kali. | Low |
| -sT | TCP connect | Completes the full TCP handshake. More reliable but noisier — every connection appears in the target's application logs. Used when -sS is not available, such as when running without root access. | High |
| -sU | UDP scan | Scans UDP ports — used for services like DNS (53), SNMP (161), and TFTP (69). Much slower than TCP scans because UDP does not confirm receipt. Frequently missed by teams that only run TCP scans. | Medium |
| -sV | Version detection | Probes open ports to determine the exact service and version running. Transforms a list of open ports into actionable intelligence. Run this after an initial port discovery scan to avoid wasting time on closed hosts. | Medium |
| -O | OS detection | Analyses TCP/IP stack behaviour to guess the operating system. Not always accurate, but useful for narrowing down which exploit paths are relevant. Requires root and at least one open and one closed port. | Medium |
The -sS SYN scan is the default on Kali for a reason. It is the most useful general-purpose scan — fast, reliable, and quiet enough to avoid triggering basic IDS rules. The other scan types are not replacements for -sS. They answer different questions that -sS alone cannot answer, particularly -sU for UDP services which a TCP-only scan would miss entirely.
Running your first Nmap scan against the lab target
Everything from this point runs in your lab against Metasploitable. This is active reconnaissance — packets are being sent to a live target. The testing window is open, the IP is authorised, and Metasploitable was built to be scanned and attacked. Nothing here touches anything outside your private lab network.
The scenario: Your host discovery sweep from Lesson 12 returned three live hosts. You have confirmed 192.168.56.101 as Metasploitable — your primary target. The active phase is underway and your team lead wants a complete service map of this host before the vulnerability scanning phase begins. You start with a focused SYN scan to identify open ports, then layer version detection on top.
# Step 1 — initial SYN scan to discover open ports quickly
# This is active recon — packets reach the target at 192.168.56.101
# Only run this inside your authorised lab environment
# -sS sends SYN packets without completing the handshake (stealth scan)
# requires root privileges — you already have them on Kali
# -p- scans all 65,535 ports instead of just the default top 1,000
# slower but more thorough — never assume common ports are the only ones open
# -T4 sets the timing template to aggressive — faster scan with acceptable accuracy
# scale from -T0 (paranoid/slowest) to -T5 (insane/fastest)
# T4 is the standard for lab environments; use T2 or T3 on sensitive production systems
# Replace the IP with your actual Metasploitable address from Lesson 9
nmap -sS -p- -T4 192.168.56.101
Starting Nmap 7.94 ( https://nmap.org ) Nmap scan report for 192.168.56.101 Host is up (0.00044s latency). Not shown: 65505 closed tcp ports PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 23/tcp open telnet 25/tcp open smtp 53/tcp open domain 80/tcp open http 111/tcp open rpcbind 139/tcp open netbios-ssn 445/tcp open microsoft-ds 512/tcp open exec 513/tcp open login 514/tcp open shell 1099/tcp open rmiregistry 1524/tcp open ingreslock 2049/tcp open nfs 2121/tcp open ccproxy-ftp 3306/tcp open mysql 5432/tcp open postgresql 5900/tcp open vnc 6000/tcp open X11 6667/tcp open irc 8009/tcp open ajp13 8180/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 4.21 seconds
Breaking it down:
A real production server typically has between two and five services exposed. Twenty-three is a red flag on its own — it suggests either a deliberately misconfigured system (which Metasploitable is) or a real server that has been neglected and accumulated services over years without anyone auditing what is actually needed.
Telnet transmits everything in plain text — including usernames and passwords. It was replaced by SSH precisely because anyone on the same network could capture and read telnet sessions. Seeing it open on a host in 2024 is an immediate critical finding. The service should not exist on any system that handles anything of value.
The Berkeley r-services are older than Telnet and even less secure. They were designed for trust-based authentication between Unix systems — meaning a system could be configured to allow connections from another machine without any password at all. Finding these open in a real engagement is genuinely alarming. In a lab, they are a gift for exploitation practice.
All 65,535 ports checked in just over four seconds against a local virtual machine at T4. On a real internet-facing host with network latency and possible firewall interference, the same scan could take several minutes. Adjust -T settings accordingly — a T4 scan against a cloud host from a different continent may not complete cleanly.
The port list is valuable — but it only tells you which ports are open, not what is actually running on them. The service column shows Nmap's best guess based on port number conventions, but those guesses are often wrong. Port 8180 shows as "unknown" and port 2121 is labelled as ccproxy-ftp — but neither of those labels can be trusted until version detection confirms them.
# Step 2 — version detection and OS fingerprinting on confirmed open ports
# We already know which ports are open from Step 1
# Now we find out exactly what software is running and which version
# -sV probes each open port to identify the exact service and version
# this is what turns "port 80 open" into "Apache httpd 2.2.8 (Ubuntu)"
# version information is what you cross-reference against CVE databases
# -O attempts to identify the operating system from network behaviour
# it analyses how the TCP/IP stack responds and compares to a known database
# not always 100% accurate — treat it as a strong hint, not a guarantee
# -p specifies which ports to scan — we use the ones found open in Step 1
# no need to rescan all 65,535 — only investigate the confirmed open ones
nmap -sV -O -p 21,22,23,25,53,80,139,445,3306,5432,5900,8180 192.168.56.101
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) 23/tcp open telnet Linux telnetd 25/tcp open smtp Postfix smtpd 53/tcp open domain ISC BIND 9.4.2 80/tcp open http Apache httpd 2.2.8 ((Ubuntu) DAV/2) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X 445/tcp open netbios-ssn Samba smbd 3.0.20-Debian 3306/tcp open mysql MySQL 5.0.51a-3ubuntu5 5432/tcp open postgresql PostgreSQL DB 8.3.0 - 8.3.7 5900/tcp open vnc VNC (protocol 3.3) 8180/tcp open http Apache Tomcat/Coyote JSP engine 1.1 OS details: Linux 2.6.9 - 2.6.33
Breaking it down:
This specific version is famous in security training circles for a very particular reason — it contains a deliberately inserted backdoor. vsftpd 2.3.4 was compromised during its distribution phase in 2011, and the backdoored version spawns a root shell when it receives a specific sequence of characters in the username field. It is one of the most well-known Metasploitable vulnerabilities and a staple of early exploitation exercises.
Samba 3.0.20 is vulnerable to CVE-2007-2447 — a command injection vulnerability that allows unauthenticated remote code execution. It is exploitable via a single Metasploit module and has been part of security training environments for over fifteen years. Seeing the exact version number here means you already know the exploit path before the vulnerability scanning phase begins.
Nmap's first scan labelled port 8180 as "unknown" because it did not recognise the port number. Version detection correctly identified it as Apache Tomcat — a Java application server with a web-based management interface that is notorious for default credential exposure. The manager panel at /manager/html often accepts admin:admin or tomcat:tomcat out of the box.
The OS detection returns a range rather than an exact version — that is normal. Nmap cannot determine the precise kernel version from network behaviour alone, but narrowing it to this range is enough to know the system is running an old Linux kernel from the late 2000s. That range maps directly to a specific set of local privilege escalation vulnerabilities.
Two scans. The first found what is open. The second found what is running. Together they produced enough information to plan the entire next phase of the engagement — which services to target, which known vulnerabilities apply, and in what order to approach them. This is what proper scanning looks like when it is grounded in the recon work that came before it.
Nmap scripting engine — adding intelligence to a scan
Beyond port scanning and version detection, Nmap ships with a scripting engine — the NSE — that runs small Lua scripts against discovered services to automate additional checks. There are over 600 built-in scripts covering everything from checking for default credentials on a service to detecting specific vulnerability signatures.
The most common use of NSE in a pen test is the --script=vuln flag, which runs a curated set of vulnerability detection scripts against all open ports. This sits somewhere between a pure port scan and a full vulnerability scanner — it checks for known vulnerabilities without the overhead of a tool like Nessus.
# Nmap scripting engine — running vulnerability detection scripts
# --script=vuln runs all scripts in the "vuln" category
# These scripts check for specific known vulnerabilities against each open port
# This generates more traffic than a plain scan — some scripts probe services actively
# Use only within your authorised scope and testing window
# -sV is included because scripts often need the version information to work correctly
# Without -sV, scripts that check for version-specific vulnerabilities may not run
nmap -sV --script=vuln -p 21,445,80,3306 192.168.56.101
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 | ftp-vsftpd-backdoor: | VULNERABLE: | vsFTPd version 2.3.4 backdoor | State: VULNERABLE (Exploitable) | IDs: CVE:CVE-2011-2523 | Risk factor: High | Description: vsFTPd version 2.3.4 backdoor, this was introduced | into the vsftpd-2.3.4.tar.gz archive. |_ Exploit: Trigger with a :) smiley in the username field. 445/tcp open netbios-ssn Samba smbd 3.0.20-Debian | smb-vuln-ms08-067: | VULNERABLE: | Microsoft MS08-067 vulnerability | State: VULNERABLE | IDs: CVE:CVE-2008-4250 | Risk factor: HIGH 80/tcp open http Apache httpd 2.2.8 | http-slowloris-check: | VULNERABLE: | Slowloris DOS attack | State: LIKELY VULNERABLE | Risk factor: High 3306/tcp open mysql MySQL 5.0.51a-3ubuntu5 |_mysql-empty-password: ERROR: Script execution failed
Breaking it down:
Nmap confirmed the backdoor is present and exploitable. The script even tells you how to trigger it. In a real engagement this would be an immediate critical finding — but on Metasploitable it is there by design. This is exactly the kind of finding that demonstrates the value of running NSE scripts after version detection rather than stopping at port names.
MS08-067 was the vulnerability that the Conficker worm used to spread to millions of systems in 2008. Finding it on a Samba host in a pen test today means the system has not received security patches for over fifteen years. That is a finding in its own right — the age of the vulnerability tells you as much about the security posture as the vulnerability itself.
Not every script succeeds. This one failed — possibly because MySQL on Metasploitable requires a specific connection method the script did not use. A failed script is not a negative result. It means you need to investigate that service manually rather than relying on automation. Script failure is information, not an error.
Teacher's Note: Run scans in sequence — host discovery first, then port discovery, then version detection, then NSE scripts. Each layer builds on the previous one. Jumping straight to --script=vuln against an entire subnet without knowing which hosts are alive or which ports are open wastes hours and generates unnecessary noise.
Practice questions
Scenario:
Scenario:
Scenario:
Quiz
Scenario:
Scenario:
Scenario:
Up Next · Lesson 15
Port Scanning
Going deeper into port scanning — TCP vs UDP, scanning strategies, and how to read results under real-world firewall conditions.