Blog
May 17, 2023
5 min read

DLL Hijacking Strikes Back: Exploiting Windows on ARM RDP Client (CVE-2023-24905)

Written By

Dor Dali

As technology advances and new devices with the latest operating systems are introduced, users have come to expect heightened security and improved performance. However, old vulnerabilities can still find their way into new systems, posing risks to users.  

Recently, during our research on Remote Desktop Protocol (RDP) here at Cyolo, I discovered that a classic technique, DLL Hijacking, can be used to exploit the RDP Client — mstsc.exe on Windows on ARM devices. I will delve into my findings and their significance in this blog post.  

DLL Hijacking: The Blast from the Past 

During my investigation of the RDP client, I used one of my favorite tools, procmon.exe, to observe that when a user opens a .rdp file, the system attempts to load a non-existent DLL called fxsresm.dll from the current working directory (CWD) instead of the Windows (operating system) directory. This makes it vulnerable to a DLL Hijacking attack. 

Image 1: mstsc.exe attempt to load a non-existent DLL from the current working directory

Having some prior experience with this kind of attack, I jumped straight into exploiting DLL Hijacking by following the usual steps. I created my own DLL with a command to open calc.exe in its DllMain() function and placed it in the same folder as the .rdp file. Although the system loaded my DLL, the Windows calculator never popped up as I expected it to. 

To uncover more details, I fired up windbg and attempted to find the place where the RDP client loads the fxsresm.dll. After locating it, I discovered two interesting facts: 

  1. The RDP client is using the LoadLibraryExW system call to load the DLL. 

  2. The flags that are being sent to the system call are LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_IMAGE_RESOURCE and LOAD_WITH_ALTERED_SEARCH_PATH

Image 2: The X2 register holds the value 0x2a which is combination of the said flags

These findings reveal that the system attempts to load the DLL as a non-executable resource and thus never called the DllMain() function in my own crafted Dll. 

Upon examining the system call documentation, I came across a critical statement: "If the module is being loaded as a datafile and the relative path begins with "." or "..", the relative path is treated as an absolute path."

This clarified why the DLL was loaded from the current working directory (CWD) instead of following the standard search path.

Determined to understand the extent of the vulnerability, I decided to investigate the nature of the fxsresm.dll file. A quick Google search led me to a DLL information website that revealed this file as a resource-only DLL, containing nothing but strings and icons. 

With this understanding it became clear that we could spoof resources loaded by changing the icons and strings in the DLL, which would present an interesting phishing attack vector. In this scenario, an attacker could manipulate the visual elements, such as icons and strings within the DLL, to mislead the user into performing certain actions. For example, by changing the icons and strings, an attacker could make an error message look like a legitimate system notification, or transform a dangerous action (such as downloading a file) into something seemingly harmless (like performing a software update). However, this still did not seem like the full extent of the vulnerability. 

From Phishing to RCE

As I examined the strings within the DLL, I stumbled upon a familiar pattern that recalled another long-standing attack technique. Some of the strings contained formatting parameters, such as %s and %u. This was an indication that the strings from the DLL are being used in a printf-style function, which is a typical scenario for a format string vulnerability. In these cases, an attacker can use format string specifiers to read from or write to the memory of the running process. And that is when it hit me  — the opportunity to create a powerful chained attack was right in front of me.

Image 3: Several exmples of formatted strings from the fxsresm.dll

By crafting a malicious DLL with harmful format strings and coupling it with a legitimate RDP file, it's possible to manipulate the memory layout of the program and even achieve Remote Code Execution (RCE) on the affected system. 

To exploit this attack, all an attacker needs to do is create a maliciously crafted DLL along with a legitimate RDP file and strategically place it where the target is likely to execute it. This could be in a commonly accessed network share folder, where unsuspecting users might inadvertently launch the RDP file. 

Given the widespread use of RDP files across various Windows versions, my next goal was to determine which Windows versions were susceptible to this attack. In this portion of my investigation I discovered something quite interesting — I could not replicate the vulnerability on any non-ARM Windows version. This implies that the vulnerability is exclusive to Windows ARM devices. However, with the growing number of ARM devices, such as laptops, internet of things (IoT), and industrial control systems (ICS) devices, the potential risk remains significant.  

Reporting to MSRC: A Responsible Disclosure 

Considering the potential implications of this vulnerability and its possible effects on impacted devices, coupled with the relatively low complexity of this attack, my team made the responsible decision to share our findings with the Microsoft Security Response Center (MSRC) before developing a fully working exploit. As always at Cyolo, our priority is to contribute and help the wider ecosystem to ensure the security of users and to prevent any potential misuse of this (and any other) vulnerability. 

Upon reviewing our report, the MSRC team concurred with our assessment regarding the Remote Code Execution potential and promptly worked on a fix to address the issue. Microsoft released a security patch on May 9, 2023 and assigned CVE-2023-24905, effectively mitigating the risks associated with this vulnerability. 

Disclosure Timelines 

Here are the timelines for the vulnerability disclosure: 

Jan 23, 2023 — Vulnerability Discovered and Reported through MSRC portal

Jan 24, 2023 — MSRC ticket was moved to Review/Repro

Mar 22, 2023 — MSRC agreed on the ticket and status changed to Develop

May 9, 2023 — Public release of the security advisory

Dor Dali

Author

Dor Dali is Head of Security Research at Cyolo. He is a cybersecurity expert with years of experience in security research and security program management. Dor holds a deep understanding and knowledge in the fields of web applications, product, and infrastructure security and is very enthusiastic about everything related to fixing security problems.

Subscribe to Our Newsletter