PoC (DoS) for CVE-2021-40449 - Win32k Elevation of Privilege Vulnerability (LPE)

Overview

CallbackHell

DoS PoC for CVE-2021-40449 (Win32k - LPE)

Description

CVE-2021-40449 is a use-after-free in Win32k that allows for local privilege escalation.

The vulnerability was found in the wild by Kaspersky.

The discovered exploit was written to support the following Windows products:

  • Microsoft Windows Vista
  • Microsoft Windows 7
  • Microsoft Windows 8
  • Microsoft Windows 8.1
  • Microsoft Windows Server 2008
  • Microsoft Windows Server 2008 R2
  • Microsoft Windows Server 2012
  • Microsoft Windows Server 2012 R2
  • Microsoft Windows 10 (build 14393)
  • Microsoft Windows Server 2016 (build 14393)
  • Microsoft Windows 10 (build 17763)
  • Microsoft Windows Server 2019 (build 17763)

However, this proof-of-concept is merely a DoS trigger meant to be used for security researchers and alike.

The PoC contains comments and a template ready to be used for fully exploiting the vulnerability.

Technical Writeup

I highly recommend reading Kaspersky's technical writeup before proceeding.

As mentioned in the technical writeup by Kasperky, the vulnerability exists in GreResetDCInternal. If an attacker hooks the user-mode callback DrvEnablePDEV, which is called during hdcOpenDCW, it is possible to destroy the original device context by calling ResetDC, which causes a use-after-free in the kernel when the user-mode callback returns.

The following pseudo-code is made partially from the leaked Windows XP source code and by reverse-engineering the latest (before the patch) GreResetDCInternal from Win32kfull.sys. The irrelevant parts have been removed with [...]. Look for the VULN: comments.

BOOL GreResetDCInternal(
    HDC hdc,
    DEVMODEW *pdmw,
    BOOL *pbBanding,
    DRIVER_INFO_2W *pDriverInfo2,
    PVOID ppUMdhpdev)
{
    // [...]
    HDC hdcNew;

    {
        // Create DCOBJ from HDC
        DCOBJ dco(hdc);

        if (!dco.bValid())
        {
            SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
        }
        else
        {
            // Create DEVOBJ from `dco`
            PDEVOBJ po(dco.hdev());

            // [...]

            // Create the new DC
            // VULN: Can result in a usermode callback that destroys old DC, which
            // invalidates `dco` and `po`
            hdcNew = hdcOpenDCW(L"",
                                pdmw,
                                DCTYPE_DIRECT,
                                po.hSpooler,
                                prton,
                                pDriverInfo2,
                                ppUMdhpdev);

            if (hdcNew)
            {
                po->hSpooler = NULL;

                DCOBJ dcoNew(hdcNew);

                if (!dcoNew.bValid())
                {
                    SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
                }
                else
                {
                    // Transfer any remote fonts

                    dcoNew->pPFFList = dco->pPFFList;
                    dco->pPFFList = NULL;

                    // Transfer any color transform

                    dcoNew->pCXFList = dco->pCXFList;
                    dco->pCXFList = NULL;

                    PDEVOBJ poNew((HDEV)dcoNew.pdc->ppdev());

                    // Let the driver know
                    // VULN: Method is taken from old (possibly destroyed) `po`
                    PFN_DrvResetPDEV rfn = po->ppfn[INDEX_DrvResetPDEV];

                    if (rfn != NULL)
                    {
                        (*rfn)(po->dhpdev, poNew->dhpdev);
                    }

                    // [...]
                }
            }
        }
    }

    // Destroy old DC
    // [...]
}

As can be seen from the pseudo-code, the old device context can be freed in a user-mode callback from the hdcOpenDCW call, and later on, the method DrvResetPDEV is retrieved from the old device context and called with (po->dhpdev, poNew->dhpdev). These two arguments can be controlled by the user, since they are returned from the user-mode callback DrvEnablePDEV for each device context, respectively. It is thus possible to call a kernel function with two user-controlled arguments.

