Worked Examples: Complete Scanning Scenarios and Command Deconstruction

Enterprise Network Baseline: Comprehensive Discovery Through Reporting

Scenario: 10.0.0.0/8 internal corporate network, 12,000 estimated hosts, requiring full asset inventory for CMDB synchronization and vulnerability management platform ingestion.

Selected Command:

sudo nmap -Pn -sS -sV -sC -O --version-intensity 5 \
  -p- --max-retries 2 --max-rtt-timeout 300ms --initial-rtt-timeout 150ms \
  --min-hostgroup 256 --max-hostgroup 1024 --min-parallelism 50 \
  --defeat-rst-ratelimit \
  --script "banner,(http* or ssl*) and not brute and not dos" \
  --script-args "http.max-cache-size=1000000,http.useragent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'" \
  -oA enterprise-baseline-$(date +%Y%m%d) \
  --stats-every 60s \
  10.0.0.0/8

Flag Deconstruction:

| Flag | Rationale | Alternative Rejected | |------|-----------|----------------------| | -Pn | Skip host discovery; ICMP blocked by host firewalls | -sn would miss alive hosts; -PE fails on Windows default firewall | | -sS | SYN stealth; no full TCP handshake minimizes logging | -sT required for non-root but creates completed connections visible in application logs | | -sV / --version-intensity 5 | Service fingerprinting at moderate intensity; 0-9 scale, 5 balances accuracy vs. time | Intensity 9 adds ~400% time for marginal gains on obscure services | | -sC | Default safe scripts; catches obvious misconfigurations | Omitting misses SSL certificate issues, SMB signing status | | -O | OS fingerprinting for CMDB enrichment | -A includes traceroute that triggers IDS in sensitive segments | | -p- | All 65,535 ports; compliance requires no "top ports" shortcut | --top-ports 1000 misses non-standard services, common in enterprise | | --max-retries 2 | Reduces time on filtered ports from default 10 | Lower (1) causes false negatives on congested links | | --min-hostgroup 256 | Parallel host processing; scales with available bandwidth | Default 4-1024 auto; manual floor prevents underutilization on fast networks | | --defeat-rst-ratelimit | Critical for Linux targets that rate-limit RST responses | Without this, scan time increases 10x on Linux-heavy environments |

Expected Output Characteristics:

Nmap scan report for 10.0.15.87
Host is up (0.0032s latency).
Not shown: 65531 filtered ports
PORT      STATE SERVICE       VERSION
22/tcp    open  ssh           OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99 (RSA)
|_  256 11:22:33:44:55:66:77:88:99:00:aa:bb:cc:dd:ee:ff (ECDSA)
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DESKTOP-ABC123
|_ssl-date: 2024-01-15T09:23:17+00:00; -2s from scanner time.
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
49668/tcp open  msrpc         Microsoft Windows RPC
MAC Address: 00:50:56:AA:BB:CC (VMware)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|phone
Running: Microsoft Windows 10|2019
OS CPE: cpe:/o:microsoft:windows_10 cpe:/o:microsoft:windows_server_2019
OS details: Microsoft Windows 10 1903 - 2004 or Windows Server 2019
Network Distance: 1 hop

OS and Service detection performed.
Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 65536 IP addresses (2847 hosts up) scanned in 8472.34 seconds

Time Estimate: ~2.5 hours for 2,847 responsive hosts; 8.5 hours total wall-clock including unresponsive space.

Limitations: OS detection unreliable without at least one open and one closed port—verify with -sU on select targets or supplement with p0f passive analysis. Filtered port ambiguity requires follow-up with -sV --version-all on critical assets.

Cloud Infrastructure Assessment: NAT, Security Groups, and API-Sourced Targets

Scenario: AWS multi-VPC environment with 200+ EC2 instances, auto-scaling groups, and Lambda functions with VPC endpoints. Need to validate security group effectiveness and identify exposed management interfaces.

Dynamic Target Generation:

#!/bin/bash
# Generate live target list from AWS APIs, filtering by running state and network interface attachment

aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[*].Instances[*].{ID:InstanceId,IP:PrivateIpAddress,PubIP:PublicIpAddress,VPC:VpcId,SG:SecurityGroups[*].GroupId}' \
  --output json > /tmp/aws-inventory.json

# Extract scoped targets: public IPs for external assessment, private for internal pivot
jq -r '.[][] | select(.PubIP != null) | .PubIP' /tmp/aws-inventory.json > /tmp/targets-public.txt
jq -r '.[][] | select(.PubIP == null) | .IP' /tmp/aws-inventory.json > /tmp/targets-private.txt

