by Mitja Kolsek, the 0patch Team
Update 8/11/2021-A: August 2021 Windows Updates brought a fix for PetitPotam, which, in contrast to our patch that fixes an impersonation issue and keeps EfsRpcOpenFileRaw request functional, disables the EfsRpcOpenFileRaw request. CVE-2021-36942 was assigned to this vulnerability. More details below in the Microsoft's Patch section.
Update 8/11/2021-B: Neither Microsoft's August fix nor our micropatch seem to have
covered all PetitPotam affected code. Both fixed the anonymous attack
vector but we're investigating additional authenticated paths now and
looking for the best way to patch that too. The most effective PetitPotam mitigation currently remains this RPC filter on all Domain Controllers, although it may be an overly broad measure and could break something, so proceed with caution.
Update 8/19/2021: After further analysis of additional PetitPotam attack
vectors, we created additional micropatches that block all
these vectors. Today's PetitPotam patches are written for executables
from August 2021 Windows Updates, which means you have to have these
updates installed (i.e., fully updated Windows as of this writing) in
order to have them applied.
Update 9/15/2021: September 2021 Windows Updates did not bring any changes regarding the new PetitPotam attack vectors, so our micropatches remain free.
Update 12/21/2021: Microsoft provided an official fix
for this issue on December 14, which addresses the remaining attack vectors. Our
associated micropatches thus ceased being free and now require a PRO
license.
Update 6/27/2022: While Microsoft only fixed the anonymous attack vector, we decided to also address the authenticated attack vector. We therefore ported our patches for this issue to current
versions of supported Windows platforms. Given that Microsoft does not
plan to patch authenticated credentials relaying issues, these patches are now
available only to PRO and Enterprise accounts.
Update 6/3/2024: It came to our attention that PetitPotam can also be exploited against Windows Workstations, not just Servers. We therefore issued patches for all security-adopted as well as still-supported Windows versions, which we'll keep porting to relevant DLLs as they get updated.
Wow, we're busy these days. Just yesterday we issued micropatches for the "Malicious Printer Driver" 0day, and today we're fixing a critical remote code execution issue that allows an anonymous attacker to take over a Windows Domain Controller: the infamous "PetitPotam" bug.
PetitPotam was discovered by security researcher topotam, who published their proof-of-concept on Github on July 20, 2021. There is no official vendor patch for it at the time of this writing; in fact, Microsoft's support article implies they do not consider this a vulnerability but rather a mis-configuration, and provides some generic mitigations that do not address the root issue.
As usually, CERT/CC vulnerability note by Will Dormann nicely explains the vulnerability and an exploit chain leading to a complete domain takeover. The main problem is that any user - even anonymous - can force a domain controller to send NTLM credentials of its computer account to attacker's server, where these can be received and then relayed to another service in the domain to make a malicious privileged request.
Analysis
We took a look at what goes on in the code when an EfsRpcOpenFileRaw request is received by the server. It is function EfsRpcOpenFileRaw_Downlevel in efslsaext.dll that processes this request. This function has most of its code enclosed in an impersonation block between a call to RpcImpersonateClient and a call to RpcRevertToSelf. Code inside this block is being executed under the identity of the requesting entity (in our case, attacker), while code outside executes as Local System, i.e., the computer account.
Unfortunately, function EfsRpcOpenFileRaw_Downlevel, outside the impersonation block, makes a call to EfsGetLocalFileName, which tries to open the attacker-supplied UNC path. By doing so, it sends local computer's NTLM credentials inside the SMB request to the remote network share. If the attacker is waiting on the other end, they get these credentials.
Let's take a look at relevant parts of function EfsRpcOpenFileRaw_Downlevel:
|
Beginning of function EfsRpcOpenFileRaw_Downlevel, with the call to EfsGetLocalFilename being called without impersonation |
|
Continuation of function EfsRpcOpenFileRaw_Downlevel |
Note that only this call to EfsGetLocalFileName is non-impersonated, while core EFSRPC functionality executes under requester's identity. This means that anonymous or unprivileged user cannot remotely execute EFSRPC functions such as reading or creating arbitrary network files.
Micropatch
Our micropatch extends the impersonation block such that it now encloses the previously un-impersonated call to EfsGetLocalFileName; as a result, the SMB request which this function triggers contains attacker's NTLM credentials instead of computer account's. Therefore, in case of an anonymous request the attacker gets credentials of the ANONYMOUS LOGON user (which are of no use), and if they use credentials of a Windows domain user, the acquired NTLM credentials will be of that same user (which they already have).
The patch contains two patchlets, one starting impersonation by calling RpcImpersonateClient, and another stopping impersonation by calling RpcRevertToSelf.
MODULE_PATH "..\Affected_Modules\efslsaext.dll_10.0.17763.1075_64bit_WinSrv2019-u202107\efslsaext.dll"
PATCH_ID 663
PATCH_FORMAT_VER 2
VULN_ID 7174
PLATFORM win64
patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x280c
N_ORIGINALBYTES 5
JUMPOVERBYTES 0
PIT rpcrt4!0x53370,efslsaext!0x288c
;0x53370 -> RpcImpersonateClient
;0x288c -> Error block
code_start ;Injected at the top of the block containing
EfsRpcGetLocalFileName, in the EfsRpcOpenFileRaw_Downlevel
function
mov rcx, 0 ;Set rcx for RpcImpersonateClient to 0, so it
impersonates the current client
call PIT_0x53370 ;Call RpcImpersonateClient
mov rbx, rax ;Move the result to rbx, so it can be used for error
reporting in case of failure
cmp rax, 0 ;Check if impersonation failed
jne PIT_0x288c ;If failed, jump to error block
code_end
patchlet_end
patchlet_start
PATCHLET_ID 2
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x288c
N_ORIGINALBYTES 5
JUMPOVERBYTES 0
PIT rpcrt4!0x563b0
;0x563b0 -> RpcReverToSelf
code_start ;Injected at the top of the block right after the
RpcRevertToSelf call, in the EfsRpcOpenFileRaw_Downlevel function
call PIT_0x563b0 ;Call RpcRevertToSelf to stop impersonating
code_end
patchlet_end
Let's look at the difference between running the PetitPotam tool against a fully updated Windows Server without and with 0patch.
Without 0patch
Let's see which user executes the call to EfsGetLocalFileName:
As expected, it's Local System. And the PetitPotam tool, chained with Active Directory Certificate Server produces domain controller's certificate:
With 0patch
Let's see which user executes the call to EfsGetLocalFileName this time:
Good, it's the Anonymous Logon user, which is useless to the attacker. Consequently, the PetitPotam attack doesn't work anymore:
Patch Availability
This micropatch was written for:
- Windows Server 2019 (updated with July 2021 Updates)
- Windows Server 2016 (updated with July 2021 Updates)
- Windows Server 2012 R2 (updated with July 2021 Updates)
- Windows Server 2008 R2 (updated with January 2020 Updates, no Extended Security Updates)
Our tests indicate that Windows Server 2012 (non R2), Windows Server 2008 (non R2) and Windows Server 2003 are not affected by this issue.
Micropatches for this vulnerability are, as always, automatically downloaded and applied to all affected computers (unless your policy prevents that), and will be free until Microsoft has
issued an official fix. If you want to use them, create a free account
at 0patch Central, then install and register 0patch Agent from 0patch.com. Everything else will happen automatically. No computer reboots will be needed.
Compatibility note: Some Windows 10 and Server systems exhibit occasional timeouts in the Software Protection Platform Service (sppsvc.exe) on a system running 0patch Agent. This looks like a bug in Windows Code Integrity
mitigation that prevents a 0patch component to be injected in the
service (which is okay) but sometimes also does a lot of seemingly
meaningless processing that causes process startup to time out. As a
result, various licensing-related errors can occur. The issue, should it
occur, can be resolved by excluding sppsvc.exe from 0patch injection as described in this article.
Update 8/19/2021: Microsoft's August 2021 updates brought a functionally similar fix as our micropatch, but since other attack vectors were subsequently discovered, we have issued additional micropatches that apply on top of August 2021 Windows executables. In order to use them, you have to have August 2021 Windows Updates applied. In addition, we have found Windows Server 2012 to be affected to these additional vectors and have also covered this Windows version with our new micropatches.
[Update 8/11/2021: added section Microsoft's Patch]
Microsoft's Patch
August 2021 Windows Updates brought Microsoft's official fix for this issue. The associated documentation states: "The EFS API OpenEncryptedFileRaw(A/W),
often used in backup software, continues to work in all versions of
Windows (local and remote), except when backing up to or from a system
running Windows Server 2008 SP2. OpenEncryptedFileRaw will no longer
work on Windows Server 2008 SP2. Note: If you are unable to use backup software on
Windows 7 Service Pack 1 and Windows Server 2008 R2 Service Pack 1 and
later, after installing the updates that address this CVE, contact the
manufacturer of your backup software for updates and support."
Let's take a look at this fix.
Microsoft's fix is in the same function as our micropatch ( EfsRpcOpenFileRaw_Downlevel in efslsaext.dll), but it sabotages the function so it doesn't work anymore. We actually also sometimes sabotage an entire function if it seems that could affect such a small amount of users that the benefits would outweigh the risk. In fact, we were initially inclined to do it here too as we were unable to find any backup product or mechanism that would be using this function - but then decided to rather fix the obvious bug we had noticed, and keep the function "alive".
Note that Microsoft's fix also includes a hidden undocumented feature: instead of outright sabotaging OpenEncryptedFileRaw, the fix checks an undocumented registry value AllowOpenRawDL (DWORD) under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EFS; if this value exists and is equal to 1, OpenEncryptedFileRaw works as before. Therefore, if Microsoft's fix broke your backup, you can disable it using this value, but doing so will make you vulnerable to the PetitPotam attack.
We find this Microsoft's fix to be appropriate and therefore do not plan to port our PetitPotam micropatch to the August 2021 version of efslsaext.dll unless 0patch users come complaining the fix broke their backup. We also invite any Windows users whose backup got broken by August 2021 Windows Update to contact us at sales@0patch.com.
Update 8/11/2021: Neither Microsoft's August fix nor our micropatch seem to have
covered all PetitPotam affected code. Both fixed the anonymous attack
vector but we're investigating additional authenticated paths now and
looking for the best way to patch that too.
Update 8/19/2021: Our new micropatches released today address these additional attack vectors.
Credits
We'd like to thank topotam for sharing details about this vulnerability, and Will Dormann, Benjamin Delpy and Kevin Beaumont for sharing lots of useful insights and context that helped us understand this vulnerability and create this micropatch to protect users.
Please revisit this blog post for updates or follow 0patch on Twitter.