Microsoft Windows - NtUserGetClipboardAccessToken Token Leak (MS15-023)

EDB-ID:

38199




Platform:

Windows

Date:

2015-09-15


Source: https://code.google.com/p/google-security-research/issues/detail?id=461

Windows: NtUserGetClipboardAccessToken Token Leak Redux
Platform: Windows 8.1 Update, Windows 10 Build 10130
Class: Security Bypass/EoP

Summary:
The NtUserGetClipboardAccessToken win32k system call exposes the access token of the last user to lower-privileged users. It can also be used to open an anonymous impersonation thread token which normally OpenThreadToken shouldn't be able to do. This is a bypass of the fix for CVE-2015-0078.

Description:

This was supposedly fixed as CVE-2015-0078 in MS15-023 to prevent access to the token from any process running below medium IL. The check is roughly:

if(IsImmersiveBroker() || CheckAccessForIntegrityLevelEx(0x2000)) {
    ObOpenObjectByPointer(WinStationObject->ClipboardAccessToken, Access, TokenHandle);
}

This is possible to bypass because IsImmersiveBroker level is trivial to get. It seems Win32k sets the appropriate Win32Process flag when first initializing the process and converting it to a GUI thread. If the executable is signed by a Microsoft certificate and has a specially named section of “.imrsiv” the flag will be set, however this will be done regardless of the IL of the process. Therefore you can create a process using one of the pre signed executables, such as explorer.exe, RuntimeBroker.exe or LicensingUI.exe then inject a DLL into the process. This allows you to bypass the check and capture the token.

I’ve had a quick look at what else might be exploitable from being able to get IsImmersiveBroker to return true. Nothing stands out but it’s probably worth restricted the IL level of processes allowed to get this flag set.

Proof of Concept:

I’ve provided a PoC which will capture any token currently on the clipboard that it can access. It creates an instance of LicensingUI.exe and injects a DLL into it. Note the built executables are for x64 Windows, you'll need to rebuild to test on 32 bit. The password for the archive is "password".

1) Copy the PoC to a directory, including the executable and the DLL
2) Execute the Poc_NtUserGetClipboardAccessToken_SecurityBypass.exe as a low integrity process. You can do this by marking the executable file with low IL using icacls or by using psexec. 
3) Perform a clipboard operation, for example select some text and copy it to the clipboard
4) The PoC should show it has opened a token by opening a message dialog, if you inspect the tokens it’s likely to show a primary token has been captured with medium IL. 

Expected Result:
It shouldn’t be possible to capture the token.

Observed Result:
The token was captured in the low IL process.

Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/38199.zip