Introduction

As we enter a new decade, we find that old coding errors in old kernel code have the potential of impacting even the newest operating systems like Windows 10.

Finding an overflow vulnerability like DejaBlue in the Remote Desktop Protocol (RDP) shouldn’t be a big surprise. RDP was first released by Citrix in 1995 — 25 years ago! — as part of an enhanced version of Windows NT 3.51 called WinFrame.

It was later added to Windows NT 4.0 Terminal Server Edition by Microsoft and has been a part of all Windows Server operating systems ever since, as well as all non-home client operating systems since Windows XP.

Remote access protocols like RDP are hugely beneficial for system administrators — especially in OT environments — because they enable users to remotely configure OT systems from their offices or from home, without the inconvenience and potential safety issues of wandering onto the plant floor.

But exposing RDP to the internet also adds a lot of risk. In the past few years we’ve seen compromised RDP access as the top entry vector for ransomware attacks such as SamSam, Dharma, and CrySis. The attackers typically get in by exploiting weak or missing RDP credentials.

These RDP-focused ransomware attacks have been attributed to diverse threat actors including an Iranian cyber-espionage group; a Chinese-state sponsored actor; and a healthcare ransomware extortion scheme most likely operated by a sophisticated cybercriminal organization.

Last month, we also saw attempts to exploit the BlueKeep RDP vulnerability for cryptocurrency mining. Not surprisingly, these were preceded by attackers scanning the internet for machines with vulnerable RDP ports. Cryptocurrency miners are certainly an annoyance in corporate environments, but they’re much more serious in OT environments, where they can reduce production efficiency and potentially cause downtime — since stealing CPU cycles for cryptomining can impact the critical need for sub-millisecond response times in cyber physical systems (CPS).

Finally, although we haven’t seen it yet, DejaBlue and other RDP vulnerabilities could be used in targeted attacks to deploy back-doors for persistent access, which is especially worrisome in OT environments.

This blog post describes how RDP works and how the DejaBlue vulnerability exploits a heap overflow vulnerability in the Windows kernel code, which was reverse-engineered by CyberX’s Section 52 threat intelligence team.

It concludes with an estimate of the number of vulnerable machines exposed to the internet, and a series of recommendations for protecting against DejaBlue and similar vulnerabilities. There’s also a short video at the end showing Section 52’s denial-of-service exploit for the DejaBlue vulnerability.

Background on RDP

RDP (Remote Desktop Protocol) provides users with the ability to remotely access and control the resources and data of a Windows computer.

This protocol usually works on port 3389/TCP and 3389/UDP.

In order to transmit complex data, the protocol is built using modular components called Static Virtual Channels. Each channel has its own purpose and is used to transmit specific data, for example:

  • rdpdr – File System operations
  • rdpsnd – Audio output
  • cliprdr – Clipboard sharing
  • drdynvc – dynamic virtual channels

The virtual channels are chosen during the initial connection phase between the server and the client. The client is responsible for specifying which channels it would like to use.

The chosen channels are transmitted in plain text. We can see in the screenshot below which channels the client has requested:

Defining channel IDs to be used in RDP server/client communication. Plain text is used during this initial phase of communication.

Defining channel IDs to be used in RDP server/client communication. Plain text is used during this initial phase of communication.

The server returns list of unique IDs that will identify each channel. These IDs are used to specify which channel will be used when the data is transmitted.

Also, one of several security levels are chosen during the initialization stage, including:

  • Standard RDP Security
  • SSL
  • CredSSP
  • RDSTLS
  • CredSSP with Early User Authorization

The username and password don’t have to be provided during the initialization state in some cases. If the security level requires a username and password, the DejaBlue vulnerability is rendered useless.

The DVC Manager

drdynvc (Dynamic Virtual Channels)

The RDP protocol supports only 31 channels per session. In order to overcome this limitation, a new channel called drdynvc was created to support additional channels.

The channels in drdynvc are called dynamic because they can be created during the session itself and not just during the initialization phase.

Dynamic channels are identified by name as well. Here are some examples:

  • Microsoft::Windows::RDS::Video::Control::v08.01
  • Microsoft::Windows::RDS::Video::Data::v08.01
  • Microsoft::Windows::RDS::Geometry::v08.01

During the initialization phase, the drdynvc channel also needs to be initialized, but only once per session.

DVC Manager – Initialize

During the Capabilities Exchange phase of the RDP Connection Sequence, the server sends a protocol data unit (PDU) message indicating the maximum supported version and other relevant information.

The client will respond with its maximum supported version, as can be seen here:

Handshake mechanism for exchanging information about supported versions during creation of Dynamic Virtual Channels (DVCs).

Handshake mechanism for exchanging information about supported versions during creation of Dynamic Virtual Channels (DVCs).

DVC – Open

The next step is opening the DVC itself. The request to open a dynamic channel will always come from the server. Dynamic channels have a unique ID that will be used to identify on which channel the data is transmitted.

Handshake mechanism for creating unique IDs for Dynamic Virtual Channels (DVCs).

Handshake mechanism for creating unique IDs for Dynamic Virtual Channels (DVCs).

DVC – Send data

Each packet is called a PDU (Protocol Data Unit) and its size is limited to 1,600 (0x640) bytes.

