base on An advanced, yet simple, tunneling/pivoting tool that uses a TUN interface. # Ligolo-ng : Tunneling like a VPN ![Ligolo Logo](doc/logo.png) An advanced, yet simple, tunneling tool that uses TUN interfaces. [![GPLv3](https://img.shields.io/badge/License-GPLv3-brightgreen.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Go Report](https://goreportcard.com/badge/github.com/nicocha30/ligolo-ng)](https://goreportcard.com/report/github.com/nicocha30/ligolo-ng) [![GitHub Sponsors](https://img.shields.io/github/sponsors/nicocha30)](https://github.com/sponsors/nicocha30) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/nicocha30/ligolo-ng/total) [📑 Ligolo-ng Documentation (Setup/Quickstart)](https://docs.ligolo.ng/) > [!TIP] > Ligolo-ng 0.8 added a lot of new features, including: > - 🌐 API and a beautiful Web Interface thanks to [L'ami du Raisin](https://github.com/jeremiebedjai), allowing **multiplayer**! > - ⚙️ Simple configuration file, to keep your tunneling/proxy settings > - 🚦 **Daemon mode**, to run Ligolo-ng as a service > - 🔗 Auto-bind, to **automatically configure tunneling** whenever a specific agent connects > - 📶 Easy and automatic (autoroute) route and interface management on **Windows, Linux, MacOS and BSD**! > - 💀 Agent kill, to remotely terminate an agent > > Please try it out! > [Release: Ligolo-ng 0.8](https://github.com/nicocha30/ligolo-ng/releases/tag/v0.8) > > ![Ligolo Web](doc/webui.png) ## Table of Contents <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> - [Introduction](#introduction) - [Features](#features) - [Demo](#demo) - [How is this different from Ligolo/Chisel/Meterpreter... ?](#how-is-this-different-from-ligolochiselmeterpreter-) - [How to use - documentation - tutorial](#how-to-use---documentation---tutorial) - [Does it require Administrator/root access ?](#does-it-require-administratorroot-access-) - [Supported protocols/packets](#supported-protocolspackets) - [Performance](#performance) - [Caveats](#caveats) - [Todo](#todo) - [Credits](#credits) <!-- END doctoc generated TOC please keep comment here to allow auto update --> ## 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/Proxychains!) - 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 privileges on the *agent* - Socket listening/binding on the *agent* - Multiple platforms supported for the *agent* - Can handle multiple tunnels - Reverse/Bind Connection - Automatic tunnel/listeners recovery (in case of network issues) - Websocket support ## Demo [Ligolo-ng-demo.webm](https://github.com/nicocha30/ligolo-ng/assets/31402213/3070bb7c-0b0d-4c77-9181-cff74fb2f0ba) ## 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). ## How to use - documentation - tutorial You will find the documentation for Ligolo-ng, as well as the steps to follow to get it up and running on the [Ligolo-ng Documentation](https://docs.ligolo.ng/) ## 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. ```shell $ 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> - Jeremie Bedjai (Ligolo-ng-Web)", Assign "at most 3 tags" to the expected json: {"id":"7029","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"