Selected Command (External Perspective):

sudo nmap -Pn -sS -sV --version-light \
  -p 22,80,443,3389,5432,3306,6379,27017,9200,8080,8443,9443,5000 \
  --source-port 53 \
  --data-length 24 \
  -iL /tmp/targets-public.txt \
  --max-rate 500 \
  --max-retries 1 \
  --script "http-title,ssl-cert,ssh-hostkey,mongodb-info,redis-info" \
  -oX /tmp/aws-external-$(date +%Y%m%d).xml \
  --script-args "http.max-redirects=2,http.pipeline=1" \
  2>&1 | tee /tmp/nmap-aws-log.txt

Cloud-Specific Complications:

| Challenge | Mitigation in Command | Verification Required | |-----------|----------------------|----------------------| | AWS Rate Limiting | --max-rate 500 caps at 500 packets/second; adjust per VPC flow log analysis | Monitor ThrottledRequests in CloudTrail; burst to 1000 only with EC2 API rate limit increase ticket | | NAT Gateway Port Allocation | --source-port 53 mimics DNS responses, reducing NAT table exhaustion | Verify ErrorPortAllocation CloudWatch metric remains zero | | Security Group Logging Gaps | --data-length 24 avoids empty-packet signatures that trigger VPC Flow Log REJECT noise without actionable data | Correlate with VPC Flow Logs: aws logs filter-log-events --log-group-name /aws/vpc/flowlogs | | Azure NSG Logging | For hybrid environments, prepend --randomize-hosts to distribute across subnets, reducing NSG log burst pricing | Azure Monitor NetworkSecurityGroupEvent table query for denied flow trends | | GCP VPC Flow Log Correlation | Use --max-hostgroup 64 to prevent flow log aggregation from obscuring per-target patterns | Export to BigQuery: SELECT src_ip, dest_port, COUNT(*) FROM flow_logs WHERE reporter='SRC' GROUP BY 1,2 |

Expected Output Characteristics:

Nmap scan report for ec2-52-XX-XX-XX.compute-1.amazonaws.com (52.XX.XX.XX)
Host is up (0.018s latency).

PORT     STATE    SERVICE    VERSION
22/tcp   filtered ssh
80/tcp   open     http       nginx 1.18.0 (Ubuntu)
| http-title: Site doesn't have a title (text/html).
443/tcp  open     ssl/http   nginx 1.18.0
| ssl-cert: Subject: commonName=*.example.com
| Subject Alternative Name: DNS:*.example.com, DNS:example.com
| Not valid before: 2023-08-15T00:00:00
|_Not valid after:  2024-09-14T23:59:59
3389/tcp filtered ms-wbt-server
5432/tcp open     postgresql PostgreSQL 12.8
|_ssl-date: TLS randomness does not represent time

Critical Verification: Filtered port 22 with open 5432 indicates security group inconsistency—aws ec2 describe-security-groups --group-ids sg-XXXX to validate intended rules vs. implementation drift.

Red Team Engagement: Staged Evasion with Timing, Decoys, and Protocol Obfuscation

LEGAL BOUNDARY NOTICE: All commands require explicit, documented authorization with defined scope, time boundaries, and rules of engagement. Unauthorized use violates Computer Fraud and Abuse Act (US), Computer Misuse Act (UK), and equivalent jurisdictions. This section assumes valid, signed engagement letter with incident response contact procedures.

Staged Approach:

Stage 1: Passive Reconnaissance (No Nmap)

# OSINT-driven target list only; zero direct contact
theHarvester -d targetcorp.com -b all -f /tmp/th-recon-passive

Stage 2: Slow Discovery with Decoys

sudo nmap -sS -Pn -p 22,80,443,445,3389 \
  -T2 \
  --scan-delay 5s --max-retries 1 \
  -D RND:10,ME \
  --source-port 443 \
  --data-string "GET / HTTP/1.0\r\n\r\n" \
  --spoof-mac Cisco \
  --badsum \
  -f \
  --mtu 24 \
  -oN /tmp/stage2-discovery.txt \
  203.0.113.0/24

