PyRDP is a Python
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
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
-p) parameters applied to
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
-v) option to the previous command. In this example we store the files relatively to the current directory in
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 -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
--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.
- 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.
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.