Research by: Eyal Itkin
Overview
Used by thousands of IT professionals and security researchers worldwide, the Remote Desktop Protocol (RDP) is usually considered a safe and trustworthy application to connect to remote computers. Whether it is used to help those working remotely or to work in a safe VM environment, RDP clients are an invaluable tool.
However, Check Point Research recently discovered multiple critical vulnerabilities in the commonly used Remote Desktop Protocol (RDP) that would allow a malicious actor to reverse the usual direction of communication and infect the IT professional or security researcher’s computer. Such an infection could then allow for an intrusion into the IT network as a whole.
16 major vulnerabilities and a total of 25 security vulnerabilities were found overall. The full list can be found in Appendix A & B.
7th of August 2019 – New developments in the research:
After the initial publication of our research, our researchers found new implications for the Reverse RDP Attack that also impact Microsoft’s Hyper-V product. Due to these new developments, Microsoft updated their response and issued the vulnerability an official CVE: CVE-2019-0887. Full details can be found in the newly published blog post.
Introduction
The Remote Desktop Protocol (RDP), also known as “mstsc” after the Microsoft built-in RDP client, is commonly used by technical users and IT staff to connect to / work on a remote computer. RDP is a proprietary protocol developed by Microsoft and is usually used when a user wants to connect to a remote Windows machine. There are also some popular open-source clients for the RDP protocol that are used mainly by Linux and Mac users.
RDP offers many complex features, such as: compressed video streaming, clipboard sharing, and several encryption layers. We therefore decided to look for vulnerabilities in the protocol and its popular implementations.
In a normal scenario, you use an RDP client, and connect to a remote RDP server that is installed on the remote computer. After a successful connection, you now have access to and control of the remote computer, according to the permissions of your user. But if the scenario could be put in reverse? We wanted to investigate if the RDP server can attack and gain control over the computer of the connected RDP client.
Figure 1: Attack scenario for the RDP protocol
There are several common scenarios in which an attacker can gain elevated network permissions by deploying such an attack, thus advancing his lateral movement inside an organization:
Now that we decided on our attack vector, it is time to introduce our targets, the most commonly used RDP clients:
Fun fact: As “rdesktop” is the built-in client in Kali-linux, a Linux distro used by red teams for penetration testing, we thought of a 3rd (though probably not practical) attack scenario: Blue teams can install organizational honeypots and attack red teams that try to connect to them through the RDP protocol.
Open-Source RDP clients
As is usually the case, we decided to start looking for vulnerabilities in the open source clients. It seems that it will only make sense to start reverse engineer Microsoft’s client after we will have a firm understanding of the protocol. In addition, if we find common vulnerabilities in the two open sourced clients, we could check if they also apply to Microsoft’s client. In a recon check it looked like “rdesktop” is smaller than “FreeRDP” (has fewer lines of code), and so we selected it as our first target.
Note: We decided to perform an old-fashioned manual code audit instead of using any fuzzing technique. The main reasons for this decision were the overhead of writing a dedicated fuzzer for the complex RDP protocol, together with the fact that using AFL for a protocol with several compression and encryption layers didn’t look like a good idea.
After a short period, it looked like the decision to manually search for vulnerabilities paid off. We soon found several vulnerable patterns in the code, making it easier to “feel” the code, and pinpoint the locations of possible vulnerabilities.
We found 11 vulnerabilities with a major security impact, and 19 vulnerabilities overall in the library. For the full list of CVEs for “rdesktop”, see Appendix A.
Note: An additional recon showed that the xrdp open-source RDP server is based on the code of “rdesktop”. Based on our findings, it appears that similar vulnerabilities can be found in “xrdp” as well.
Instead of a technical analysis of all of the CVEs, we will focus on two common vulnerable code patterns that we found.
Remote Code Executions – CVEs 2018-20179 – 2018-20181
Throughout the code of the client, there is an assumption that the server sent enough bytes to the client to process. One example for this assumption can be found in the following code snippet in Figure 2:
Figure 2: Parsing 2 fields from stream “s” without first checking its size
As we can see, the fields “length” and “flags” are parsed from the stream “s”, without checking that “s” indeed contains the required 8 bytes for this parsing operation. While this usually only leads to an Out-Of-Bounds read, we can combine this vulnerability with an additional vulnerability in several of the inner channels and achieve a much more severe effect.
There are three logical channels that share a common vulnerability:
The vulnerability itself can be seen in Figure 3:
Figure 3: Integer-Underflow when calculating the remaining “pkglen”
By reading too much data from the stream, i.e. sending a chopped packet to the client, the invariant that “s->p <= s->end” breaks. This leads to an Integer-Underflow when calculating “pkglen”, and to an additional Integer-Overflow when allocating “xmalloc(pkglen + 1)” bytes for our buffer, as can be seen in my comment above the call to “xmalloc”.
Together with the proprietary implementation of “STRNCPY”, seen in Figure 4, we can trigger a massive heap-based buffer overflow when copying data to the tiny allocated heap buffer.
Figure 4: proprietary implementation of the “strncpy” function
By chaining together these two vulnerabilities, found in three different logical channels, we now have three remote code execution vulnerabilities.
CVE 2018-8795 – Remote Code Execution
Another classic vulnerability is an Integer-Overflow when processing the received bitmap (screen content) updates, as can be seen in Figure 5:
Figure 5: Integer-Overflow when processing bitmap updates
Although “width” and “height” are only 16 bits each, by multiplying them together with “Bpp” (bits-per-pixel), we can trigger an Integer-Overflow. Later on, the bitmap decompression will process our input and break on any decompression error, giving us a controllable heap-based buffer-overflow.
Note: This tricky calculation can be found in several places throughout the code of “rdesktop”, so we marked it as a potential vulnerability to check for in “FreeRDP”.
After finding multiple vulnerabilities in “rdesktop”, we approached “FreeRDP” with some trepidation; perhaps only “rdesktop” had vulnerabilities when implementing RDP? We still can’t be sure that every implementation of the protocol will be vulnerable.
And indeed, at first glance, the code seemed much better: there are minimal size checks before parsing data from the received packet, and the code “feels” more mature. It is going to be a challenge. However, after a deeper examination, we started to find cracks in the code, and eventually we found critical vulnerabilities in this client as well.
We found 5 vulnerabilities with major security impact, and 6 vulnerabilities overall in the library. For the full list of CVEs for “FreeRDP”, see Appendix B.
Note: An additional recon showed that the RDP client NeutrinoRDP is a fork of an older version (1.0.1) of “FreeRDP” and therefore probably suffers from the same vulnerabilities.
At the end of our research, we developed a PoC exploit for CVE 2018-8786, as can be seen in this video:
CVE 2018-8787 – Same Integer-Overflow
As we saw earlier in “rdesktop”, calculating the dimensions of a received bitmap update is susceptible to Integer-Overflows. And indeed, “FreeRDP” shares the same vulnerability:
Figure 6: Same Integer-Overflow when processing bitmap updates
Remote Code Execution – CVE 2018-8786
Figure 7: Integer-Truncation when processing bitmap updates
As can be seen in Figure 7, there is an Integer-Truncation when trying to calculate the required capacity for the bitmap updates array. Later on, rectangle structs will be parsed from our packet and into the memory of the too-small allocated buffer.
This specific vulnerability is followed by a controlled amount (“bitmapUpdate->number”) of heap allocations (with a controlled size) when the rectangles are parsed and stored to the array, granting the attacker a great heap-shaping primitive. The downside of this vulnerability is that most of the rectangle fields are only 16 bits wide, and are upcasted to 32 bits to be stored in the array. Despite this, we managed to exploit this CVE in our PoC. Even this partially controlled heap-based buffer-overflow is enough for a remote code execution.
After we finished checking the open source implementations, we felt that we had a pretty good understanding of the protocol and can now start to reverse engineer Microsoft’s RDP client. But first thing first, we need to find which binaries contain the logic we want to examine. The *.dll files and *.exe files we chose to focus on:
Testing prior vulnerabilities
We started by testing our PoCs for the vulnerabilities in the open-source clients. Unfortunately, all of them caused the client to close itself cleanly, without any crash. Having no more excuses, we opened IDA and started to track the flow of the messages. Soon enough, we realized that Microsoft’s implementation is much better than the implementations we tested previously. Actually, it seems like Microsoft’s code is better by several orders of magnitude, as it contains:
Needless to say, there were checks for Integer-Overflows when processing bitmap updates.
Wait a minute, they share a clipboard?
When we checked “rdesktop” and “FreeRDP”, we found several vulnerabilities in the clipboard sharing channel (every logical data layer is called a channel). However, at the time, we didn’t pay much attention to it because they only shared two formats: raw text and Unicode text. This time it seems that Microsoft supports several more shared data formats, as the switch table we saw was much bigger than before.
After reading more about the different formats in MSDN, one format immediately attracted our attention: “CF_HDROP”. This format seems responsible for “Drag & Drop” (hence the name HDROP), and in our case, the “Copy & Paste” feature. It’s possible to simply copy a group of files from the first computer, and paste them in the second computer. For example, a malware researcher might want to copy the output log of his script from the remote VM to his desktop.
It was roughly at this point, while I was trying to figure out the flow of the data, Omer (@GullOmer) asked me if and where PathCanonicalizeA is called. If the client fails to properly canonicalize and sanitize the file paths it receives, it could be vulnerable to a path-traversal attack, allowing the server to drop arbitrary files in arbitrary paths on the client’s computer, a very strong attack primitive. After failing to find imports for the canonicalization function, we dug in deeper, trying to figure out the overall architecture for this data flow.
Figure 8 summarizes our findings:
Figure 8: Architecture of the clipboard sharing in Microsoft’s RDP
This is where rdpclip.exe comes into play. It turns out that the server accesses the clipboard through a broker, and that is rdpclip.exe. In fact, rdpclip.exe is just a normal process (we can kill / spawn it ourselves) that talks to the RDP service using a dedicated virtual channel API.
At this stage, we installed ClipSpy, and started to dynamically debug the clipboard’s data handling that is done inside rdpclip.exe.
These are our conclusions regarding the data flow in an ordinary “Copy & Paste” operation in which a file is copied from the server to the client:
Path Traversal over the shared RDP clipboard
If we look back on the steps performed on the received clipboard data, we notice that the client doesn’t verify the received Fgd blob that came from the RDP server. And indeed, if we modify the server to include a path traversal path of the form: ..\canary1.txt, ClipSpy shows us (see Figure 9) that it was stored “as is” on the client’s clipboard:
Figure 9: Fgd with a path-traversal was stored on the client’s clipboard
In Figure 10, we can see how explorer.exe treats a path traversal of ..\filename.txt:
Figure 10: Fgd with a path-traversal as explorer.exe handles it
Just to make sure, after the “paste” in folder “Inner”, the file is stored to “Base” instead:
Figure 11: Folders after a successful path traversal attack
And that’s practically it.
If a client uses the “Copy & Paste” feature over an RDP connection, a malicious RDP server can transparently drop arbitrary files to arbitrary file locations on the client’s computer, limited only by the permissions of the client. For example, we can drop malicious scripts to the client’s “Startup” folder, and after a reboot they will be executed on his computer, giving us full control.
Note: In our exploit, we simply killed rdpclip.exe, and spawned our own process to perform the path traversal attack by adding additional malicious file to every “Copy & Paste” operation. The attack was performed with “user” permissions, and does not require the attacker to have “system” or any other elevated permission.
Here is a video of our PoC exploit:
Taking it one step further
Every time a clipboard is updated on either side of the RDP connection, a CLIPRDR_FORMAT_LIST message is sent to the other side, to notify it about the new clipboard formats that are now available. We can think of it as a complete sync between the clipboards of both parties (except for a small set of formats that are treated differently by the RDP connection itself). This means that our malicious server is notified whenever the client copies something to his “local” clipboard, and it can now query the values and read them. In addition, the server can notify the client about a clipboard “update” without the need for a “copy” operation inside the RDP window, thus completely controlling the client’s clipboard without being noticed.
Scenario #1:
A malicious RDP server can eavesdrop on the client’s clipboard – this is a feature, not a bug. For example, the client locally copies an admin password, and now the server has it too.
Scenario #2:
A malicious RDP server can modify any clipboard content used by the client, even if the client does not issue a “copy” operation inside the RDP window. If you click “paste” when an RDP connection is open, you are vulnerable to this kind of attack. For example, if you copy a file on your computer, the server can modify your (executable?) file / piggy-back your copy to add additional files / path-traversal files using the previously shown PoC.
We were able to successfully test this attack scenario using NCC’s .NET deserialization PoC:
Note: The content of the synced clipboard is subject to Delayed Rendering. This means that the clipboard’s content is sent over the RDP connection only after a program actively asks for it, usually by clicking “paste”. Until then, the clipboard only holds the list of formats that are available, without holding the content itself.
Disclosure Timeline
Microsoft’s Response
During the responsible disclosure process, we sent the details of the path traversal in mstsc.exe to Microsoft.
This is Microsoft’s official response:
“Thank you for your submission. We determined your finding is valid but does not meet our bar for servicing. For more information, please see the Microsoft Security Servicing Criteria for Windows (https://aka.ms/windowscriteria).”
As a result, this path traversal has no CVE-ID, and there is no patch to address it.
Conclusion
During our research, we found numerous critical vulnerabilities in the tested RDP clients. Although the code quality of the different clients varies, as can be seen by the distribution of the vulnerabilities we found, we argue that the remote desktop protocol is complicated, and is prone to vulnerabilities. As we demonstrated in our PoCs for both Microsoft’s client and one of the open-sourced clients, a malicious RDP server can leverage the vulnerabilities in the RDP clients to achieve remote code execution over the client’s computer.
As RDP is regularly used by IT staff and technical workers to connect to remote computers, we highly recommend that everyone patch their RDP clients. In addition, due to the nature of the clipboard findings we showed in Microsoft’s RDP client, we recommend users to disable the clipboard sharing channel (on by default) when connecting to a remote machine.
Recommendation for Protection
Check Point recommends the following steps in order to protect against this attack:
Appendix A – CVEs found in rdesktop:
Appendix B – CVEs found in FreeRDP: