Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cve-2019-1458_POC — POC for cve-2019-1458 | Kitploit
Tools/GitHubGitHub/piotrflorczyk/cve-2019-1458_poc
Vulnerability AnalysisExploitationReverse EngineeringLearning & EducationBinary Exploitation
GitHubpiotrflorczyk/cve-2019-1458_poc

cve-2019-1458_POC

POC for cve-2019-1458

View Repository
1815394 years agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2019-1458: Going from 'in the wild report' to POC

Intro

In December Kaspersky published a blogpost about [0day exploit used in the wild][1]. It piqued my interest because although they described how the exploit was working, they didn't provide any POC in their analysis. This is why I decided to try writing POC for this vulnerability based on Kaspersky's blogpost and patch analysis.
This post describes my journey doing that.

Information gathering:

First thing was to collect as much information about this vulnerability as I could. Reading through mentioned blogpost I extracted following information:

  • Vulnerability is related to window switching functionality
  • Requires simulating ALT key presses to trigger
  • There needs to be two calls to undocumented NtUserMessageCall API
  • Special switch window needs to be created
  • There was some reference to kernel function win32k!DrawSwitchWndHilite

Beside that there is nice screenshot of decompiled code showing some of previously listed things. To be exact it shows: creation of switch window, call to function named toggle_alt_key and multiple calls to NtUserMessageCall.

Part of decompiled exploit code [Image source][1]

A lot of useful information, but it still doesn't describe how exactly this vulnerability works and how to trigger it.

Patch diffing

[Affected module was win32k.sys][2]. I downloaded both patched and unpatched versions of this module.
For win7 x64 those were:

  • patched: KB4530692
  • unpatched: KB4525233

They can be downloaded from [Microsoft Update Catalog][3]

Here is bindiff result of comparing both versions

win32k comparison

After ruling out functions related to DebugHook functionality all we are really left with is this slightly changed function InitFunctionTables()

InitFunctionTables changes

Definitely not the biggest patch out there.
This won't help to immediately identify root cause of this vulnerability. But it's worth noting that some initial values for variables at *(gpsi+0x14E), *(gpsi+0x154), *(gpsi+0x180) have been added. So this might be a bug related to uninitialized variable.

POC building - step by step

In this section I will present how I progressively build up POC that triggers this vulnerability, while simultaneously figuring out what the vulnerability actually was.

Where to start

Patch diffing didn't give too much useful info at the beginning, so I relied mostly on Kaspersky's blogpost at first stage of development.
To have a good testing environment I prepared Win7 SP1 x64 VM with last vulnerable version of win32k running. On top of that I attached Windbg to this VM to do kernel debugging and while doing that I also set up symbol server path.
I started my investigation by looking at win32k!DrawSwitchWndHilite which was mentioned in blogpost. It is being called from two places: xxxMoveSwitchWndHilite and xxxPaintSwitchWindow, latter one immediately got my attention, because of surrounding GetKeyState/GetAsyncKeyState calls that were mentioned in original report. What is more those calls are checking for ALT key being pressed.

Interesting callsite to DrawSwitchWndHilite
Call to DrawSwitchWndHilite from xxxPaintSwitchWindow

Further following call cross references (xxxWrapSwitchWndProc->xxxSwitchWndProc->xxxPaintSwitchWindow->DrawSwitchWndHilite) I found that first element in that chain is referenced in InitFunctionTables, function that was fixed in patch.

Next I looked into NtUserMessageCall from screenshot of decompiled code. Here is declaration of this function

NtUserMessageCall(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOLEAN bAnsi)

Exploit is calling it with msg = 0x14 and dwType = 0xE0. Let's see what it does.

HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wcx;
ZeroMemory(&wcx, sizeof(wcx));
wcx.hInstance = hInstance;
wcx.cbSize = sizeof(wcx);
wcx.lpszClassName = L"SploitWnd";
wcx.lpfnWndProc = DefWindowProc;

printf("[*] Registering window\n");
ATOM wndAtom = RegisterClassEx(&wcx);
if (wndAtom == INVALID_ATOM) {
    printf("[-] Failed registering SploitWnd window class\n");
    exit(-1);
}

printf("[*] Creating instance of this window\n");
HWND sploitWnd = CreateWindowEx(0, L"SploitWnd", L"", 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (sploitWnd == INVALID_HANDLE_VALUE) {
    printf("[-] Failed to create SploitWnd window\n");
    exit(-1);
}
NtUserMessageCall(sploitWnd, WM_ERASEBKGND, 0, 0, 0, 0xE0, 1);

Here I registered simple window class and created window of that class. Then called NtUserMessageCall with same parameters as exploit. To see what happens under the hood I setup breakpoint kd> ba e 1 win32k!NtUserMessageCall and run the code. There are quite a few calls being made to this function so I had to catch the right one, but it wasn't that difficult, it was the one with really short callstack.

NtUserMessageCall
NtUserMessageCall

Stepping through code revealed that it calls function from gapfnMessageCall array, index is calculated based on msg value and is equal to 0, so the call is made to NtUserfnDWORD

NtUserfnDWORD
NtUserfnDWORD

Next call is made using dwType value, and now gpsi offset equals to 0x40, and call leads to xxxWrapSwitchWndProc (this function already appeared when I was checking DrawSwitchWndHilite call chain).
xxxWrapSwitchWndProc simply calls xxxSwitchWndProc.

xxxSwitchWndProc
xxxSwitchWndProc

And this is the end, code fails here, not going any further to xxxPaintSwitchWindow, which is where we want to get based on msg value (0x14). Let's check why.

Triggering correct path

Code fails at this stage because, as highlighted on previous image, fnid of our window is not equal to 0x2A0 (FNID_SWITCH) and message we are sending is not equal to 1, hence we end up in xxxDefWindowProc. To avoid this scenario we have to call xxxSwitchWndProc with fnid set to FNID_SWITCH, so that we will go straight to switch statement and later to xxxPaintSwitchWindow.
How to set correct fnid? Actually the same function does it in the first if block, we just have to fail all checks inside it to get to the instruction setting fnid.

Here are conditions we need to meet, to fail all three if checks:

Download Tool