| Evasion Technique | Flag | Detection Evasion Mechanism | |-------------------|------|----------------------------| | Timing obfuscation | -T2, --scan-delay 5s | Below most threshold-based IDS; 5s exceeds Snort scan.rules default 60s/30ports | | Decoy traffic | -D RND:10,ME | 10 random decoy IPs distribute logging; ME places real scan among decoys | | Source port trust abuse | --source-port 443 | Exploits firewall rules allowing return traffic from established HTTPS sessions | | Protocol mimicry | --data-string | Initial TCP payload resembles HTTP request, not SYN-only probe | | Checksum invalidation | --badsum | Bypasses simple stateless filters that verify checksums; valid stacks drop, some IPS pass | | Fragmentation | -f, --mtu 24 | 8-byte fragments evade pattern-matching on signature-based IDS; reassembly required | | MAC spoofing | --spoof-mac Cisco | ARP-level obfuscation on local segment; useless routed but confuses layer-2 monitoring |

Stage 3: Protocol-Specific Obfuscation for C2 Discovery

sudo nmap -sS -Pn -p 4444,5555,6666,7777,8888,9999,31337 \
  -T1 \
  --scan-delay 15s \
  --randomize-hosts \
  -D RND:5,ME \
  --source-port 53 \
  --ip-options "L 10.0.0.1" \
  -oN /tmp/stage3-c2-probe.txt \
  --script "ssl-cert,banner" \
  203.0.113.0/24

Decision Tree: Why Not Alternatives

  • Rejected -sF (FIN), -sN (NULL), -sX (Xmas): Modern stateful firewalls and endpoint protection correctly handle these; only effective against legacy stateless ACLs
  • Rejected -sI (idle scan): Requires predictable IPID sequence, increasingly rare; high failure rate, long execution time
  • Selected -sS with timing over -sA (ACK): ACK scan useful for mapping firewall rules but provides no service information; combined approach adds detection surface

Explicit Limitations: Decoys require real routable IPs or they trigger ARP storms; -D RND uses random addresses that may be blackholed. --badsum packets dropped by any RFC-compliant stack—only useful against specific IPS configurations. Verify decoy effectiveness with tcpdump 'host [decoy-ip]' on sensor placement.

Incident Response Forensics: Rapid Threat Infrastructure Identification

Scenario: SOC alert for suspected Cobalt Strike beaconing. Need rapid infrastructure mapping of C2 indicators.

Command Sequence:

# Phase 1: Single-host deep inspection (2 minutes)
sudo nmap -Pn -sS -sV --version-intensity 9 -A \
  -p 1-65535 \
  --script "malware*,backdoor*,vulners" \
  --script-args "vulners.cvsslimit=7.0" \
  -oX /tmp/ir-deep-192.168.1.100.xml \
  192.168.1.100

# Phase 2: Lateral movement pattern search (5 minutes per /24)
sudo nmap -Pn -sS -p 445,135,139,5985,5986,47001 \
  --script "smb-enum-shares,smb-enum-sessions,smb-security-mode" \
  --script-args "smbuser=DOMAIN\\analyst,smbpass=[REDACTED]" \
  -oG /tmp/ir-lateral.gnmap \
  192.168.1.0/24

C2 Discovery Pattern Signatures:

| Pattern | Nmap Detection Method | Verification Command | |---------|----------------------|----------------------| | Cobalt Strike default certificate | ssl-cert script CN=, O=, OU= patterns | openssl s_client -connect [IP]:443 </dev/null 2>/dev/null \| openssl x509 -text -noout | | Metasploit RC4 payload | http-header cookie entropy analysis | Python zscoring on Set-Cookie values across multiple probes | | Empire/Invoke-Obfuscation | Unusual User-Agent in http-title response | Manual curl -A [agent] -v [target] | | DNS tunneling precursor | --script dns-* on discovered hosts with port 53 open | dig @[IP] version.bind chaos txt for BIND version |

Expected Output (Cobalt Strike Default Cert):

443/tcp open  ssl/https
| ssl-cert: Subject: commonName=192.168.1.100/organizationName=./stateOrProvinceName=./countryName=--
| Issuer: commonName=192.168.1.100/organizationName=./stateOrProvinceName=./countryName=--
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-01-01T00:00:00
|_Not valid after:  2025-01-01T00:00:00
|_ssl-date: TLS randomness does not represent time

Critical IR Note: Default Cobalt Strike certificate self-signed with -- country code and ./ organization. Not definitive (configurable), but high-confidence indicator requiring immediate host isolation per playbook.

DevSecOps Pipeline: Automated Vulnerability Scanning

GitLab CI Integration:

# .gitlab-ci.yml
stages:
  - security-scan

variables:
  NMAP_TARGET: "${CI_ENVIRONMENT_URL:-staging.internal}"
  NMAP_SEVERITY_THRESHOLD: "7.0"
  NMAP_FAIL_ON_CVSS: "true"

