PyRDP – RDP Monster-In-The-Middle (Mitm) And Library For Python With The Ability To Watch Connections Live Or After The Fact
PyRDP is a Python
Supported Systems
PyRDP should work on Python 3.6 and up on the x86-64, ARM and ARM64 platforms.
This tool has been tested to work on Python 3.6 on Linux (Ubuntu 18.04),
Next, export OSI Layer 7 PDUs:
And lastly, filter down the trace to contain only the conversation of interest (Optional but recommended) by applying a display filter and clicking File > Export Specified Packets...
Now this trace can be used directly in pyrdp-convert
.
Configuring PyRDP
Most of the PyRDP configurations are done through command line switches, but it is also possible to use a configuration file for certain settings such as log configuration.
The default configuration files used by PyRDP are located in mitm.default.ini and player.default.ini. Both files are thoroughly documented and can serve as a basis for further configuration.
In the future there are plans to support other aspects of PyRDP configuration through those configuration files.
Using PyRDP as a Library
If you’re interested in experimenting with RDP and making your own tools, head over to our documentation section for more information.
Using PyRDP with twistd
The PyRDP MITM component was also implemented as a twistd plugin. This enables you to run it in debug mode and allows you to get an interactive debugging repl (pdb) if you send a SIGUSR2
to the twistd process.
twistd --debug pyrdp -t <target>
Then to get the repl:
killall -SIGUSR2 twistd
Using PyRDP with twistd in Docker
In a directory with our docker-compose.yml
you can run something like this:
docker-compose run -p 3389:3389 pyrdp twistd --debug pyrdp --target 192.168.1.10:3389
This will allocate a TTY and you will have access to Pdb
‘s REPL. Trying to add --debug
to the docker-compose.yml
command will fail because there is no TTY allocated.
Using PyRDP with Bettercap
We developped our own Bettercap module, rdp.proxy
, to monster-in-the-middle all RDP connections on a given LAN. Check out this document for more information.
Docker Specific Usage Instructions
Since docker restricts the interactions with the host system (filesystem and network), the PyRDP docker image must be run with some parameters depending on your use case. This section documents those parameters.
We refer to the publicly provided docker image but if you built your own replace gosecure/pyrdp
with the name of your locally built image.
Mapping a Listening Port
In most of the monster-in-the-middle cases you will need to map a port of your host into the docker image. This is achieved by the --publish
(-p
) parameters applied to docker run
.
For example, to listen on 3389 (RDP’s default port) on all interfaces, use:
docker run -p 3389:3389 gosecure/pyrdp pyrdp-mitm.py 192.168.1.10
Logs and Artifacts Storage
To store the PyRDP output permanently (logs, files, etc.), add the --volume
(-v
) option to the previous command. In this example we store the files relatively to the current directory in pyrdp_output
:
docker run -v $PWD/pyrdp_output:/home/pyrdp/pyrdp_output -p 3389:3389 gosecure/pyrdp pyrdp-mitm.py 192.168.1.10
Make sure that your destination directory is owned by a user with a UID of 1000, otherwise you will get permission denied errors. If you are the only non-root user on the system, usually your user will be assigned UID 1000.
Logging the host IP address
If you want PyRDP to log the host IP address in its logs, you can set the HOST_IP
environment variable when using docker run
:
docker run -p 3389:3389 -e HOST_IP=192.168.1.9 gosecure/pyrdp pyrdp-mitm.py 192.168.1.10
Using the GUI Player in Docker
Using the player will require you to export the DISPLAY
environment variable from the host to the docker. This redirects the GUI of the player to the host screen. You also need to expose the host’s network and prevent Qt from using the MIT-SHM X11 Shared Memory Extension. To do so, add the -e
and --net
options to the run command:
docker run -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 --net=host gosecure/pyrdp pyrdp-player.py
Keep in mind that exposing the host’s network to docker can compromise the isolation between your container and the host. If you plan on using the player, X11 forwarding using an SSH connection would be a more secure way.
PyRDP Lore
- Introduction blog post in which we demonstrated that we can catch a real threat actor in action
- Talk at NorthSec 2019 where two demos were performed:
- First demo: credential logging, clipboard stealing, client-side file browsing and a session take-over
- Second demo: the execution of cmd or powershell payloads when a client successfully authenticates
- PyRDP Logo licensed under CC-BY-SA 4.0.
- BlackHat USA Arsenal 2019 Slides
- DerbyCon 2019 Slides (Video)
- Blog: PyRDP on Autopilot
Contributing to PyRDP
See our contribution guidelines.
Acknowledgements
PyRDP uses code from the following open-source software:
- RC4-Python for the RC4 implementation.
- rdesktop for bitmap decompression.
- rdpy for RC4 keys, the bitmap decompression bindings and the base GUI code for the PyRDP player.
- FreeRDP for the scan code enumeration.