Windows: NtImpersonateAnonymousToken AC to Non-AC EoP
Platform: Windows 10 1703 and 1709
Class: Elevation of Privilege
Summary:
The check for an AC token when impersonating the anonymous token doesn’t check impersonation token’s security level leading to impersonating a non-AC anonymous token leading to EoP.
Description:
There's a missing check for impersonation level in NtImpersonateAnonymousToken when considering if the caller is currently an AC. This results in the function falling into the restricted token case if the caller is impersonating a non AC token at identification or below. Some example code is shown highlighting the issue.
SeCaptureSubjectContext(&ctx);
PACCESS_TOKEN token = ctx.ClientToken;
if (!ctx.ClientToken) <--- Should check the token's impersonation level here, and fallback to the PrimaryToken.
token = ctx.PrimaryToken;
if (token->Flags & 0x4000) {
// ... Impersonate AC anonymous token.
} else if (!SeTokenIsRestricted(PsReferencePrimaryToken())) { <-- AC PrimaryToken isn't restricted so this check passes
// ... Impersonate normal anonymous token.
}
For example when using a split-token admin you can trivially get the linked token and impersonate that. As an AC token isn't restricted this results in impersonating the normal anonymous token which is arguably less restricted than the AC token in some cases and is certainly less restricted than the anonymous AC token which is normally created using SepGetAnonymousToken. For example you can open objects with a NULL DACL if you can traverse to them or open devices which would normally need the special AC device object flag for traversal across the object namespace. You can also access the anonymous token's device map and modify it, potentially leading to bypass of symbolic link protections in certain cases.
Proof of Concept:
I’ve provided a PoC as a C# project. The PoC will respawn itself as the Microsoft Edge AC and then execute the exploit. You must run this as a UAC split token admin. Note that this ISN’T a UAC bypass, just that a split-token admin has a trivial way of getting a non-AC token by requesting the linked token.
1) Compile the C# project. It will need to grab the NtApiDotNet from NuGet to work. Ensure the main executable and DLLs are in a user writable location (this is needed to tweak the file permissions for AC).
2) Execute the PoC as normal user level split-token admin.
3) Once complete a dialog should appear indicating the operation is a success.
Expected Result:
The AC anonymous token is impersonated, or at least an error occurs.
Observed Result:
The Non-AC anonymous token is impersonated.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/43515.zip