Network scanning and enumeration are the bedrock of every penetration test. Before you can exploit a system, you need to know what is out there, what ports are open, what services are running, and how they are configured. This guide covers the tools and techniques used by professional pentesters to map networks and extract critical information from targets.
Understanding the TCP Handshake
Every network scan is built on top of the TCP three-way handshake. A client initiates a connection by sending a SYN packet. The server responds with SYN-ACK if the port is open, or RST if it is closed. The client finalises with ACK. Different scan types manipulate this handshake at various stages to evade detection or extract information.
Scan Types Overview
- SYN Scan (-sS) — Sends a SYN packet and waits for SYN-ACK. Never completes the handshake. Fast and stealthy.
- TCP Connect Scan (-sT) — Completes the full three-way handshake. Noisy but reliable.
- FIN Scan (-sF) — Sends a FIN packet. Closed ports reply with RST; open ports ignore it.
- NULL Scan (-sN) — Sends a packet with no flags set. Behaviour mirrors FIN scan.
- ACK Scan (-sA) — Sends an ACK packet to map firewall rules, not to determine open/closed.
- UDP Scan (-sU) — Sends UDP probes. Unreliable but necessary for discovering UDP services like DNS and SNMP.
bash$ sudo nmap -sS 192.168.1.100 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:00 UTC Nmap scan report for 192.168.1.100 Host is up (0.0032s latency). Not shown: 994 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 445/tcp open microsoft-ds 3306/tcp filtered mysql 8080/tcp open http-proxy
Pro Tip: SYN scans require root privileges because they construct raw packets. Use sudo or run as root. TCP Connect scans work without root but are easily logged.
Nmap In-Depth Usage
Nmap is the Swiss Army knife of network scanning. Mastering its flags is essential for efficient reconnaissance.
Essential Nmap Flags
-sS— SYN stealth scan-sT— TCP connect scan-sU— UDP scan-sV— Service version detection-O— Operating system detection-A— Aggressive mode (enables OS detection, version detection, script scanning, and traceroute)-T4— Timing template (0=paranoid, 3=normal, 4=aggressive, 5=insane)--top-ports 1000— Scan the most common 1000 ports-p-— Scan all 65535 ports-Pn— Skip host discovery (treat all hosts as online)
bash$ nmap -sV -O -T4 --top-ports 1000 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:05 UTC Nmap scan report for 10.10.10.50 Host is up (0.0015s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 6ubuntu0.1 80/tcp open http Apache httpd 2.4.57 443/tcp open ssl/http Apache httpd 2.4.57 445/tcp open netbios-ssn Samba smbd 4.17.5-Ubuntu 3306/tcp open mysql MySQL 8.0.35-0ubuntu0.22.04.1 Device type: general purpose Running: Linux 5.X|6.X OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:linux:linux_kernel:6 OS details: Linux 5.15 - 6.2 Network Distance: 1 hop
Note: The -A flag is powerful but very noisy. Use it in later stages of a test when stealth is less important. For initial recon, prefer -sV and -sC separately.
bash$ nmap -p- -Pn -T4 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:10 UTC Nmap scan report for 10.10.10.50 Host is up (0.0020s latency). All 65535 scanned ports on 10.10.10.50 are filtered (firewall) $ nmap -sU --top-ports 50 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:12 UTC Nmap scan report for 10.10.10.50 PORT STATE SERVICE 53/udp open domain 161/udp open snmp 162/udp open snmptrap 500/udp open isakmp
NSE Scripts (Nmap Scripting Engine)
NSE scripts extend Nmap's capabilities to detect vulnerabilities, enumerate services, and brute-force credentials. They are categorised by purpose.
Script Categories
- vuln — Checks for known vulnerabilities
- safe — Non-intrusive scripts that should not crash services
- intrusive — May affect the target service
- discovery — Enumerates directories, DNS records, etc.
- brute — Password brute-forcing scripts
bash$ nmap --script vuln -sV 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:15 UTC Pre-scan script results: | smb-vuln-ms17-010: | VULNERABLE: | Remote Code Execution vulnerability in Microsoft SMBv1 servers (MS17-010) | State: VULNERABLE | IDs: CVE:CVE-2017-0143 | Risk factor: HIGH $ nmap --script safe -sV 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:17 UTC | http-enum: | /admin/: Possible admin folder | /robots.txt: Robots file | /backup/: Directory listing | /wp-content/: WordPress content directory $ nmap --script smb-enum-shares -p 445 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:20 UTC | smb-enum-shares: | ADMIN$ - Remote Admin (DISK) | C$ - Default share (DISK) | IPC$ - Remote IPC (IPC) | Documents - (DISK) READ, WRITE | Backup - (DISK) READ
Pro Tip: Use --script http-enum for quick web directory discovery, --script dns-brute for subdomain enumeration, and --script smb-enum-shares for SMB share discovery on internal networks.
bash$ nmap --script http-enum -p 80,443 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:22 UTC | http-enum: | /login.php: Possible login page | /dashboard/: Restricted area | /uploads/: Upload directory (indexable) | /api/v1/users: API endpoint | /.git/config: Git config file exposed $ nmap --script dns-brute --script-args dns-brute.domain=target.com,dns-brute.threads=10 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:25 UTC | dns-brute: | DNS Brute-force hostnames: | www.target.com - A 203.0.113.10 | mail.target.com - A 203.0.113.20 | vpn.target.com - A 203.0.113.30 | dev.target.com - A 203.0.113.40 | admin.target.com - A 203.0.113.50
Service Enumeration
Once Nmap identifies open ports, the next step is deep service enumeration. Each service has its own set of tools and techniques.
FTP Enumeration
FTP servers often permit anonymous access, a common misconfiguration that exposes sensitive files.
bash$ ftp 10.10.10.50 Connected to 10.10.10.50. 220 (vsFTPd 3.0.5) Name (10.10.10.50:root): anonymous 331 Please specify the password. Password: 230 Login successful Remote system type is UNIX. ftp> ls -la 200 PORT command successful. 150 Here comes the directory listing. drwxr-xr-x 2 1001 1001 4096 May 15 10:30 . drwxr-xr-x 2 1001 1001 4096 May 15 10:30 .. -rw-r--r-- 1 1001 1001 220 May 15 10:30 welcome.txt -rw-r--r-- 1 1001 1001 1024 May 15 10:30 backup.sql 226 Directory send OK. $ nmap --script ftp-anon -p 21 10.10.10.50 Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-15 10:32 UTC | ftp-anon: Anonymous FTP login allowed | -rw-r--r-- 1 1001 1001 220 May 15 10:30 welcome.txt |_-rw-r--r-- 1 1001 1001 1024 May 15 10:30 backup.sql
Pro Tip: Always check for anonymous FTP access. If granted, download everything — configuration files, database dumps, and user home directories often contain credentials.
SMB Enumeration
SMB (Server Message Block) is a goldmine on Windows and Linux (Samba) networks. Shares often contain sensitive data, and null sessions are still surprisingly common.
bash$ smbclient -L //10.10.10.50 -N Anonymous login successful Sharename Type Comment --------- ---- ------- ADMIN$ Disk Remote Admin C$ Disk Default share IPC$ IPC Remote IPC Documents Disk Backup Disk Data Disk Reconnecting with SMB1 for workgroup listing. do_connect: Connection to 10.10.10.50 succeeded (SMBv2) $ smbclient //10.10.10.50/Documents -N Anonymous login successful Try "help" to get a list of possible commands. smb: \> ls . D 0 Mon May 15 10:35:00 2026 .. D 0 Mon May 15 10:35:00 2026 passwords.txt A 512 Mon May 15 10:34:00 2026 network-config.txt A 256 Mon May 15 10:33:00 2026 smb: \> get passwords.txt getting file \passwords.txt of size 512 as passwords.txt (512.0 KiloBytes/sec)
bash$ enum4linux -a 10.10.10.50 Starting enum4linux v0.9.1 ( http://labs.portcullis.co.uk/application/enum4linux/ ) [+] Target OS: Windows 10 / Windows Server 2019 [+] Got OS info via SMB: Windows 10.0 Build 17763 [+] Share Enumeration: ADMIN$ - Remote Admin C$ - Default share Documents - Backup - IPC$ - Remote IPC [+] User Enumeration: Administrator (SID: S-1-5-21-xxxx) Guest (SID: S-1-5-21-xxxx) jdoe (SID: S-1-5-21-xxxx) asmith (SID: S-1-5-21-xxxx) [+] Password Policy: Minimum password length: 8 Password history: 24 Lockout threshold: 5 attempts
SNMP Enumeration
SNMP (Simple Network Management Protocol) with default community strings like public exposes detailed system information.
bash$ snmpwalk -v 2c -c public 10.10.10.50 iso.3.6.1.2.1.1.1.0 = STRING: "Linux server 5.15.0-generic #1 SMP" iso.3.6.1.2.1.1.5.0 = STRING: "MAILSERVER" iso.3.6.1.2.1.25.4.2.1.2 = STRING: "apache2" iso.3.6.1.2.1.25.4.2.1.2 = STRING: "sshd" iso.3.6.1.2.1.25.4.2.1.2 = STRING: "mysqld" iso.3.6.1.2.1.25.6.3.1.2 = STRING: "openssh-server" iso.3.6.1.2.1.25.6.3.1.2 = STRING: "apache2-bin" $ snmpwalk -v 2c -c public 10.10.10.50 1.3.6.1.2.1.25.4.2.1.2 iso.3.6.1.2.1.25.4.2.1.2.1 = STRING: "systemd" iso.3.6.1.2.1.25.4.2.1.2.2 = STRING: "sshd" iso.3.6.1.2.1.25.4.2.1.2.3 = STRING: "cron" iso.3.6.1.2.1.25.4.2.1.2.4 = STRING: "rsyslogd" iso.3.6.1.2.1.25.4.2.1.2.5 = STRING: "apache2" iso.3.6.1.2.1.25.4.2.1.2.6 = STRING: "mysqld"
Note: SNMP versions 1 and 2c send community strings in cleartext. Version 3 supports encryption but is rarely deployed. Always check public and private as default community strings.
SMTP Enumeration
SMTP servers can reveal valid usernames through the VRFY and EXPN commands, which check if a user exists without sending mail.
bash$ nc -v 10.10.10.50 25 Connection to 10.10.10.50 25 port [tcp/smtp] succeeded! 220 mail.target.com ESMTP Postfix (Ubuntu) VRFY root 252 2.0.0 root VRFY nobody 252 2.0.0 nobody VRFY fakeuser 550 5.1.1: Recipient address rejected: User unknown EXPN support 250 2.1.5 support@target.com EXPN admin 250 2.1.5 admin@target.com
Pro Tip: Use smtp-user-enum to automate SMTP user enumeration with a wordlist. Combine the results with password spraying attacks on exposed login panels.
bash$ smtp-user-enum -M VRFY -U /usr/share/wordlists/usernames.txt -t 10.10.10.50 Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum ) [+] Using VRFY mode against 10.10.10.50:25 [+] Found users at target: root nobody support admin info sales postmaster
Banner Grabbing
Banner grabbing identifies software versions by reading the welcome messages services send upon connection. This information helps select the right exploit or vulnerability check.
bash$ nc -v 10.10.10.50 22 Connection to 10.10.10.50 22 port [tcp/ssh] succeeded! SSH-2.0-OpenSSH_8.9p1 Ubuntu-6ubuntu0.1 $ nc -v 10.10.10.50 80 Connection to 10.10.10.50 80 port [tcp/http] succeeded! GET / HTTP/1.0 Host: 10.10.10.50 HTTP/1.1 200 OK Date: Thu, 15 May 2026 10:40:00 GMT Server: Apache/2.4.57 (Ubuntu) X-Powered-By: PHP/8.1.22 Set-Cookie: PHPSESSID=abc123; path=/ Content-Type: text/html; charset=UTF-8 $ curl -I http://10.10.10.50 HTTP/1.1 200 OK Date: Thu, 15 May 2026 10:41:00 GMT Server: Apache/2.4.57 (Ubuntu) X-Powered-By: PHP/8.1.22 Set-Cookie: PHPSESSID=def456; path=/ Content-Type: text/html; charset=UTF-8 $ openssl s_client -connect 10.10.10.50:443 CONNECTED(00000003) depth=0 CN = target.com verify error:num=20:unable to get local issuer certificate --- Certificate chain 0 s:CN = target.com i:C = US, O = Let's Encrypt, CN = R3 --- Server certificate subject=CN = target.com issuer=C = US, O = Let's Encrypt, CN = R3 --- No client certificate CA names sent --- SSL handshake has read 3525 bytes and written 397 bytes --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 2048 bit
Web Enumeration
Web servers are the most common service on the internet. Identifying the technology stack helps tailor further testing.
bash$ whatweb 10.10.10.50 http://10.10.10.50 [200 OK] Apache[2.4.57], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.57 (Ubuntu)], IP[10.10.10.50], JQuery[3.6.0], PHP[8.1.22], Script, Title[Home - Target Corp] $ curl -s -D- http://10.10.10.50 -o /dev/null HTTP/1.1 200 OK Date: Thu, 15 May 2026 10:45:00 GMT Server: Apache/2.4.57 (Ubuntu) X-Powered-By: PHP/8.1.22 Set-Cookie: PHPSESSID=ghi789; path=/; HttpOnly X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Content-Length: 15823 Content-Type: text/html; charset=UTF-8
Note: WhatWeb runs hundreds of fingerprinting rules against the target. For a browser-based alternative, use the Wappalyzer extension during manual review.
DNS Enumeration
DNS records reveal subdomains, mail servers, name servers, and sometimes sensitive information left in TXT records.
bash$ dig ANY target.com ; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> ANY target.com ;; ANSWER SECTION: target.com. 300 IN A 203.0.113.10 target.com. 300 IN AAAA 2001:db8::1 target.com. 300 IN MX 10 mail.target.com. target.com. 300 IN NS ns1.target.com. target.com. 300 IN NS ns2.target.com. target.com. 300 IN TXT "v=spf1 include:_spf.target.com ~all" target.com. 300 IN TXT "_globalsign-domain-verification=xxxx" $ nslookup target.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: target.com Address: 203.0.113.10 $ nslookup -type=mx target.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: target.com mail exchanger = 10 mail.target.com. $ dnsrecon -d target.com [*] Performing DNSSEC Zone Walk [*] Checking SOA for DNSSEC [*] DNSSEC not configured for target.com [*] Performing SRV Record Enumeration [*] _sip._tcp.target.com SRV 10 100 5060 sip.target.com [*] _ldap._tcp.target.com SRV 10 100 389 ldap.target.com [*] 25 Records Found $ dnsenum target.com dnsenum VERSION:1.2.3 ----- target.com ----- Host's addresses: target.com. 300 IN A 203.0.113.10 Name Servers: ns1.target.com. 300 IN A 203.0.113.100 ns2.target.com. 300 IN A 203.0.113.101 Mail (MX) Servers: mail.target.com. 300 IN A 203.0.113.20 Brute forcing subdomains: www.target.com. 300 IN A 203.0.113.10 mail.target.com. 300 IN A 203.0.113.20 vpn.target.com. 300 IN A 203.0.113.30 dev.target.com. 300 IN A 203.0.113.40 admin.target.com. 300 IN A 203.0.113.50 blog.target.com. 300 IN A 203.0.113.60 git.target.com. 300 IN A 203.0.113.70
Pro Tip: Always check TXT records for domain verification tokens, SPF configurations, and DMARC policies — these sometimes leak internal hostnames or third-party service accounts.
Masscan: Scanning at Scale
Masscan is the fastest port scanner in existence, capable of scanning the entire internet in under 5 minutes. It is ideal for large-scale reconnaissance and internal network discovery.
bash$ sudo masscan 10.10.10.0/24 -p22,80,443,445,3306,8080 --rate=10000 Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2026-05-15 11:00 UTC -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 256 hosts [6 ports/host] Discovered open port 22/tcp on 10.10.10.1 Discovered open port 80/tcp on 10.10.10.1 Discovered open port 22/tcp on 10.10.10.50 Discovered open port 80/tcp on 10.10.10.50 Discovered open port 443/tcp on 10.10.10.50 Discovered open port 445/tcp on 10.10.10.50 Discovered open port 8080/tcp on 10.10.10.25 Discovered open port 3306/tcp on 10.10.10.100 $ sudo masscan 10.10.10.0/24 -p0-65535 --rate=1000 -oL output.txt Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2026-05-15 11:05 UTC -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 256 hosts [65536 ports/host] Discovered open port 22/tcp on 10.10.10.1 Discovered open port 53/tcp on 10.10.10.1 Discovered open port 22/tcp on 10.10.10.50 Discovered open port 80/tcp on 10.10.10.50 Discovered open port 443/tcp on 10.10.10.50 Discovered open port 445/tcp on 10.10.10.50 Discovered open port 8080/tcp on 10.10.10.25 Discovered open port 1433/tcp on 10.10.10.200
Pro Tip: Masscan sends packets at raw speed — --rate=10000 sends 10,000 packets per second. On internal networks, reduce the rate to avoid triggering IDS/IPS alerts. Use -oL to output in a format Nmap can read with nmap -iL.
Putting It All Together: A Methodology
A structured approach ensures you do not miss anything. Here is a recommended workflow:
- Initial Discovery — Masscan across the target subnet for top 100 ports
- Detailed Scan — Nmap with
-sV -sC -T4on discovered hosts - Service Enumeration — Deep-dive each service (SMB, FTP, SNMP, SMTP, etc.)
- Web Enumeration — WhatWeb, curl, directory brute-forcing
- DNS Recon — dnsrecon, dnsenum, dig for subdomain discovery
- Vulnerability Scanning — Nmap NSE vuln scripts, banner version cross-referencing
- Documentation — Record every open port, service version, and finding
Remember: Enumeration is the longest phase of any penetration test. Thorough enumeration separates professional engagements from shallow ones. If you think you have enough information, enumerate one more time.
Next Steps
Mastering scanning and enumeration is the foundation for advanced exploitation and post-exploitation. Practice these techniques on FoxFoster Labs and CTF Arena, where you can apply them against deliberately vulnerable targets in a safe environment.
Deepen your knowledge with our FoxFoster Academy courses on network penetration testing, and check out our other blog posts for guides on web application security testing and OSINT and threat intelligence.