In this blog post, I’ll discuss my analysis of CVE-2023-36563, a Microsoft WordPad Information Disclosure Vulnerability, from initial patch diff to working exploit. Then, I’ll discuss detection and mitigation strategies for preventing exploitation of this vulnerability.
CVE-2023-36563 Overview
Summary
CVE-2023-36563’s flaw lies within legacy functionality to convert an OLE 1 storage object (OLESTREAM) to the new IStorage format. By crafting a file with a malicious OLE 1 LinkedObject
, an attacker could coerce authentication to an untrusted server to steal NTLM hashes.
Inspiration
There were a few things that made this vulnerability stick out to me and inspired me to figure out how it worked:
- The vulnerability was added to CISA’s Known Exploited Vulnerabilities Catalog, meaning someone was able to exploit this vulnerability in the wild.
- The “information disclosure” referred to a victim’s NTLM hashes, which can be very practically abused using NTLM relay attacks.
- The vulnerability is triggered by opening a malicious file with WordPad, which is very applicable for phishing and red team operations.
- It’s WordPad, and it’s hilarious that this vulnerability was announced right as WordPad is being deprecated
Technical Analysis
When trying to understand how recently released (or N-day) vulnerabilities work, performing a binary patch diff is an enormous help. In essence, we compare the binary instructions of a program using software like Bindiff before and after an update is applied. This gives us vital hints regarding fixes that occurred during a patch.
During my analysis, I reminded myself that this vulnerability resulted in NTLM hash disclosures. This heavily suggested that the vulnerability had something to do with making a web request or accessing a resource, since such operations can trigger an NTLM challenge-response.
Additionally, the CVE mentioned that the vulnerability was triggered by opening a malicious file in WordPad, so I would likely need to get familiar with the RTF file type.
WordPad.exe
Before Patch MD5: bd05d1b9fba2f5f1db6fbb59d3a78d84
After Patch MD5: e46d2a1e4836b78d00eeccc0e1db0f52
Modified Functions
I figured the wordpad.exe
binary was a great place to start patch diffing. Bindiff
identified several interesting functions that were modified by the patch. The one that interested me most was the LoadImageResource
function, which sounded like it might handle retrieving an image within a document.
This ended up being a red herring. I set a breakpoint on the function in windbg
and triggered it when hovering over an icon within WordPad that loaded several preview images of bullet points. Thus, it seemed to me like the function handled loading a resource from within the WordPad executable itself–not something we’d be able to easily exploit.
shell\shell32\netfldrp_ui.h(83)\SHELL32.dll!00007FFE78FA87DF: (caller: 00007FFE7614F490) ReturnHr(5) tid(1184) 80004001 Not implemented
(1498.11d4): Unknown exception - code 000006ba (first chance)
(1498.11d4): Unknown exception - code 000006ba (first chance)
ModLoad: 00007ffe`6c550000 00007ffe`6c567000 C:\Windows\system32\OnDemandConnRouteHelper.dll
ModLoad: 00007ffe`404f0000 00007ffe`4053b000 C:\Windows\system32\ndfapi.dll
ModLoad: 00007ffe`6f970000 00007ffe`6f98f000 C:\Windows\system32\wdi.dll
Breakpoint 1 hit
wordpad!LoadImageResource:
New Functions
I also noticed that a new function was added called QueryConvertOLELinkCallback
, a wrapper that would call a provided callback function. This wrapper was called within one of WordPad’s main editing functions, as shown below. I wasn’t sure what this was used for quite yet, but I took note of it.
An OLE Primer
The QueryConvertOLELinkCallback
got me thinking that the vulnerability might have something to do with Microsoft’s Object Linking and Embedding (OLE) format. In essence, OLE allows for objects and files to be embedded within other files on Windows.
As a brief example of how OLE objects work, let’s examine a paint object embedded within an RTF file. To do this, we can pop open WordPad, select Insert Object
and Paintbrush Picture
. Then, we’ll be able to create a paint image in MsPaint and have it show up in the RTF file.
If we opened the RTF file in Notepad, we would notice an \objdata
tag containing hexadecimal data for the embedded object. More on this in just a bit.
OLE functionality has been extensively abused by attackers, especially within Rich Text Format (RTF) files, which happens to be the default file type for WordPad. OLE was even the culprit of the infamous Follina RCE vulnerability (CVE-2022-30190).
Much of OLE’s functionality is implemented by the ole32.dll
Windows library, so that seemed like a logical next place to explore. This is where things started to get interesting.
Ole32.dll
Before Patch MD5: 5151f3912370086a405a9a7070768f4b
After Patch MD5: 72907f2a113ebf319838f6276fbd0460
Modified Functions
The following functions were modified from the patch. The naming convention implies they perform some sort of OLE object conversion.
wConvertOLESTREAMToIStorage
OLESTREAMToGenericObject
OleConvertOLESTREAMToIStorage
OleConvertOLESTREAMToIStorageEx
New Functions
The patch added these new functions:
CheckOLELinkConversionRegistrySetting
FindStringInMultiString
IsAppExcludedFromOLELinkConversionRegistrySetting
OleConvertOLESTREAMToIStorage2
OleConvertOLESTREAMToIStorageEx2
The IsAppExcludedFromOLELinkConversionRegistrySetting
function instantly stuck out to me as an added check to determine whether some sort of OLE link should be processed.
Additionally, the addition of OleConvertOLESTREAMToIStorage2
and OleConvertOLESTREAMToIStorageEx2
was intriguing. Although it took a couple days after the patch, Microsoft added them to their official documentation. The function prototype looks like this:
HRESULT OleConvertOLESTREAMToIStorage2(
[in] LPOLESTREAM lpolestream,
[out] LPSTORAGE pstg,
[in] const DVTARGETDEVICE *ptd,
[in] DWORD opt,
[in] PVOID pvCallbackContext,
[in] OLESTREAMQUERYCONVERTOLELINKCALLBACK pQueryConvertOLELinkCallback
);
The last 3 arguments are new from the patch, and Microsoft’s description of them is shown below. An opt
flag could now be provided to “disable a linked object during conversion.” Additionally, a pQueryConvertOLELinkCallback
function pointer could be specified to determine whether a linked object should be converted or not. And remember, we noticed the QueryConvertOLELinkCallback
function specified in the patched version of WordPad. Coincidence? I think not!
Creating an Exploit
Things were now starting to make sense. Clearly, there was an unsafe conversion happening to an OLE LinkedObject
that coerced NTLM authentication to occur. It was time to craft a payload to trigger this.
Crafting the Payload
Remember that embedded paint object we created earlier? Let’s take a look at the hex bytes within the \objdata
tag. I created an 010 template based on Microsoft’s documentation of the OLE 1 format, so we could see what’s going on.
We have the OLE magic followed by a FormatID
field, which can have either the value 0x2
(as shown here) for an EmbeddedObject
, or 0x1
for a LinkedObject
. A LinkedObject
! We know from our previous analysis that this is the type of object that triggers this vulnerability.
Looking further at the documentation for a LinkedObject
, I found that if the OLE object was of type LinkedObject
, the TopicName
field should point to a UNC path for the linked file:
Now that sounded juicy. I went ahead and set the TopicName
to be a file on a remote SMB share that I controlled. I also had to modify the payload a bit to remove the NativeDataSize
and NativeData
fields, since the LinkedObject
structure did not contain them.
It was almost time to reap the benefits of my work.
The Mark of the Web
It is important to briefly discuss a concept on Windows known as the Mark of the Web (MOTW). Whenever a file is downloaded from a remote resource, Windows sets a specific flag on that file. The purpose is to indicate to applications that it should be treated with caution, since it is from an untrusted source. You can view this special flag by selecting a file’s Properties in Windows Explorer. Below shows the properties of my exploit file after I downloaded it from my remote server:
Applications such as Word, Excel, and yes, WordPad, are designed to open files with the MOTW flag set in safe mode, prompting a user before loading any external resources. This is because, on Windows, fetching remote resources can lead to authentication challenges which can disclose NTLM credentials. If this bit is not set, security is much more lax.
The point is, a document that does not have the MOTW bit set and causes a remote resource to be fetched is likely not exploiting a vulnerability. Therefore, it was important to test the RTF file I crafted with the MOTW set.
Exploitation
I downloaded my crafted RTF file from my web server and ensured the MOTW flag was set. Then, I spun up Responder on my remote server to listen for SMB resource requests. Next, I opened the crafted file in WordPad:
Note that WordPad showed an alert which might lead one to believe that external resource fetches were blocked. However, this was not the case, as WordPad happily attempted to authenticate to my rogue server:
As shown in the windbg
stack trace below, the file access resulted from the vulnerable OleConvertOLESTREAMToIStorage
function.
Success :)
Mitigation
Microsoft released a support article a few days after Patch Tuesday which provided mitigations for CVE-2023-36563.
Users can add the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\AppCompat\ OLELinkConversionFromOLESTREAMToIStorage
and set the DWORD value Disabled
to 0x00000001
, according to the document. Additionally, users can add applications they wish to allowlist for OLE link conversion to the ExclusionList
key value.
Additionally, users should be sure to apply the patch provided by Microsoft. I confirmed that my exploit did not function after patching my system.
Detection
Exploitation of this vulnerability requires opening an RTF file with a legacy OLE 1 LinkedObject
structure. You probably shouldn’t receive such a file for a legitimate reason unless you are communicating with a time traveler from the 1990’s. Additionally, a malicious LinkedObject
would need to contain a remote UNC path to exploit this vulnerability.
With this in mind, I created the following YARA rule. I am currently retro hunting with it on Virus Total as well as looking for threat actors currently using this vulnerability.
rule RTF_LinkedObject_UNC_Path {
meta:
description = "CVE-2023-36563: Detects and RTF with a LinkedObject containing a remote UNC path in TopicName"
author = "Dillon Franke"
reference = "CVE-2023-36563"
strings:
// Match the \objdata tag
$rtf_objdata = "\\objdata"
$rtf_header = { 7B 5C 72 74 } // "{\rt"
// // Match OLE version and FormatID for LinkedObject
$ole_header = "0105000001000000"
// // Match UNC path prefix
$unc_path_upper = { 35 43 35 43 } // "\\..." UNC path 5C5C
$unc_path_lower = { 35 63 35 63 } // "\\..." UNC path 5c5c
condition:
// File format should be RTF
$rtf_header at 0 and
// // Check for \objdata tag
$rtf_objdata and
// // // Check for header and UNC path after the \objdata tag
$ole_header in (@rtf_objdata..@rtf_objdata+0x50) and
$unc_path_lower in (@rtf_objdata..@rtf_objdata+0x400) or
$unc_path_upper in (@rtf_objdata..@rtf_objdata+0x400)
}
Thank You
Thanks for reading. I welcome any feedback and am always willing to discuss/collaborate on vulnerability research. Please reach out me @dillon_franke on Twitter, or via my contact page.