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:

  1. Initial Discovery — Masscan across the target subnet for top 100 ports
  2. Detailed Scan — Nmap with -sV -sC -T4 on discovered hosts
  3. Service Enumeration — Deep-dive each service (SMB, FTP, SNMP, SMTP, etc.)
  4. Web Enumeration — WhatWeb, curl, directory brute-forcing
  5. DNS Recon — dnsrecon, dnsenum, dig for subdomain discovery
  6. Vulnerability Scanning — Nmap NSE vuln scripts, banner version cross-referencing
  7. 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.