The data can also be compressed. Compression is only available in DVC version 3, and the algorithm used is RDP 8.0 lossless compression.

RDP 8.0 compression is based on Lempel-Ziv and static Huffman encoding but slightly modified.

The interesting point here is that a single uncompressed PDU packet is limited to 8,192 (0x2000) bytes by the RDP protocol specification.

The structure of the compressed data is called RDP_SEGMENTED_DATA.

The structure of the packet is shown below:

  • descriptor (1 byte) – Specifies whether it wraps single or multiple segments; each PDU can contain multiple data segments in one packet.
  • segmentCount (2 bytes) – Number of segments; exists only if descriptor == 255
  • uncompressedSize (4 bytes) – Total size of uncompressed data; exists only if descriptor == 255
  • segmentArray (variable) – Its structure is RDP_DATA_SEGMENT, which is 4-byte size + compressed data (RDP8_BULK_ENCODED_DATA); exists only if descriptor == 255

The structure looks like this:

image006

DejaBlue Vulnerabilities

CVE-2019-1181 & CVE-2019-1182

These vulnerabilities were discovered internally by Microsoft and published in August 2019.
Microsoft described the vulnerabilities as “critical” because they can result in Remote Code Execution (RCE).

Like BlueKeep, the vulnerabilities are also particularly serious because they’re “pre-authentication” — and therefore “wormable” — meaning they can be used to create an automated worm that jumps from machine to machine without any user interaction (similar to WannaCry).

The vulnerabilities affect all Windows versions from Windows 7 to Windows 10 including server versions.

The vulnerabilities reside in the DVC Manager component which handles the channel drdynvc.

The Cause of the Bug: Int Overflow in DLL

The bug that causes these vulnerabilities lies in the DLL RDPcorets.dll, and the vulnerable function is DecompressUnchopper::Decompress.

This function is responsible for decompressing data from the RDP_SEGMENTED_DATA packet.

We can see from the code below that once the descriptor has the value 225, the code checks to see if there is enough space for the uncompressedSize, by comparing it to the length of the buffer (this + 16).

If the buffer is too small for the uncompressed data, the code will delete the original buffer and allocate a new one with the uncompressedSize + 0x2000. It assumes there’s no possibility it will need more than 0x2000, because the packet should be limited to that value by the protocol specification.

This leads to an int overflow situation. If we send uncompressed data with the value of 0xFFFFE001, and the code tries to reallocate it, the new size of the buffer would be 1 (0xFFFFE001 + 0x2000 = 1).

Let’s say we send uncompressed data that causes an int overflow, but also send a real buffer with the size 0x1500. What will happen is that the code will copy the 0x1500 bytes to the 1 byte buffer, using the memcpy function. This will result in memory corruption of the heap.

Windows code reverse-engineered by Section 52, CyberX’s threat intelligence team, showing location of heap overflow vulnerability.

Windows code reverse-engineered by Section 52, CyberX’s threat intelligence team, showing location of heap overflow vulnerability.

Shodan Data: Vulnerable RDP Connections

CyberX’s Section 52 team created a proprietary scanner that scans open RDP connections to determine if they’re vulnerable to DejaBlue.

We used Shodan to scan for open RDP sessions and found there are currently around 3.5 million open RDP connections. Using our tool, we found out that 9.26% or around 330,000 of these systems are vulnerable to DejaBlue.

This is much smaller than the estimate of 1 million vulnerable systems that was discussed earlier this year. We don’t know exactly why, but we’re guessing it’s because:

  • DejaBlue only affects newer Windows versions — and there are a lot fewer of these deployed worldwide.
  • Owners of newer Windows systems are much more likely to patch than owners of older Windows systems.
Distribution of systems with open RDP ports by geography (via Shodan).

Distribution of systems with open RDP ports by geography (via Shodan).

Recommendations

There have been many excellent articles written about how to protect yourself from exploitation of RDP vulnerabilities, including a recent blog post by eSet that provides a comprehensive table describing 10 separate ways to strengthen RDP security.

These include the usual steps of patching systems when possible (but this is often difficult in OT due to limited maintenance windows); enabling Network Level Authentication (NLA); and using complex passwords with VPNs and 2FA for stronger identification and authentication.

Cisco also published a detailed blog post about how to share encryption keys with inline IPS devices to decrypt RDP traffic. The procedure seems long and fairly complicated but the authors explain that this approach will help detect and prevent attacks that leverage RDP vulnerabilities to deliver malware in the encrypted RDP traffic.

And of course you should shut down RDP ports on any internet-facing systems that don’t require RDP access from the internet — but that’s sometimes difficult to accomplish overnight, especially in legacy OT environments.

A final recommendation is to deploy network security monitoring with behavioral anomaly detection. This will enable your SOC to rapidly detect any unusual or unauthorized connections to your IoT/OT network — so you can mitigate attacks in their early stages, before attackers can shut down or blow up you facilities.

Denial-of-Service Exploit Video

In this video of Section 52’s denial-of-service exploit for the DejaBlue vulnerability, you’ll see the malicious executable being launched at the top left, followed by the RDP services being terminated at the top right. You’ll also see the RDP ports being shut-down in the bottom right window, as indicated by red highlighting.