Microsoft Windows CVE-2018-8134 – Elevation of Privilege Exploit

Authors:James Forshaw           Risk:High

CVE:CVE-2018-8134              0day:Elevation of Privilege 

0day -id:0DAY-176187            Date:2018-05-16

Description

An elevation of privilege vulnerability exists in the way that the Windows Kernel API enforces permissions. An attacker who successfully exploited the vulnerability could impersonate processes, interject cross-process communication, or interrupt system functionality.

To exploit the vulnerability, a locally authenticated attacker could run a specially crafted application.

The security update addresses the vulnerability by helping to ensure that the Windows Kernel API properly enforces permissions.

Analysis

When a protected process is created it sets the protection inside the EPROCESS structure but also adds a special trust SID to the primary token as part of SeSubProcessToken. Where the process protection is used for things such as what access rights to other processes the trust SID is used for direct access checks where a security descriptor has a process trust label. A good example is the \KnownDlls object directory which is labeled as PPL-WinTcb to prevent tampering from anything not at that protection level.

This trust SID isn’t cleared during duplication so it’s possible for a non-protected process to open the token of a protected process and duplicate it with the trust SID intact. However using that token should clear the SID, or at least cap it to the maximum process protection level. However there’s a missing edge case, when setting a primary token through NtSetInformationProcess (specifically in PspAssignPrimaryToken). Therefore we can exploit this with the following from a normal non-admin process:

1) Create a protected process, werfaultsecure.exe is a good candidate as it’ll run PP-WinTcb. It doesn’t have to do anything special, just be created.
2) Open the process token (we get PROCESS_QUERY_LIMITED_INFORMATION) and duplicate it to a new primary token.
3) Create a new suspended process which will run the exploit code with the original token.
4) Set the protected process token using NtSetInformationProcess
5) Resume exploit process and do something which needs to pass the trust label check.

NOTE: There is also a related issue during impersonation and the call to SeTokenCanImpersonate. Normally the current process trust SID is checked against the impersonation token trust SID and if the process token’s is lower a flag is returned to the caller which resets the new token’s trust SID to the process one. This check occurs before the check for SeImpersonatePrivilege but _after_ the check for an anonymous token authentication ID. Therefore if you’re an admin you could craft a token with the anonymous token authentication ID (but with actual groups) and do a similar trick as with the process token to prevent the reset of the trust SID during impersonation. However I couldn’t find an obvious use for this as the trust label seems to be based on the minimum between the impersonation and process token’s trust SIDs and when impersonating over a boundary such as in RPC it looks like it gets reset to the process’ protection level. But might be worth cleaning this up as well if you’re there.

Exploit

I’ve provided a PoC as a C# project. It does the previous described trick to run a process which can then set the trust label on a new event object it creates (\BaseNamedObject\PPDEMO). If you run the poc with a command line parameter it will try and do the event creation but should print access denied.

1) Compile the C# project. It will need to grab the NtApiDotNet from NuGet to work.
2) Run the poc with no parameters as a normal user. It will capture the token and respawn itself to create the event.

Expected Result:
Setting the trust label returns access denied.

Observed Result:
The trust label is successfully set.

POC

https://bugs.chromium.org/p/project-zero/issues/attachment?aid=326574&signed_aid=H1OwoiSrQmhF3aCk6jVpUA==

Leave a Reply