From 280399c1b90935d72b18a13b736cddb7c0ad97e1 Mon Sep 17 00:00:00 2001 From: "Mariusz B. / mgeeky" Date: Fri, 17 Mar 2023 17:08:24 +0100 Subject: [PATCH] Added cobalt-udrl-hasher --- red-teaming/README.md | 2 + red-teaming/cobalt-udrl-hasher/README.md | 45 +++++++++ red-teaming/cobalt-udrl-hasher/hash.c | 123 +++++++++++++++++++++++ red-teaming/cobalt-udrl-hasher/hash.exe | Bin 0 -> 58394 bytes 4 files changed, 170 insertions(+) create mode 100644 red-teaming/cobalt-udrl-hasher/README.md create mode 100644 red-teaming/cobalt-udrl-hasher/hash.c create mode 100644 red-teaming/cobalt-udrl-hasher/hash.exe diff --git a/red-teaming/README.md b/red-teaming/README.md index 3dffab1..4698417 100755 --- a/red-teaming/README.md +++ b/red-teaming/README.md @@ -57,6 +57,8 @@ cmstp.exe /ni /s cmstp.inf - **`cobalt-arsenal`** - A set of my published Cobalt Strike 4.0+ compatible aggressor scripts. That includes couple of my handy utils I've used on various engagements. +- **`cobalt-udrl-hasher`** - A handy utility used to recalculate hashes needed for Cobalt Strike _User Defined Reflective Loaders_ + - **`CobaltSplunk`** - Originally devised by [Vincent Yiu](https://github.com/vysecurity/CobaltSplunk), heavily reworked by me: a Splunk application that ingests, indexes and exposes several search operators to work with Cobalt Strike logs from within of a Splunk interface. Supports Cobalt Strike 4.3+ log files syntax. Gives a lot of flexibility to work with Teamserver log files, search through them, generate insightful reports/dashboards/pivot tables and much more. - [**`code-exec-templates`**](https://github.com/mgeeky/Penetration-Testing-Tools/tree/master/red-teaming/code-exec-templates) - a small collection of template/backbone files for various code-execution techniques (VBScript/JScript embedded in HTA/SCT/XSL/VBS/JS) diff --git a/red-teaming/cobalt-udrl-hasher/README.md b/red-teaming/cobalt-udrl-hasher/README.md new file mode 100644 index 0000000..845ef99 --- /dev/null +++ b/red-teaming/cobalt-udrl-hasher/README.md @@ -0,0 +1,45 @@ +## Cobalt Strike UDRL Hasher + +Simple helper utility recomputing `DLL Reflective Loader` hashes, for offensive engineering needs whenever we want to recompile [User Defined Reflective Loaders](https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2-extend_user-defined-rdll.htm) and such. + +Ever came across [such hashes](https://github.com/stephenfewer/ReflectiveDLLInjection/blob/master/dll/src/ReflectiveLoader.h#L43) before? + +``` +#define KERNEL32DLL_HASH 0x6A4ABC5B +#define NTDLLDLL_HASH 0x3CFA685D + +#define LOADLIBRARYA_HASH 0xEC0E4E8E +#define GETPROCADDRESS_HASH 0x7C0DFCAA +#define VIRTUALALLOC_HASH 0x91AFCA54 +#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8 + +[...] + +#define HASH_KEY 13 +``` + +These can be used for a straightforward signaturing. + +We can regenerate them easily with utility included here: + +``` +cmd> hash 55 + +#define KERNEL32DLL_HASH 0xA6154C3A // kernel32.dll +#define NTDLLDLL_HASH 0x0521447A // ntdll.dll + +#define LOADLIBRARYA_HASH 0xE0D79FEB // LoadLibraryA +#define GETPROCADDRESS_HASH 0x6BAC2F89 // GetProcAddress +#define VIRTUALALLOC_HASH 0x9EE2D962 // VirtualAlloc +#define VIRTUALPROTECT_HASH 0x9154022F // VirtualProtect +#define NTFLUSHINSTRUCTIONCACHE_HASH 0x7353E65D // NtFlushInstructionCache + +#define HASH_KEY 55 + +``` + +**Notice** - if you want to get hash for a DLL, be sure to include its extension: + +``` +hash 55 kernel32.dll +``` diff --git a/red-teaming/cobalt-udrl-hasher/hash.c b/red-teaming/cobalt-udrl-hasher/hash.c new file mode 100644 index 0000000..a052cb1 --- /dev/null +++ b/red-teaming/cobalt-udrl-hasher/hash.c @@ -0,0 +1,123 @@ +// +// Simple utility aimed to help regenerating UDRL hashes +// +// cmd> gcc hash.c -o hash.exe +// +// Mariusz Banach / mgeeky, '23 +// binary-offensive.com +// + +#include +#include +#include + +BYTE hashKey = 13; + +__forceinline DWORD ror( DWORD d ) { + return _rotr( d, hashKey ); +} + +__forceinline DWORD hash( const char * c ) { + register DWORD h = 0; + do + { + h = ror( h ); + h += *c; + } while( *++c ); + + return h; +} + +__forceinline DWORD hashModule( const char * c ) { + register DWORD h = 0; + + size_t counter = strlen(c) * 2; + wchar_t * wstr = (wchar_t*)malloc(counter + 2); + char * ptr = (char*)wstr; + + mbstowcs(wstr, c, counter); + + do + { + h = ror( (DWORD)h ); + + // normalize to uppercase if the module name is in lowercase + if( *((BYTE *)ptr) >= 'a' ) + h += *((BYTE *)ptr) - 0x20; + else + h += *((BYTE *)ptr); + + ptr++; + + } while( --counter ); + + free(wstr); + return h; +} + +int endswith(const char *str, const char *suffix) +{ + if (!str || !suffix) + return 0; + size_t lenstr = strlen(str); + size_t lensuffix = strlen(suffix); + if (lensuffix > lenstr) + return 0; + return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; +} + +void print(char* str) { + DWORD val = 0; + + if(endswith(str, ".dll")) { + val = hashModule(str); + } + else { + val = hash(str); + } + + char str2[256] = ""; + char *s = str2; + + for(int i = 0; i < strlen(str); i++) { + if(isalnum(str[i])) { + *(s++) = str[i]; + } + } + + s = str2; + while (*s) *(s++) = toupper(*s); + + strncat(str2, "_HASH", sizeof(str2)-1); + + printf("#define %-30s 0x%08X\t// %s\n", str2, val, str); +} + +int main(int argc, char** argv) { + if (argc < 2) { + printf("Usage: hash.exe [string]\n"); + return 0; + } + + hashKey = atoi(argv[1]); + + printf("\n"); + + if (argc == 3) { + print(argv[2]); + } + else { + print("kernel32.dll"); + print("ntdll.dll"); + printf("\n"); + print("LoadLibraryA"); + print("GetProcAddress"); + print("VirtualAlloc"); + print("VirtualProtect"); + print("NtFlushInstructionCache"); + } + + printf("\n#define HASH_KEY %d\n", hashKey); + + return 0; +} \ No newline at end of file diff --git a/red-teaming/cobalt-udrl-hasher/hash.exe b/red-teaming/cobalt-udrl-hasher/hash.exe new file mode 100644 index 0000000000000000000000000000000000000000..0b450229e587b5e419012e161699551a930eb7f4 GIT binary patch literal 58394 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 L8pZH2qUZk)T@>6_ literal 0 HcmV?d00001