This post outlines the changes and new features that were added in the PyRDP 1.0 release and explores what is in store for future PyRDP development efforts.

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.

Announcing PyRDP 1.0

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.

Announcing PyRDP 1.0
This post outlines the changes and new features that were added in the PyRDP 1.0 release and explores what is in store for future PyRDP development efforts.

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

We have expanded the file interception capabilities to support files copied to the clipboard on either the client, the server, and even the client’s hypervisor if the client is running in a virtual machine. This feature works regardless of drive mapping and covers the more frequently used method of file transfers with RDP.
[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.
With this addition, we hope to simplify processing and conversion of network captures and session files to various formats. MP4 conversion was a much-requested feature that is helpful for sharing captures with non-technical parties or without requiring a working PyRDP deployment.

Dynamic Certificate Cloning

Versions of PyRDP prior to the 1.0 release would use a static certificate generated on first run or provided by the user through command line switches. While we are keeping this feature, the new default mode of operation will use a local certificate cache and automatically generate certificates matching the target’s common name upon the first connection. This should facilitate deployments as well as attack scenarios where the target is unknown ahead of time and reduce the number of manual steps required during pentest engagements while simultaneously increasing the likelihood of successful interception.

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

Pin It on Pinterest

Share This