Kaspersky mentions that the original exploit used GDI palette objects and a single kernel function call to achieve arbitrary memory read/write. From here, one could steal a privileged access token to gain SYSTEM privileges.

To create and hook a device context, one can do the following:

  • Find an available printer with EnumPrinters
  • Load the printer driver into memory with OpenPrinter, GetPrinterDriver and LoadLibraryExA
  • Get the printer driver's user-mode callback table with GetProcAddress and DrvEnableDriver
  • Unprotect the printer driver's user-mode callback table with VirtualProtect
  • Overwrite the printer driver's desired user-mode callback table entries
  • Create a device context for the printer with CreateDC(NULL, printerName, NULL, NULL)

We should now have a device context for a printer with hooked user-mode callbacks.

We're interested in only one hook, namely DrvEnablePDEV. This hook is interesting in two aspects: triggering the UAF and controlling the arguments, as described earlier. To trigger the UAF vulnerability, we will call ResetDC inside of the hook, which will destroy the old device context. When we return from the hook, we will still be inside the first GreResetDCInternal, which will shortly after get and call the function pointer for DrvResetPDEV from our old and destroyed device context with the two arguments that got returned from DrvEnablePDEV; the old and the new DHPDEV.

If your process is running with a medium integrity level, KASLR should not be an issue with the help of EnumDeviceDrivers and NtQuerySystemInformation.

PoC

./images/trigger.png ./images/trigger.png

References

You might also like...
CVE-2021-4034: Local Privilege Escalation in polkit's pkexec proof of concept
CVE-2021-4034: Local Privilege Escalation in polkit's pkexec proof of concept

CVE-2021-4034 Proof of Concept Qualys researches found a pretty cool local privilege escalation vulnerability in Polkit's pkexec: writeup, tweet. This

This repository contains an exploit of CVE-2021-4034, a local privilege escalation in pkexec

pwnkit (CVE-2021-4034) Privilege Escalation exploit sample This repository contains an exploit of CVE-2021-4034, a local privilege escalation in pkexe

CVE-2021-4034 Add Root User - Pkexec Local Privilege Escalation

CVE-2021-4034 CVE-2021-4034 Add Root User - Pkexec Local Privilege Escalation 根据CVE-2021-4034进行了加强,执行Exploit将会默认添加用户名rooter,密码[email protected],并且rooter用户将具

An exploit for CVE-2021-4034 aka Pwnkit: Local Privilege Escalation in polkit's pkexec

CVE-2021-4034 Exploit Usage $ git clone https://github.com/whokilleddb/CVE-2021-4034 $ cd CVE-2021-4034 $ make [!] CVE-2021-4034 Exploit By whokilledd

Plex media server local privilige escalation poc - CVE-2021-42835

