Wednesday, June 1, 2022

Free Micropatches For "Follina" Microsoft Diagnostic Tool Remote Code Execution 0day (CVE-2022-30190)


by Mitja Kolsek, the 0patch Team


[Update 6/2/2022: Additional patches were issued for Windows Servers]

[Update 15/6/2022: Microsoft issued an official patch for this vulnerability. They implemented functionally the same security check in msdt.exe as we had in sdiagnhost.exe, namely checking for the presence of "$(" in the user-provided path. With official patches being available, our micropatches for this vulnerability are no longer free but require PRO or Enterprise license.] 

It was a quiet Sunday evening with a promise of enjoying a few chapters of The End of Everything by Katie Mack (an excellent book if long-term planning is your thing) when a tweet from Kevin Beaumont came by, opening with "This is a nice find." Knowing Kevin - at lest on Twitter - this often translates to "It's going to be a long night."

The tweet quoted by Kevin was actually from Friday, where nao_sec stated that an "Interesting maldoc was submitted from Belarus. It uses Word's external link to load the HTML and then uses the "ms-msdt" scheme to execute PowerShell code."

A remote code execution vulnerability was obviously spotted getting exploited in the wild. The vulnerability, quickly confirmed by many researchers using various versions of fully updated Microsoft Office, allowed a Word document to execute arbitrary PowerShell commands on the computer with little user interaction. It utilized the "ms-msdt:" URL scheme registered by default on all modern Windows versions to execute the Diagnostic Tool msdt.exe with malicious arguments.

It all looked very similar to CVE-2021-40444, where a malicious Word document would load a remote HTML template, which in turn opened a special type of URL to launch attacker's executable. But it was even "better" because no malicious executable needed to be dropped on victim's computer to be subsequently executed, as PowerShell commands have all the power the attacker ever needs.

For more details about the context, see Kevin's article which keeps getting updated as new data becomes available. Kevin is an unofficial authority for naming 0days and he dubbed this one "Follina"; Microsoft subsequently assigned it CVE-2022-30190 after having rejected a submission by researcher CrazymanArmy as "not a security-related issue."

The Vulnerability

This issue is widely considered a vulnerability in Office, due to Office documents being an efficient vehicle for delivering a "ms-msdt:" URL and having it rendered without restrictions with user's identity. However, we believe the actual problem to be the PowerShell command injection accessible via the IT_BrowseForFile argument of msdt.exe application, as first noted by Alec Wiese. While allowing an Office document to launch an application via special URL scheme may be providing an unneeded attack surface (which may lead to additional similar 0days being discovered in the future), this would all have been a non-issue without the command execution.

So where does the PowerShell command execution come from? A minimized POC triggering the vulnerability contains this parameter for msdt.exe:


The IT_BrowseForFile value contains a PowerShell subexpression "$(calc)", which results in executing the "calc" command in PowerShell, and that launches the Calculator app. Now why does this get executed at all? To find the answer, we need to see where the data passed to msdt.exe travels. One could use Process Monitor and debugger to find out, but we decided to use Tetrane REVEN, a powerful tool for reverse engineering which often saves us a lot of time with vulnerability analyses.


Tetrane REVEN during our analysis of this vulnerability, making it easy to trace data, inspect memory and find a good location for patching

Using REVEN, we could see the value in question traveling:

  1. from msdt.exe via an ALPC call to
  2. DCOM Server Process Launcher (hosted inside a svchost.exe), which launches
  3. sdiagnhost.exe that receives the data from msdt.exe, and passes it on to a RunScript call to execute
  4. PowerShell script TS_ProgramCompatibilityWizard.ps1 (in folder C:\Windows\diagnostics\system\PCW), which - inadvertently - gets the attacker's PowerShell subexpression executed by putting it in an Invoke-Expression call.


Note that TS_ProgramCompatibilityWizard.ps1 seems to be very much aware of the possibility of a "PowerShell subexpression injection" and dutifully sanitizes user-provided data in many places by replacing all occurrences of "$" with "`$", for example:

$appName = $choice["Name"].Replace("$", "`$")

Unfortunately, the one in IT_BrowseForFile argument slips by and still gets executed.


Our Micropatch

It would be by far the simplest for us to just disable msdt.exe by patching it with a TerminateProcess() call. However, that would render Windows diagnostic wizardry inoperable, even for non-Office applications. Another option was to codify Microsoft's recommendation into a patch, effectively disabling the ms-msdt: URL protocol handler.

But when possible, we want to minimize our impact outside of removing the vulnerability, so we decided to place our patch in sdiagnhost.exe before the RunScript call and check if the user-provided path contains a "$(" sequence - which is necessary for injecting a PowerShell subexpression. If one is detected, we make sure the RunScript call is bypassed while the Diagnostic Tool keeps running.

In IDA, our patch looks like this (green blocks are our code, blue block is original code relocated to a trampoline, value of rdx is used to emulate an error):

And a video of our patch in action. Since this vulnerability can be triggered via different vectors (not just Office documents), the video demonstrates how 0patch blocks an attack via msdt.exe, regardless of how msdt.exe got launched.

Note that sdiagnhost.exe, which is where our patch resides, has been last modified in Dec 2019 or even earlier on all patched Windows versions (except Windows 11, where it's naturally younger). This means our patch will be applied even if you have skipped many Windows Update cycles.

Also Note that it doesn't matter which version of Office you have installed, or if you have Office installed at all: the vulnerability could also be exploited through other attack vectors. That is why we also patched Windows 7, where the ms-msdt: URL handler is not registered at all.

Micropatch Availability

Since this is a "0day" vulnerability with no official vendor fix available, we are providing our micropatches for free until such fix becomes available.

Micropatches were written for: 

  1. Windows 11 v21H2
  2. Windows 10 v21H2
  3. Windows 10 v21H1
  4. Windows 10 v20H2
  5. Windows 10 v2004
  6. Windows 10 v1909
  7. Windows 10 v1903
  8. Windows 10 v1809
  9. Windows 10 v1803
  10. Windows 7
  11. Windows Server 2008 R2
  12. Windows Server 2012
  13. Windows Server 2012 R2
  14. Windows Server 2016
  15. Windows Server 2019 

These micropatches have already been distributed to all online 0patch Agents. If you're new to 0patch, create a free account in 0patch Central, then install and register 0patch Agent from Everything else will happen automatically. No computer reboot will be needed.

To learn more about 0patch, please visit our Help Center

We'd like to thank nao_sec for publishing exploitation details, which allowed us to reproduce the vulnerability and create a micropatch, and all other security researchers who have shared their findings with public or privately with us. We also encourage security researchers to privately share their analyses with us for micropatching.


No comments:

Post a Comment