Git Product home page Git Product logo

ligolo-mp's Introduction

Ligolo-mp : Tunneling like ligolo-ng, now with friends!

Ligolo-mp Logo

This thing is based on amazing work by nicocha30 on Ligolo-ng. I also borrowed quite a bit from Sliver codebase. Thanks, you people are amazing!

GPLv3

Table of Contents

Introduction

Ligolo-mp is a more specialized version of Ligolo-ng, with client-server architecture, enabling pentesters to play with multiple concurrent tunnels collaboratively. Also, with a sprinkle of less important bells and whistles.

Features

Everything that you love about Ligolo-ng and:

  • Multiplayer
  • Multiple concurrent relays
  • Routing to the loopback of target machine (no more port forwarding)
  • Listeners are now independent redirectors
  • Stricter agent liveness checks
  • Built-in TUN management
  • Dynamic mTLS-enabled agent binaries generation with obfuscation option
  • Simplified certificate management

Important notes

  • This thing doesn't try to be stealthy: there are no tricky malleable profiles, no network fuckery - you will be detected. You have been warned.
  • Server-side is linux-only (agents are still multi-platform, don't worry)
  • Everything uses self-signed certs
  • This is mostly just somehow slapped together, so use at your own risk

Terminology

On our local machine we use client to connect to a server, that's running on the attacking machine. Then we run an agent on the machine we want pivot through - a target machine. To actually start pivoting, we create a tun and use it to start a relay between server and agent. We can also start a listener to, for example, chain connections through agents in cases where target machine can't directly reach our server.

Here's a very professional visual:

Ligolo-mp architecture

Building

Precompiled binaries

Precompiled binaries (Windows/Linux/macOS) are available on the Release page.

Building Ligolo-mp

Just refer to the makefile, but just for completeness sake:

# Build server
$ make assets server

# Build client
$ make client

# Build everything
$ make all

Usage

Setup

  1. Put the server binary in /usr/local/bin (or wherever you prefer)
  2. Create systemd service, like this one. You can change listening ports, connection pool size and so on with more flags (refer to -h), but let's stick to defaults for now
[Unit]
Description=Ligolo-mp
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=3
User=root
ExecStart=/usr/local/bin/ligolo-mp-server -daemon

[Install]
WantedBy=multi-user.target
  1. Run the cli part of the server with the same user as you run daemon (most probably just sudo it) and create an operator or two
$ ligolo-mp-server
...
ligolo-mp » operator new --name myoperator --server 127.0.0.1:58008 --path /home/kali/
Operator 'myoperator' added. Config is saved to '/home/kali/myoperator_127.0.0.1:58008_ligolo-mp.json'
  1. Now, on the client side, import generated config. You can import multiple configs, if you need
$ ligolo-client -import /home/kali/myoperator_127.0.0.1:58008_ligolo-mp.json
Credentials successfully imported!
  1. Run client, choose the config you need and start pivoting!
$ ligolo-client_linux                                                             
Use the arrow keys to navigate: ↓ ↑ → ← 
Select credentials
    operator
    another_operator
  -> myoperator
    friendly_operator

--------- Agents ----------
Name:          myoperator
Server:        127.0.0.1:58008

Basic flow

  1. Use 'help' command, should be pretty self-explanatory

  2. Create a TUN

ligolo-mp » tun new
[+] New TUN created: confident_euclid
  1. Add routes to networks which are accessible via host that's running ligolo agent
ligolo-mp » tun route new 10.10.2.0/24 10.10.3.0/24 10.10.4.0/32
Selected: confident_euclid
[+] Route 10.10.2.0/24@confident_euclid created

[+] Route 10.10.3.0/24@confident_euclid created

[+] Route 10.10.4.0/32@confident_euclid created
  1. Generate an agent binary (11601 - is a default port server is listening on, use whatever you provided as -agentaddr otherwise)
$ agent generate --save /home/kali/agent --os linux --arch amd64 --server 127.0.0.1:11601 --obfuscate
[+] Agent binary saved to /home/kali/agent
  1. Run agent on the target machine
# On target
$ ./agent
# On client
[+] Agent [email protected]/8,::1/128,192.168.2.53/24 joined

ligolo-mp »  
  1. Start the relay
ligolo-mp » relay start
Selected: bold_nash
Selected: confident_euclid
[+] Established a tunnel with agent [email protected]/8,::1/128,192.168.2.53/24

That's it, your pivot is ready to use. Using this flow you can maintain as many combinations of TUNs, routes and agents as you need.

Adding routes routine will check for overlaps in currently active TUNs and error out if that's the case. The only thing to keep in mind is that there's 1 to 1 mapping between agent and TUN, but I think there are enough railguards in place to prevent any undefined behavior.

If your agent dies, you can just restart in on the target machine and all the routes and the tunnel will be applied automatically. Also, if agent can't connect back to the server, it will retry indefinitely.

Accessing local ports

If you need to access the services running on the same machine that's running an agent, you can use --loopback option for a TUN. Let me demonstrate:

  1. Machine with agent bold_nash is running a service on 127.0.0.1:9999

  2. Create a loopback TUN

$ ligolo-mp » tun new --loopback 
[+] New TUN created: nervous_cori
  1. Add a route that you want to represent agent's localhost, for example
$ ligolo-mp » tun route new 10.10.10.10/24
Selected: nervous_cori
[+] Route 10.10.10.10/24@nervous_cori created
  1. Start a relay
$ ligolo-mp » relay start 
Selected: bold_nash
Selected: nervous_cori
[+] Established a relay with agent [email protected]/8,::1/128,192.168.2.53/24
  1. That's it. Now, accessing 10.10.10.10:9999 will route traffic to the bold_nash's 127.0.0.1:9999

Chaining agents

If your target machine (machine#1) can't reach the server directly, but can access a machine that's running another agent (machine#2), you can use listeners to proxy the traffic. So, to implement a chain machine#1<->machine#2<->server:

  1. Create a listener on machine#2's agent:
# 192.168.2.53 - bold_nash's address (you can also just use 0.0.0.0, if you want)
# 192.168.2.10 - server's address
ligolo-mp » listener new --from 192.168.2.53:1234 --to 192.168.2.10:11601
Selected: bold_nash
[+] Listener (bold_nash) from 192.168.2.53:1234 to 192.168.2.10:11601 started
  1. Generate an agent that'll connect through the listener
# Notice the --server option, it's pointing to the listener
ligolo-mp » agent generate --save /home/kali/chained_agent --os linux --server 192.168.2.53:1234 
[+] Agent binary saved to /home/kali/chained_agent
  1. That's it, just run an agent as usual on the machine#1.

This listener is just a TCP redirector, so you can probably find more ways to use it.

Situational awareness

If you just joined your friend's server, you probably need to see what's going on, you can do it with list subcommand

  • Listing active TUNs
$ ligolo-mp » tun list
┌───────────────────────────────────────────────┐
│ Active TUNs                                   │
├────────────────┬────────────────┬─────────────┤
│ ALIAS          │ ROUTES         │ IS LOOPBACK │
├────────────────┼────────────────┼─────────────┤
│ gallant_kepler │ 11.11.11.0/24  │ false       │
│                │ fe80::/64      │             │
│ nervous_cori   │ fe80::/64      │ true        │
│                │ 172.10.10.1/32 │             │
│                │ 10.11.0.0/16   │             │
│                │ 10.10.10.0/24  │             │
└────────────────┴────────────────┴─────────────┘
  • Listing active agents
$ ligolo-mp » agent list 
┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Active agents                                                                                         │
├──────────────┬─────────────────────────────────────────┬───────────────┬────────────────┬─────────────┤
│ ALIAS        │ AGENT INTERFACES                        │ CONNECTED TUN │ ROUTES         │ IS LOOPBACK │
├──────────────┼─────────────────────────────────────────┼───────────────┼────────────────┼─────────────┤
│ elated_wiles │ 127.0.0.1/8                             │ nervous_cori  │ 10.10.10.0/24  │ true        │
│              │ ::1/128                                 │               │ fe80::/64      │             │
│              │ 192.168.2.53/24                         │               │ 172.10.10.1/32 │             │
│              │                                         │               │ 10.11.0.0/16   │             │
└──────────────┴─────────────────────────────────────────┴───────────────┴────────────────┴─────────────┘
  • Listing active listeners
$ ligolo-mp » listener list 
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Active listeners                                                                │
├────────────────────────┬──────────────┬────────────────────┬────────────────────┤
│ ALIAS                  │ AGENT        │ FROM               │ TO                 │
├────────────────────────┼──────────────┼────────────────────┼────────────────────┤
│ dazzling_chandrasekhar │ elated_wiles │ 192.168.2.53:31337 │ 192.168.2.10:31337 │
└────────────────────────┴──────────────┴────────────────────┴────────────────────┘

Misc

  • You can enable binary obfuscation for agent generation with flag --obfuscate. Not sure why you'd need that, since this whole thing is not stealthy at all, but I was borrowing code from Sliver and it was there too
  • There is basic certificate management available with the command certificate. You can use it to refresh CA cert, for example.

Does it require Administrator/root access ?

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

However, on your the server, you need to be able to create/modify tun interfaces.

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

  • Change or at least refactor current agent protocol - it's a bit awkward to work with
  • Certificate revokation for compromised agents
  • Make TUN management more opinionated and get rid of manual management of them altogether

ligolo-mp's People

Contributors

exp101t avatar ttpreport avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ligolo-mp's Issues

Problems with setup and compilation

Hello, I've got some problem with setup. Tested env was debian 10, ubuntu, kali

./ligolo-mp_server_1.0.3_linux_amd64
panic: could not initialize certificates: sql: no rows in result set

goroutine 1 [running]:
main.main()
github.com/ttpreport/ligolo-mp/cmd/server/main.go:48 +0x7ab

Also was trying to compiled it but got errors like this

go: error loading module requirements
make: *** [Makefile:32: agent] Error 1

Any Suggestions? Thanks in advance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.