nmap-vulnerability-scan:
  stage: security-scan
  image: instrumentisto/nmap:latest
  script:
    - |
      nmap -Pn -sV --version-all \
        -p $(cat config/ports.txt | tr '\n' ',') \
        --script "vulners,smb-vuln-ms17-010,ssl-enum-ciphers,http-sql-injection" \
        --script-args "vulners.cvsslimit=${NMAP_SEVERITY_THRESHOLD}" \
        -oX /tmp/nmap-results.xml \
        --stats-every 30s \
        ${NMAP_TARGET}
    - |
      # Convert to SARIF for GitLab security dashboard ingestion
      python3 /usr/local/bin/nmap-to-sarif.py \
        /tmp/nmap-results.xml \
        /tmp/nmap-results.sarif
    - |
      # Pass/fail criteria: zero CVSS >= threshold
      CRITICAL_COUNT=$(grep -o 'cvssScore="[7-9]\.[0-9]"' /tmp/nmap-results.xml | wc -l)
      if [ "${NMAP_FAIL_ON_CVSS}" = "true" ] && [ "${CRITICAL_COUNT}" -gt 0 ]; then
        echo "FAIL: ${CRITICAL_COUNT} vulnerabilities at or above CVSS ${NMAP_SEVERITY_THRESHOLD}"
        exit 1
      fi
  artifacts:
    reports:
      sast: /tmp/nmap-results.sarif
    paths:
      - /tmp/nmap-results.xml
      - /tmp/nmap-results.sarif
    expire_in: 30 days
    when: always
  allow_failure: false
  only:
    - merge_requests
    - schedules

GitHub Actions Equivalent:

# .github/workflows/nmap-scan.yml
name: Nmap Security Scan
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  schedule:
    - cron: '0 2 * * 1'  # Weekly Monday 2AM

jobs:
  nmap:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Run Nmap vulnerability scan
        uses: hackerschoice/nmap-action@v1
        with:
          target: ${{ vars.SCAN_TARGET || 'localhost' }}
          args: '-Pn -sV --script vulners --script-args vulners.cvsslimit=7.0 -oX nmap-results.xml'
          
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: nmap-results
          path: nmap-results.xml
          
      - name: Parse and enforce threshold
        run: |
          CRITICAL=$(grep -o 'cvssScore="[7-9]\.[0-9]"' nmap-results.xml | wc -l)
          echo "critical_count=${CRITICAL}" >> $GITHUB_ENV
          if [ "${CRITICAL}" -gt 0 ]; then
            echo "::error::${CRITICAL} critical vulnerabilities detected"
            exit 1
          fi

Compliance Validation: PCI DSS and CIS Benchmark Mapping

| Requirement | Nmap Verification Technique | Command Snippet | |-------------|---------------------------|---------------| | PCI DSS 2.2.2: Enable only necessary services | Full port scan with service identification; compare against authorized service registry | nmap -Pn -sS -sV -p- --open -oG - \| awk '/Host:/{ip=$2}/Ports:/{print ip, $0}' \| diff - authorized-services.txt | | PCI DSS 4.1: Use strong cryptography | ssl-enum-ciphers for TLS 1.0/1.1 detection; certificate validation | --script ssl-enum-ciphers --script-args min-tls-version=1.2 | | PCI DSS 4.2.1: Strong encryption for transmission | ssh-audit equivalent via ssh2-enum-algos | --script ssh2-enum-algos then grep for 3des, rc4, diffie-hellman-group1-sha1 | | CIS 3.1: Ensure packet redirect sending is disabled | Not directly scannable; use ip-forwarding script as proxy indicator | --script ip-forwarding combined with traceroute anomaly detection | | CIS 3.6: Configure iptables/Windows Firewall | --script firewall-bypass negative confirmation; absence of response != security | nmap -Pn -sA -p 445 --reason to detect ACK-filtering presence |

PCI DSS 4.1 Validation Command:

sudo nmap -Pn -sS -p 443,8443,9443 \
  --script "ssl-enum-ciphers,ssl-cert,ssl-heartbleed" \
  --script-args "ssl-enum-ciphers.showall" \
  -oX /tmp/pci-ssl-validation.xml \
  target.payment-gateway.example.com

Pass/Fail Criteria in Output:

443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.3: 
|     ciphers: 
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|     cipher preference: client
|_  least strength: A

FAIL Condition: Any grade below B, or presence of TLSv1.0, TLSv1.1, SSLv3, or cipher names containing _RC4_, _3DES_, _DES_, EXPORT, NULL.