Local Privilege PlEXcalasion - CVE-2021-42835 Plex Media Server for Windows prior to version 1.25.0.5282, vulnerable to Time Of Check Time Of Use (TOC

CVE-2021-4034 POC and Docker and Analysis write up
CVE-2021-4034 POC and Docker and Analysis write up

CVE-2021-4034 POC and Docker and Analysis write up

Proof of Concept (PoC) CVE-2021-4034
Proof of Concept (PoC) CVE-2021-4034

PwnKit-Exploit CVE-2021-4034 @c0br40x help to make this section in README!! Proof of Concept [email protected]:~/PwnKit-Exploit$ make cc -Wall exploit.

PoC for cve-2021-4034

cve-2021-4034 PoC for cve-2021-4034 Based on the PoC by https://haxx.in: https://haxx.in/files/blasty-vs-pkexec.c. Probably he's https://github.com/bl

CVE-2021-3156 POC and Docker and Analysis write up

CVE-2021-3156 [toc] 漏洞简介 漏洞编号: CVE-2021-3156 漏洞产品: sudo 影响版本: 1.8.2-1.8.31sp12; 1.9.0-1.9.5sp1 利用后果: 本地提权 源码获取: https://www.sudo.ws/getting/source/ 环境

Comments
  • Failed to allocate remote memory Windows 2019 17763

    Failed to allocate remote memory Windows 2019 17763

    Hi, I saw your project the other day and I decided to give it a try against a Windows Server 2019 (Build 17763) that I have set up. Every time I ran the exploit I got a [-] Failed to allocate remote memory[-] Failed to write to remote memory error and I was wondering was is it that makes it not work.

    The problem arises here: LPVOID buffer = VirtualAllocEx(proc, NULL, sizeof(payload), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    because the buffer is left blank therefore I get the error each time, but what could cause the allocation to fail?

    I'm trying to debug the problem, but I don't seem to be able to reach its solution.

    Any hints? Thanks so much.

    opened by MikosMotta 0
  • Exploit does not elevate privileges on Windows build 19042.746

    Exploit does not elevate privileges on Windows build 19042.746

    Hi,

    thank you for your work!

    The exploit does not elevate privileges on Windows build 19042.746 I tried to inject into explorer.exe for the last step and that does work for spawning the cmd, also all the steps before the injection do work. Injecting into winlogon.exe did not work as the privileges are not sufficient I guess. But once the cmd got spawned it has the context of the executing user and not system.

    What could be done to debug this or add functionality for Windows build 19042.746 ?

    Many thanks

    opened by 0xShkk 2
Owner
Oliver Lyak
Security Researcher
Previously known as @ollypwn
Oliver Lyak
win32k LPE bypass CVE-2021-1732

CVE-2022-21882 win32k LPE bypass CVE-2021-1732 Test only tested on windows 20h2 19042.1415 tested on windows 21H1 (not working) Download https://raw.g

null 6 Apr 12, 2022
My exploit for CVE-2021-40449, a Windows LPE via a UAF in win32kfull!GreResetDCInternal.

CVE-2021-40449 My exploit for CVE-2021-40449, a Windows LPE via a UAF in win32kfull!GreResetDCInternal. short wu along with the UAF vulnerabilty other

hakivvi 29 Sep 18, 2022
PoC for PwnKit: Local Privilege Escalation Vulnerability in polkit’s pkexec (CVE-2021-4034)

CVE-2021-4034 PoC for PwnKit: Local Privilege Escalation Vulnerability in polkit’s pkexec (CVE-2021-4034) https://seclists.org/oss-sec/2022/q1/80 http

Andris Raugulis 906 Sep 18, 2022
PoC for CVE-2021-28476 a guest-to-host "Hyper-V Remote Code Execution Vulnerability" in vmswitch.sys.

CVE-2021-28476: a guest-to-host "Microsoft Hyper-V Remote Code Execution Vulnerability" in vmswitch.sys. This is a proof of concept for CVE-2021-28476

Axel Souchet 208 Sep 15, 2022
Exploit for CVE-2021-40449

CVE-2021-40449 More info here: https://kristal-g.github.io/2021/11/05/CVE-2021-40449_POC.html Compiling I did a bit of a hack with the MinHook library

null 49 Jul 27, 2022
Local Privilege Escalation Edition for CVE-2021-1675

Local Privilege Escalation Edition of CVE-2021-1675/CVE-2021-34527 Local Privilege Escalation implementation of the CVE-2021-1675/CVE-2021-34527 (a.k.

Halil Dalabasmaz 330 Sep 9, 2022
CVE-2021-24084 Windows Local Privilege Escalation Left officially unpatched since 2020. Hence, its still a zero day

WindowsMDM-LPE-0Day Works best on Windows 11 CVE-2021-24084 Windows Local Privilege Escalation Left officially unpatched since 2020. Hence, its still

Exploit Blizzard 36 Aug 31, 2022
CVE-2021-4034 One day for the polkit privilege escalation exploit

CVE-2021-4034 One day for the polkit privilege escalation exploit Just execute make, ./cve-2021-4034 and enjoy your root shell. The original advisory

Davide Berardi 1.6k Sep 17, 2022
Self-contained exploit for CVE-2021-4034 - Pkexec Local Privilege Escalation

PwnKit Self-contained exploit for CVE-2021-4034 - Pkexec Local Privilege Escalation Usage Should work out of the box on Linux distributions based on U

Oliver Lyak 626 Sep 23, 2022