What's going on in network intelligence and why is it necessary?
Network reconnaissance methods are the first thing a penetration tester (or attacker) does when working with a target infrastructure. In MITRE ATT&CK terminology, several methods are used simultaneously:- Network Service Discovery (T1046, Discovery) - Discovering open port services
- Remote System Discovery (T1018, Discovery) - Identifying active hosts on the network
- Vulnerability Scanning (T1595.002, Reconnaissance) - Searches for vulnerabilities using active detection.
The entire intelligence process consists of three stages:
- Identifying hosts - those who are generally active on the network.
- Port Scanning - What Doors Are Open?
- Fingerprint identification - what is behind it, what version, what operating system
Discovering hosts on the network: ping scanning, ARP and other methods.
Before performing a port scan, it's important to understand which hosts are typically responsible. Don't run a scan of the entire /24 subnet on all ports 65535 without prior reconnaissance—it'll waste your time.ICMP ping scan
The easiest way is to send an ICMP echo reply request to each address in the specified range:Head:
nmap -sn 192.168.1.0/24 -oG ping_sweep.gnmap
The -sn flag tells nmap to "Discover hosts only, don't touch ports." By default, Nmap sends not only ICMP echo but also TCP SYN to port 443, TCP ACK to port 80, and ICMP vent timestamp request—this combination increases the chances of host discovery, even if one of the protocols is blocked.
Problem: Many hosts aren't responding to ICMP requests. Corporate firewalls often block pings. If a network ping test shows 5 hosts out of the expected 50, this doesn't mean the network is empty. Quite the opposite.
ARP scans on the local network
If you are in the same L2-segment as the goals (typical situation on the internal pentest), ARP-queries work most reliable:Bash:
nmap -sn -PR 192.168.1.0/24
Flag -PR switches nmap to ARP queries. Why is it more reliable? ARP is a channel-level protocol, without it, network connectivity is impossible. It is impossible to block the ARP in the locale without loss of communication. Every living host is obliged to answer - he has nowhere to go.
Caste samples for filtering bypass
When ICMP is blocked and you are not in the local segment, you help TCP samples for specific ports. From the official nmap documentation: several types of samples can be combined to detect hosts:Bash:
# TCP SYN на популярные порты + ICMP
nmap -sn -PS22,80,443,3389 -PE 10.0.0.0/24
-PS22,80,443,3389 sends TCP SYN to these ports. If the host answers SYN-ACK or RST, it is alive. -PE adds ICMP echo in case TCP ports are closed, but ICMP is allowed.
Remove the list of live hosts for the next stage:
Bash:
grep "Up" ping_sweep.gnmap | awk '{print $2}' > live_hosts.txt
Port Scanning Techniques: What Happens at Packets Level
Definition of open ports is the core of network reconnaissance. Nmap supports more than ten scanning techniques, but in practice 90% of the tasks are solved by three: SYN, Connect and UDP. The rest are for specific scenarios: firewall analysis or IDS bypass.Stealth Scanning SYN (-sS)
SYN scan is a default and most popular nmap technique. It is its tool that uses when running from root without additional flags:Bash:
sudo nmap -sS -p- 192.168.1.100 -oA syn_scan
What is happening on the network:
- Nmap sends TCP-package with SYN flag to the target port
- If the port is open, the target is SYN-ACK. Nmap immediately sends RST, breaking the connection
- If the port is closed - the target responds to RST
- If there is no answer or comes ICMP unreachable - the port is marked as filtered
Flag -p- critically important - it scans all 65535 ports. Without it, nmap only checks the top 1000. In my practice, forgotten services are regularly found on non-standard ports: RDP on 33389, web interfaces at 8443, 9090, databases on 13306. You miss the port, you'll miss the attack vector.
TCP Connect Scanning (-sT)
Connect-Scan uses a system call connect() for installation of a full TCP connection:Bash:
nmap -sT -p- 192.168.1.100 -oA connect_scan
UDP-scanning (-sU)
UDP scanning - headache for beginner pentesters. But it cannot be ignored: DNS (53), SNMP (161/162), DHCP (67/68) - critical services that work on UDP. As stated in the report of nmap: “exploitable UDP services are quite and cross-dispared don’t ignore the auditorium”.Bash:
sudo nmap -sU --top-ports 100 192.168.1.100 -oA udp_scan
Why UDP scan is so slow and capricious:
- UDP doesn't have a Hyundai. Sent the package - and you are waiting
- If the port is closed, the target meets ICMP Port Unreachable
- If the port is open - usually silence (no answer at all)
- Nmap marks the absence of an answer as open|filtered- the port can be both open and filtered firewall
The practice tip: combine UDP and TCP in one start:
Bash:
sudo nmap -sS -sU --top-ports 200 -iL live_hosts.txt -oA combined_scan
ACK scan for firewall analysis (-sA)
ACK scan does not look for open ports - it defines firewall rules:Bash:
sudo nmap -sA -p 80,443,8080 192.168.1.1
Nmap sends packages only with the ACK flag. This is not the beginning of the connection, so:
- If RST comes - the port is not filtered (the package went through the firewall)
- If there is no answer or comes ICMP unreachable - the port is filtered
Masscan - fast port scanning on large networks
When you need to scan the subnet /16 (65536 addresses), nmap will work hours. Masscan solves the problem by order faster - in minutes when scanning a limited set of ports or a high rate (100K +), although a complete scan of all 65535 ports at /16 at a moderate rate will take days. According to the author - Robert Graham - masscan is able to send up to 10 million packets per second on a 10GbE adapter.But there is a fundamental difference: masscan is a “radar”, nmap – “binocular with a thermal imager”. Masscan quickly finds where open ports are sticking out. Nmap examines every found in detail.
Basic Start with Safe Rate
Bash:
sudo masscan -p1-65535 10.0.0.0/16 --rate=5000 \
-oG masscan_results.gnmap
Analysis of flags:
- -p1-65535- all TCP ports. Masscan does not know any "top-1000"
- --rate=5000- 5000 packs per second. For the corporate LAN - acceptable. For products with sensitive equipment reduce to 1000
- -oG- grepable-format, convenient for parsing and transferring in nmap
Transferring MassCAN results to NMAP
Masscan is a rough tool that produces false positives (instant sending and receiving of packets, unexpected responses to each). Always verify the results:Bash:
# Extract unique IPs from Masscan results
grep "Host:" Masscan_results.gnmap \
| awk '{print $2}' | sort -u > Masscan_hosts.txt
# Deep check of hosts found by nmap
# This uses -p- to fully check all ports,
# not found by Masscan (which may produce false negatives).
# To save time, you can extract ports from the mass scan and pass them via -p. This two-step scheme—masscan to determine coverage, nmap to determine depth—is the standard method
for
port scanning on large infrastructures . I personally don't use any
other packages for large networks.
Fingerprinting and OS detection services using nmap
Finding an open port is half the battle. We need to know what's behind it. Scanning services and versions is the step where the list of ports turns into a list of potential attack vectors.Version detection (-sV)
Bash:
sudo nmap -sV --version-intensity 7 -p 22,80,443,3306,8080 192.168.1.100
How it works -sV: nmap connects to an open port and sends a sample (probes) from the underlying nmap-service-probes . The responses are compared against known patterns. The --version-intensity parameter controls the number of samples:
- 0 - minimum number of samples, maximum speed
- 9 (default) - all samples, maximum accuracy
Capturing a banner with netcat
When nmap shows a port as tcpwrapped (the service accepted the connection but didn't respond to requests), I check it myself:Bash:
# HTTP banner
echo -e "HEAD / HTTP/1.0 \r \n \r \n " | nc -w 5 192.168.1.100 8080
# SSH banner - often gives the version right away on connection
nc -w 5 192.168.1.100 22
# SMTP banner
nc -w 5 192.168.1.100 25
SSH usually immediately returns a string like SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6. One line - and you know: OpenSH 8.9, Ubuntu. You can search CVE for this version. It's the same as sending two bytes.
OS fingerprint identification (-O)
Bash:
sudo nmap -O --osscan-guess 192.168.1.100
Nmap analyzes the behavior of the TCP/IP target stack: TTL values, TCP Window Size, TCP Options, ICMP responses, fragmentation. Each OS implements a stack in its own way - nmap compares the responses with the nmap-os-db base.
The --osscan-guess flag causes nmap to give the most likely OS even with low confidence. This is useful when the firewall distorts some of the responses.
For reliable fingerprinting, both open and closed ports are used - nmap uses the difference in responses to compare with the base value.
NSE Scripts: Scanning for Vulnerabilities with nmap
Nmap Scripting Engine turns a port scanner into a vulnerability scanning tool (T1595.002, Reconnaissance):Bash:
# General scan for other vulnerabilities
nmap -sV --script vuln -p 445 192.168.1.0/24
# Check for EternalBlue (MS17-010)
nmap -p 445 --script smb-vuln-ms17-010 192.168.1.0/24
# Check for MS12-020 (CVE-2012-0002) - RCE in RDP
nmap -p 3389 --script rdp-vuln-ms12-020 192.168.1.100
# Audit SSL/TLS configuration
nmap -p 443 --script ssl-enum-ciphers 192.168.1.100
CVE-2012-0002 (CVSS v2: 9.3, HIGH - the highest of three severity categories in CVSS v2: Low - 0-3.9, Medium - 4.0-6.9, High - 7.0-10.0; CVSS v3) is a vulnerability in the implementation of the Remote Desktop Protocol (RDP) in Microsoft Windows XP SP2/SP3, Windows Server 2003, Windows Vista SP2, and Windows Server 2008. Improper handling of RDP packets in memory allows a remote attacker to execute arbitrary code via specially crafted RDP packets that provide access to an uninitialized or deleted object. Classification: CWE-94 (official NVD classification). The CVE description mentions access to an unallocated or deleted object in memory, which some researchers believe is closer to CWE-416 (Use-After-Free) / CWE-824 (Access to an Unallocated Pointer), but NVD officially classifies this vulnerability as CWE-94.
At the time of writing, nmap does not include an official NSE script for BlueKeep ( CVE-2019-0708 ). Community-provided scripts are available (e.g., from Ekultk on GitHub). Alternatives include rdpscan (Robert Graham) or the Metasploit module auxiliary/scanner/rdp/cve_2019_0708_bluekeep. CVE-2019-0708 is a Remote Code Execution Vulnerability in Remote Desktop Services with CVSS 9.8 (CRITICAL). Vector: CVSS:3.1/AV:N/A:L/L/PR:N/UI:C/H/H:H/H:H/A:H:H/H:H:H:N/A:11:C, low complexity, does not require any privileges or user action. Classification: CWE-416 (Use-After-Free). The vulnerability affects Windows XP, Windows Server 2003, Windows 7, Windows Server 2008, and Windows Server 2008 R2. In addition to Microsoft desktop and server operating systems, it affects a number of industrial and medical systems (for example, Siemens Axiom Multix M) using embedded versions of Windows with RDP. Microsoft even released unscheduled patches for XP and Server 2003, ending support, which in itself indicates the severity of the vulnerability.
Package fragmentation
Bash:
sudo nmap -sS -f --mtu 16 -p 80 443 192.168.1.100
The -f flag splits IP packets into fragments. --mtu 16 specifies the fragment size (must be a multiple of 8). Some stateless firewalls cannot reassemble fragmented packets and pass them through without analysis. Modern stateful firewalls recognize this, but in legacy infrastructures (and they still exist), it works.
Scanning using decoys
Bash:
sudo nmap -sS -D RND:10 -p- 192.168.1.100
-D RND:10 Adds 10 decoy IP addresses to your scan. The target's logs will show 11 "scanners" instead of one. However, random decoy addresses (RND) are often ineffective—an IDS may filter them out due to a lack of traffic or belonging to irrelevant ranges. For real effectiveness, it's better to specify the IP addresses of active hosts in the same subnet: -D 10.0.0.5,10.0.0.12,10.0.0.33,ME.
Randomizing port order
Bash:
sudo nmap -sS --randomize-hosts -p- -iL live_hosts.txt
By default, nmap scans hosts in a specific order. The --randomize-hosts option changes the order. nmap randomizes ports by default (you can control this with the --top-ports or -r options for a sequential search).
The Complete Network Intelligence Cycle: A Step-by-Step Scenario
Here's how I create a port scanning system for pentesting in a real project. I did it once, I did it twice, I did it three times.Step 1: Train your workforce members.
Баш:
ENGAGEMENT="pentest_$(date +%Y%m%d)"
mkdir -p /tmp/${ENGAGEMENT}/{scans,pcaps,loot}
Step 2: Get your insurance policy quickly through Masscan.
Bash:
sudo Masscan -p1-65535 10.10.0.0/16 --rate=3000 \
-oG /tmp/${ENGAGEMENT}/scans/masscan_full.gnmap
With rate=3000 and scanning the entire port range in /16, the scan will take several days (65536 hosts × 65535 ports / 3000 packets / se ≈ 16+ days). For faster coverage, limit the set of ports (-p 1-1000) or increase the rate. This will give you a rough map of open ports.
Step 3: Removing Active Hosts
Bash:
grep "Host:" /tmp/${ENGAGEMENT}/scans/masscan_full.gnmap \
| awk '{print $2}' | sort -u \
> /tmp/${ENGAGEMENT}/scans/live_hosts.txt
echo "Hosts found: $(wc -l < /tmp/${ENGAGEMENT}/scans/live_hosts.txt)"
Step 4: Discover the host for the dropped connection (ARP + TCP)
Bash:
sudo nmap -sn -PR -PS22,80,443,3389 10.10.0.0/16 \
-oG /tmp/${ENGAGEMENT}/scans/nmap_discovery.gnmap
# Merge with Masscan results
grep "Up" /tmp/${ENGAGEMENT}/scans/nmap_discovery.gnmap \
| awk '{print $2}' >> /tmp/${ENGAGEMENT}/scans/live_hosts.txt
sort -u -o /tmp/${ENGAGEMENT}/scans/live_hosts.txt \
/tmp/${ENGAGEMENT}/scans/live_hosts.txt
Step 5: Deep Network Scan with Nmap
Bash:
sudo nmap -sS -sV -sC -O \
-p- \
-iL /tmp/${ENGAGEMENT}/scans/live_hosts.txt \
-oA /tmp/${ENGAGEMENT}/scans/full_scan \
--max-retries 2 \
--host-timeout 30m \
-T4
Analysis: -sS (SYN scan) + -sV (version detection) + -sC (default scripts) + -O (OS detection) + -p- (all ports) + -T4 (aggressive timing for LAN).
Step 6: Targeted vulnerability scanning
Bash:
# SMB vulnerabilities on all hosts with port 445
sudo nmap -p 445 --script smb-vuln-ms17-010,smb-vuln-ms08-067 \
-iL /tmp/${ENGAGEMENT}/scans/live_hosts.txt \
-oA /tmp/${ENGAGEMENT}/scans/smb_vulns
# SSL/TLS audit for all HTTPS
sudo nmap -p 443,8443 --script ssl-enum-ciphers \
-iL /tmp/${ENGAGEMENT}/scans/live_hosts.txt \
-oA /tmp/${ENGAGEMENT}/scans/ssl_audit
Step 7: Manually check for non-standard ports.
Bash:
# Port 9090 was shown by tcpwrapped - we check it manually
echo -e "GET / HTTP/1.0\r\n\r\n" | nc -w 5 10.10.5.42 9090
# We record traffic during manual observations
sudo tcpdump -i eth0 -w /tmp/${ENGAGEMENT}/pcaps/manual.pcap \
host 10.10.5.42 &
Step 8: Prioritize UDP Scan Targets
Bash:
sudo nmap -sU --top-ports 50 \
-iL /tmp/${ENGAGEMENT}/scans/live_hosts.txt \
-oA /tmp/${ENGAGEMENT}/scans/udp_scan \
--max-retries 1
UDP scanning is performed last and covers only the 50 most popular ports - otherwise latency will increase dramatically on large networks.
Common mistakes beginners make
Scan only the 1000 most popular ports. Without the -p- parameter, nmap checks the 1000 most popular ports. Services on ports 8888, 31337, or 500000 will be skipped. I found RDP on port 33389, Jenkins on port 8888, and an unprotected REST API on port 50080—all outside the top 1000. For those at risk, this means that without the -p- parameter, you'll miss a third of the attack surface.Trust Masscan's results without further verification. Masscan uses asynchronous delivery—it doesn't wait for a response to every message. False positives are normal. Always verify with nmap.
Launch with -T5 on the production network. Aggressive timing of the serial flow packet launch, capable of disabling network equipment. For pharmaceutical production, the maximum is -T3, for more sensitive targets, -T2. Once you've made this mistake, remember it forever.
Ignore UDP. DNS, SNMP, TFTP, NTP—all over UDP. SNMP with the public string parameter is a common method in internal penetration tests, providing access to network equipment configuration.
Scan without logging results. The -oA flag saves the output in three formats (nmap, xml, gnmapa). Without this second confirmation, the attack will be considered lost.
Last edited: