Over the last few years PyRDP has secured itself as a strong candidate for both offensive security engagements and honeypot scenarios. GoSecure is happy to announce the upcoming 1.0 release of the tool. This release adds a significant amount of documentation for using PyRDP as a library as well as multiple performance improvements and support for several new techniques.
For a full tour of the PyRDP features, make sure to tune in to our SecTor talk on October 21st 2020 at 14:00 EDT where we will be showing off what PyRDP can do.
In the next sections we will highlight some of the new features that are shipping with 1.0.
Over the last few years PyRDP has secured itself as a strong candidate for both offensive security engagements and honeypot scenarios. GoSecure is happy to announce the upcoming 1.0 release of the tool. This release adds a significant amount of documentation for using PyRDP as a library as well as multiple performance improvements and support for several new techniques.
For a full tour of the PyRDP features, make sure to tune in to our SecTor talk on October 21st 2020 at 14:00 EDT where we will be showing off what PyRDP can do.
In the next sections we will highlight some of the new features that are shipping with 1.0.
CredSSP Support for Honeypot Scenarios
One of our focus points with PyRDP is to implement as much of RDP as possible such that connections intercepted by PyRDP appear identical to connection to legitimate servers. Due to protections in RDP against monster-in-the-middle – specifically, network-level authentication (NLA) – which uses CredSSP to make interception nearly impossible (see CredSSPY for other attacks on CredSSP) we had been downgrading the connection encryption layer to plain SSL, which is relatively easy to fingerprint by scanners and malicious actors.
PyRDP 1.0 offers a workaround to allow CredSSP authentication against servers which are controlled by the operator. This is mainly interesting for honeypot scenarios which attempt to lure threat actors to collect information about attacks.
Under the Hood
This technique relies on the way that CredSSP authentication works as well as being in possession of the RDP private key belonging to the target server, so it does assume that the RDP server is fully controlled by the PyRDP operator. In the next few paragraphs, we will break down how this was implemented with minimal code changes to the PyRDP code base.
Image 1 – CredSSP authentication flow
The previous illustration displays a slightly simplified CredSSP authentication flow. A plaintext authentication method negotiation happens immediately after the TCP channel is opened, and the client offers CredSSP, which the servers accepts in its negotiation response. Previously, PyRDP was downgrading the negotiation request to SSL so the server would engage using this authentication mechanism unless NLA enforcement was activated. With PyRDP 1.0 and the CredSSP feature activated we no longer perform any tampering in this step.
Once this is done, the peers establish a TLS channel with PyRDP using the certificate and private key of the server in both directions. This is a critical step in the ability to bypass SSP’s mutual authentication. Within this TLS channel, the client performs an SPNEGO to determine which authentication provider to use (NTLM or Kerberos). PyRDP lets this negotiation happen, untampered.
Once the provider is selected, the binding phase happens, which is specific to the provider. The case for Kerberos works in a similar fashion, so here we only cover the NTLM case: a mutual hashing of the server’s public key with a well-known salt, encrypted using the NTLM hash of the user’s password as a key. This step’s purpose is to ensure that the certificate that the client received matches the certificate presented by the server and thus prevent a monster-in-the-middle attack. The NTLM hash is used as an additional layer to prove knowledge of the password without any credentials being sent until both peers are verified. This works because the wrong hash would cause decryption to fail and thus peer validation to fail as well. After successful verification, the actual credentials are sent to the server, still encrypted using the NTLM hash.
Even with PyRDP in the middle, knowledge of the private key allows all the negotiation to happen transparently. Thankfully, the RDP connection proceeds over the already-established TLS channel after this authentication step, so only minor code changes were needed to allow CredSSP to passthrough without any tampering on PyRDP’s part.
Clipboard File Carving
[2020-05-27 12:36:48,966] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - ---- Received Clipboard Files ----
[2020-05-27 12:36:48,967] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - secret3.txt
[2020-05-27 12:36:48,967] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - -------------------------
[2020-05-27 12:36:50,049] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Starting transfer for file "secret3.txt" ClipId=1
[2020-05-27 12:36:50,083] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Transfer completed for file "secret3.txt" location: "pyrdp_output/files/Stephanie315037/secret3.txt"
[2020-05-27 12:36:57,629] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - ---- Received Clipboard Files ----
[2020-05-27 12:36:57,630] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - secret3.txt
[2020-05-27 12:36:57,630] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - -------------------------
[2020-05-27 12:36:58,438] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Starting transfer for file "secret3.txt" ClipId=1
[2020-05-27 12:36:58,472] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Transfer completed for file "secret3.txt" location: "pyrdp_output/files/Stephanie315037/secret3_1.txt"
[2020-05-27 12:37:05,465] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - ---- Received Clipboard Files ----
[2020-05-27 12:37:05,466] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - secret3.txt
[2020-05-27 12:37:05,466] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - -------------------------
[2020-05-27 12:37:06,360] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Starting transfer for file "secret3.txt" ClipId=1
[2020-05-27 12:37:06,396] - INFO - Stephanie315037 - pyrdp.mitm.connections.cliprdr - Transfer completed for file "secret3.txt" location: "pyrdp_output/files/Stephanie315037/secret3_2.txt"
Headless Player Support
We created an alternative docker image we call our slim image to remove all the UI functionality for pure interception scenarios. This reduced the image size from 800MB to a little over 70MB. It also enables PyRDP to run on other architectures supported by Python like ARM. This is useful to improve deployment speeds, keep dependencies to a minimum and use PyRDP in larger embedded devices like a Raspberry Pi. This image is available on DockerHub under gosecure/pyrdp:1.0.0-slim
or gosecure/pyrdp:latest-slim
to use our master branch.
On top of that, we also added a brand new --headless
option to the player which dumps keystrokes, mouse, and clipboard events to the terminal without doing any rendering of the video. This allows for high throughput when processing multiple replay files and makes it easier to develop analysis tools around captured sessions.
$ pyrdp-player.py ––headless Tashia991771.pyrdp
INFO - pyrdp - Starting PyRDP Player in headless mode.
== REPLAY FILE: Tashia991771.pyrdp
--------------------
HOST: RDPSRV
--------------------
--------------------
USERNAME:
PASSWORD:
DOMAIN:
--------------------
<Resolution: 1920x1080>
<Tab released>
...
<Control released>
<Tab released>toor
<Return pressed>
<Return released>
-------------------
CLIPBOARD DATA: Top Secret Data
--------------------
<Click (Left) @ (751, 433)>
<Click (Left) @ (23, 24)>
<Click (Left) @ (23, 24)>
<Click (Left) @ (1270, 701)>
hellopyrdp
New Conversion Tool
We rewrote the pyrdp-replay tool to a more generic conversion tool: pyrdp-convert. This tool supports conversion from unencrypted PCAPs (OSI layer 7) to replay sessions, like its predecessor, and supports additional cases:
- Layer 7 PCAP to MP4
- PyRDP Session to MP4
- Encrypted PCAP to Session (Experimental)
- Encrypted PCAP to MP4 (Experimental)
usage: pyrdp-convert.py [-h] [-l] [-s SECRETS] [-f {replay,mp4}] [--src SRC] [--dst DST] [-o OUTPUT] input
positional arguments:
input Path to a .pcap or .pyrdp file
optional arguments:
-h, --help show this help message and exit
-l, --list Print the list of sessions in the capture without processing anything
-s SECRETS, --secrets SECRETS
Path to the file containing the SSL secrets to decrypt Transport Layer
Security.
-f {replay,mp4}, --format {replay,mp4}
Format of the output
--src SRC If specified, limits the converted streams to connections initiated from this
address
--dst DST If specified, limits the converted streams to connections destined to this
address
-o OUTPUT, --output OUTPUT
Path to write the converted files to. If a file name is specified, it will be
used as a prefix,otherwise the result is output next to the source file with
the proper extension.
Dynamic Certificate Cloning
Image 2 – Dynamically cloned certificate
Other Features
- Display scaling for replays in the player
- Improved bandwidth usage through GDI graphics pipeline support
- Support for transparent proxying and dynamic targets
- Added documentation for PyRDP internal architecture
Conclusion
For the full release notes and change log, head over to the PyRDP GitHub page. You can also grab a fresh copy of the 1.0 release through Docker as outlined in the project’s README file or via git.
We will keep adding features to PyRDP as we need them and based on the requested features on the issues page, so all ideas should be submitted there. Here are a few things that we are thinking about for the future:
- Improving the headless player’s output format to something more computer friendly (JSON)
- Additional support for RDP extensions
- Client fingerprinting capabilities
Remember that Hacktoberfest is currently under way and we’re encouraging everyone who’s interested in contributing to PyRDP to hop in!
References
- MS-RDPBCGR: RDP Authentication Negotiation
- MS-CSSP: CredSSP Specification
- MS-NLMP : NTLM Provider for GSS
- GSS-API : Generic Security Service Provider Specification