From aaf96b44869f5e9688f5f3ee8fce210e9acdbb46 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Wed, 25 Jan 2017 03:19:20 +0100 Subject: [PATCH] [BUGFIX] Fixed injections to running processes (32/64 bit mismatch) --- chimera_pe/src/enumproc.h | 60 +++++++++++++++++++++++------- chimera_pe/src/main.cpp | 42 +++++++++++++-------- chimera_pe/src/pe_raw_to_virtual.h | 4 +- chimera_pe/src/resource.h | 2 +- chimera_pe/src/sysutil.cpp | 13 ++++--- chimera_pe/src/sysutil.h | 2 +- chimera_pe/src/target_util.h | 2 +- 7 files changed, 87 insertions(+), 38 deletions(-) diff --git a/chimera_pe/src/enumproc.h b/chimera_pe/src/enumproc.h index 72cc323..48804eb 100644 --- a/chimera_pe/src/enumproc.h +++ b/chimera_pe/src/enumproc.h @@ -1,27 +1,33 @@ #pragma once #include +#include +#include +using namespace std; bool get_process_name(IN HANDLE hProcess, OUT LPWSTR nameBuf, IN SIZE_T nameMax) { - HMODULE hMod; - DWORD cbNeeded; - - if (EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded)) { - GetModuleBaseName( hProcess, hMod, nameBuf, nameMax); - return true; + memset(nameBuf, 0, nameMax); + DWORD out = GetModuleBaseName(hProcess, 0, nameBuf, nameMax); + if (out == 0) { + out = GetProcessImageFileName(hProcess, nameBuf, nameMax); } - return false; + return (out > 0); } -bool is_searched_process( DWORD processID, LPWSTR searchedName) +bool is_searched_process(DWORD processID, LPWSTR searchedName, bool is64b) { HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if (hProcess == NULL) return false; - + bool proc64b = !is_system32b() && !is_wow64(hProcess); + if (is64b != proc64b) { + CloseHandle(hProcess); + return false; + } WCHAR szProcessName[MAX_PATH]; if (get_process_name(hProcess, szProcessName, MAX_PATH)) { + if (wcsstr(szProcessName, searchedName) != NULL) { - printf( "%S (PID: %u)\n", szProcessName, processID ); + printf("%S (PID: %u) : %d\n", szProcessName, processID, proc64b); CloseHandle(hProcess); return true; } @@ -32,6 +38,34 @@ bool is_searched_process( DWORD processID, LPWSTR searchedName) HANDLE find_running_process(LPWSTR searchedName) { + bool is64b = !is_compiled_32b(); + + HANDLE hProcessSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); + PROCESSENTRY32 process_entry = { 0 }; + process_entry.dwSize = sizeof(process_entry); + + if (!Process32First(hProcessSnapShot, &process_entry)) { + return NULL; + } + + do + { + if (is_searched_process(process_entry.th32ProcessID, searchedName, is64b)) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_entry.th32ProcessID); + return hProcess; + } + + } while (Process32Next(hProcessSnapShot, &process_entry)); + + // Close the handle + CloseHandle(hProcessSnapShot); + return NULL; +} + + +HANDLE find_running_process2(LPWSTR searchedName) +{ + bool is64b = !is_compiled_32b(); DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; @@ -44,9 +78,9 @@ HANDLE find_running_process(LPWSTR searchedName) //search handle to the process of defined name for ( i = 0; i < cProcesses; i++ ) { - if( aProcesses[i] != 0 ) { - if (is_searched_process(aProcesses[i], searchedName)) { - HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, aProcesses[i]); + if (aProcesses[i] != 0) { + if (is_searched_process(aProcesses[i], searchedName, is64b)) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, aProcesses[i]); return hProcess; } } diff --git a/chimera_pe/src/main.cpp b/chimera_pe/src/main.cpp index 2d2392f..f185444 100644 --- a/chimera_pe/src/main.cpp +++ b/chimera_pe/src/main.cpp @@ -42,36 +42,48 @@ HANDLE make_new_process(HANDLE &mainThread) return pi.hProcess; } +bool is_process_64b(HANDLE hProcess) +{ + if (is_system32b()) { + return false; + } + if (is_wow64(hProcess)) { + printf("[*] wow64\n"); + return false; + } + printf("[*] not wow64\n"); + return true; +} + int main(int argc, char *argv[]) { + //we may inject into existing process + HANDLE hProcess = find_running_process(L"calc.exe"); + HANDLE mainThread = NULL; + if (!hProcess) { + //or create a new one: + printf("making a new process!\n"); + hProcess = make_new_process(mainThread); + } + + bool is64b = is_process_64b(hProcess); + BYTE* res_data = NULL; SIZE_T res_size = 0; - if (is_compiled_32b()) { + if (!is64b) { printf("payload 32 bit\n"); if ((res_data = get_raw_payload(res_size, MY_RESOURCE32)) == NULL) { printf("Failed!\n"); return -1; } - } else { + } + else { printf("payload 64 bit\n"); if ((res_data = get_raw_payload(res_size, MY_RESOURCE64)) == NULL) { printf("Failed!\n"); return -1; } } - /* - if (!is_compiled_32b()) { - printf("[ERROR] Not supported! Compile the loader as a 32 bit application!\n"); - system("pause"); - return (-1); - }*/ - //we may inject into existing process - HANDLE hProcess = find_running_process(L"calc.exe"); - HANDLE mainThread = NULL; - if (!hProcess) { - //or create a new one: - hProcess = make_new_process(mainThread); - } if (inject_PE(hProcess, res_data, res_size)) { printf("Injected!\n"); } else { diff --git a/chimera_pe/src/pe_raw_to_virtual.h b/chimera_pe/src/pe_raw_to_virtual.h index e52028c..a8e62e9 100644 --- a/chimera_pe/src/pe_raw_to_virtual.h +++ b/chimera_pe/src/pe_raw_to_virtual.h @@ -54,7 +54,7 @@ bool sections_raw_to_virtual(BYTE* payload, SIZE_T destBufferSize, OUT BYTE* des SIZE_T sec_size = next_sec->SizeOfRawData; raw_end = next_sec->SizeOfRawData + next_sec->PointerToRawData; - if (next_sec->VirtualAddress + sec_size >= destBufferSize) { + if (next_sec->VirtualAddress + sec_size > destBufferSize) { printf("[!] Virtual section size is out ouf bounds: %lx\n", sec_size); sec_size = SIZE_T(destBufferSize - next_sec->VirtualAddress); printf("[!] Truncated to maximal size: %lx\n", sec_size); @@ -63,7 +63,7 @@ bool sections_raw_to_virtual(BYTE* payload, SIZE_T destBufferSize, OUT BYTE* des printf("[-] VirtualAddress of section is out ouf bounds: %lx\n", static_cast(next_sec->VirtualAddress)); return false; } - if (next_sec->PointerToRawData + sec_size >= destBufferSize) { + if (next_sec->PointerToRawData + sec_size > destBufferSize) { printf("[-] Raw section size is out ouf bounds: %lx\n", sec_size); return false; } diff --git a/chimera_pe/src/resource.h b/chimera_pe/src/resource.h index 4750879..d2c54cf 100644 --- a/chimera_pe/src/resource.h +++ b/chimera_pe/src/resource.h @@ -1,4 +1,4 @@ // resource.h #define MY_RESOURCE32 101 -#define MY_RESOURCE64 102 +#define MY_RESOURCE64 102 diff --git a/chimera_pe/src/sysutil.cpp b/chimera_pe/src/sysutil.cpp index 2f55323..fa5e551 100644 --- a/chimera_pe/src/sysutil.cpp +++ b/chimera_pe/src/sysutil.cpp @@ -8,13 +8,13 @@ typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); bool is_compiled_32b() { - if (sizeof(LPVOID) == sizeof(DWORD)) { - return true; - } +#if defined(_WIN64) return false; +#endif + return true; } -bool is_wow64() +bool is_wow64(HANDLE process = NULL) { LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL bIsWow64 = false; @@ -27,7 +27,10 @@ bool is_wow64() if (fnIsWow64Process == NULL) { return false; } - if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) { + if (process == NULL) { + process = GetCurrentProcess(); + } + if (!fnIsWow64Process(process, &bIsWow64)) { return false; } if (bIsWow64 == TRUE) { diff --git a/chimera_pe/src/sysutil.h b/chimera_pe/src/sysutil.h index c48ee3d..8f76e9a 100644 --- a/chimera_pe/src/sysutil.h +++ b/chimera_pe/src/sysutil.h @@ -3,6 +3,6 @@ #include bool is_compiled_32b(); -bool is_wow64(); +bool is_wow64(HANDLE process); bool is_system32b(); bool validate_ptr(LPVOID buffer_bgn, SIZE_T buffer_size, LPVOID field_bgn, SIZE_T field_size); \ No newline at end of file diff --git a/chimera_pe/src/target_util.h b/chimera_pe/src/target_util.h index e2cfa58..a9a89b8 100644 --- a/chimera_pe/src/target_util.h +++ b/chimera_pe/src/target_util.h @@ -16,7 +16,7 @@ bool get_default_browser(LPWSTR lpwOutPath, DWORD szOutPath) printf("[ERROR] Failed with value = %x\n", res); return false; } - printf("%S\n", lpwOutPath ); + printf("%S\n", lpwOutPath); return true; }