From 1ff1328f5666adda3adc784cbf2a2db1fa0942a7 Mon Sep 17 00:00:00 2001 From: realoriginal Date: Sun, 17 Mar 2024 03:40:46 +0000 Subject: [PATCH] grimreaper: Successfully ported over to LLVM-MINGW --- Common.h | 1 + Makefile | 10 +++++----- Obf.c | 51 ++++++++++++++++++++++++++++++++++++------------ Pipe.c | 30 ++++++++++++++++++++++++++++ crt/memcpy.c | 13 ++++++++++++ crt/memset.c | 12 ++++++++++++ requirements.txt | 4 ++++ 7 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 Pipe.c create mode 100644 crt/memcpy.c create mode 100644 crt/memset.c create mode 100644 requirements.txt diff --git a/Common.h b/Common.h index 38031c2..31eb2d9 100644 --- a/Common.h +++ b/Common.h @@ -12,6 +12,7 @@ #include #include +#include #include "Native.h" #include "Macros.h" #include "Labels.h" diff --git a/Makefile b/Makefile index 6d08633..b1f6ffb 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -CC_X64 := x86_64-w64-mingw32-gcc -CC_X86 := i686-w64-mingw32-gcc +CC_X64 := clang -target x86_64-w64-mingw32-gnu +CC_X86 := clang -target i686-w64-mingw32-gnu SOURCE := $(wildcard *.c) HSHKEY := $(shell python3 -c "import random; print(hex(random.getrandbits(32)))") @@ -8,7 +8,7 @@ CFLAGS := $(CFLAGS) -Os -fno-asynchronous-unwind-tables -nostdlib CFLAGS := $(CFLAGS) -fno-ident -fpack-struct=8 -falign-functions=1 CFLAGS := $(CFLAGS) -s -ffunction-sections -falign-jumps=1 -w CFLAGS := $(CFLAGS) -falign-labels=1 -Wl,-TSectionLink.ld -CFLAGS := $(CFLAGS) -fdata-sections +CFLAGS := $(CFLAGS) -fdata-sections -fms-extensions -mno-sse LFLAGS := $(LFLAGS) -Wl,-s,--no-seh,--enable-stdcall-fixup OUTX64 := grimreaper.x64.exe @@ -26,8 +26,8 @@ all: $(SOURCE) @ nasm -f win64 asm/x64/Start.asm -o bin/Start.x64.o @ nasm -f win32 asm/x86/GetIp.asm -o bin/GetIp.x86.o @ nasm -f win32 asm/x86/Start.asm -o bin/Start.x86.o - @ $(CC_X64) bin/Start.x64.o bin/GetIp.x64.o bin/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX64) - @ $(CC_X86) bin/Start.x86.o bin/GetIp.x86.o bin/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX86) + @ $(CC_X64) bin/Start.x64.o bin/GetIp.x64.o bin/*.c crt/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX64) + @ $(CC_X86) bin/Start.x86.o bin/GetIp.x86.o bin/*.c crt/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX86) @ python3 scripts/extract.py -f bin/$(OUTX64) -o $(SHLX64) @ python3 scripts/extract.py -f bin/$(OUTX86) -o $(SHLX86) diff --git a/Obf.c b/Obf.c index 633e3f4..edecd37 100644 --- a/Obf.c +++ b/Obf.c @@ -59,7 +59,7 @@ typedef struct static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS NTAPI ThreadCallbackFrameCaptureInternal( _In_ PTHREAD_PARAM Parameter ) { /* Set the frame pointer */ - Parameter->Csp = C_PTR( U_PTR( __builtin_frame_address( 0 ) ) + sizeof( PVOID ) ); + Parameter->Csp = C_PTR( U_PTR( _AddressOfReturnAddress() ) ); /* Execute ntdll!NtSignalAndWaitForSingleObject */ ( ( __typeof__( NtSignalAndWaitForSingleObject ) * )( PeGetFuncEat( @@ -361,7 +361,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL Ctx->Rip = U_PTR( Function ); /* Read the return value */ - Ret = *( ULONG_PTR * )( Ctx->Rsp ); + Ret = C_PTR( *( ULONG_PTR * )( U_PTR( Ctx->Rsp ) ) ); /* Unset the return address */ *( ULONG_PTR * )( Ctx->Rsp ) = U_PTR( NULL ); @@ -416,7 +416,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL Ctx->Eip = U_PTR( Function ); /* Read the return value */ - Ret = *( ULONG_PTR * )( Ctx->Esp ); + Ret = C_PTR( *( ULONG_PTR * )( Ctx->Esp ) ); /* Unset the return address */ *( ULONG_PTR * )( Ctx->Esp ) = U_PTR( NULL ); @@ -449,7 +449,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL }; /* Queue an APC to block the call setup until this handle has been signaled */ - Nst = Api.NtQueueApcThread( Thd, Api.NtWaitForSingleObject, BlockingHandle, FALSE, NULL ); + Nst = Api.NtQueueApcThread( Thd, C_PTR( Api.NtWaitForSingleObject ), BlockingHandle, FALSE, NULL ); /* Failed to queue the APC */ if ( ! NT_SUCCESS( Nst ) ) { @@ -528,6 +528,7 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO HANDLE Th3 = NULL; HANDLE Th4 = NULL; HANDLE Th5 = NULL; + HANDLE Th6 = NULL; LPVOID Mem = NULL; DWORD Cln = 0; @@ -654,12 +655,32 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO break; }; - /* Call NtWaitForSingleOBject */ + /* Call NtAllocateVirtualMemory */ Nst = ThreadSetCallInternal( &Th2, Th1, Sfp, Sfl, + PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtAllocateVirtualMemory" ) ), + 6, + NtCurrentProcess(), + &Mem, + 0, + &Len, + MEM_COMMIT, + PAGE_READWRITE + ); + + if ( ! NT_SUCCESS( Nst ) ) { + /* ABrot! */ + }; + + /* Call NtWaitForSingleOBject */ + Nst = ThreadSetCallInternal( + &Th3, + Th2, + Sfp, + Sfl, PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtWaitForSingleObject" ) ), 3, Handle, @@ -675,8 +696,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO /* Call NtAllocateVirtualMemory */ Nst = ThreadSetCallInternal( - &Th3, - Th2, + &Th4, + Th3, Sfp, Sfl, PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtAllocateVirtualMemory" ) ), @@ -697,8 +718,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO /* Call RtlDecompressBufferEx */ Nst = ThreadSetCallInternal( - &Th4, - Th3, + &Th5, + Th4, Sfp, Sfl, PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "RtlDecompressBufferEx" ) ), @@ -720,8 +741,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO /* Call NtProtectVirtualMemory */ Nst = ThreadSetCallInternal( - &Th5, - Th4, + &Th6, + Th5, Sfp, Sfl, PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtProtectVirtualMemory" ) ), @@ -740,7 +761,7 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO }; /* Signal and wait for the last call to complete */ - Nst = Api.NtSignalAndWaitForSingleObject( Evt, Th5, FALSE, NULL ); + Nst = Api.NtSignalAndWaitForSingleObject( Evt, Th6, FALSE, NULL ); /* Failed to signal/and or wait on the thread */ if ( ! NT_SUCCESS( Nst ) ) { @@ -748,7 +769,7 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO }; /* Query the exit status of the NtWaitForSingleObject call */ - Nst = Api.NtQueryInformationThread( Th2, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL ); + Nst = Api.NtQueryInformationThread( Th3, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL ); /* Failed to query its basic information */ if ( ! NT_SUCCESS( Nst ) ) { @@ -759,6 +780,10 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO Nst = Tbi.ExitStatus; } while ( 0 ); + if ( Th6 != NULL ) { + Api.NtTerminateThread( Th6, STATUS_SUCCESS ); + Api.NtClose( Th6 ); + }; if ( Th5 != NULL ) { Api.NtTerminateThread( Th5, STATUS_SUCCESS ); Api.NtClose( Th5 ); diff --git a/Pipe.c b/Pipe.c new file mode 100644 index 0000000..b01efa5 --- /dev/null +++ b/Pipe.c @@ -0,0 +1,30 @@ +/*! + * + * GRIMREAPER + * + * Austin Hudson + * + * suspicious.actor + * +!*/ + +#include "Common.h" + +typedef struct +{ + D_API( NtCreateNamedPipeFile ); + D_API( NtDeviceIoControlFile ); + D_API( NtClose ); +} API ; + +/*! + * + * Purpose: + * + * Opens a named pipe as a server and awaits for a connection. + * +!*/ +D_SEC( B ) NTSTATUS PipeOpen( _In_ LPWSTR PipeName ) +{ + +}; diff --git a/crt/memcpy.c b/crt/memcpy.c new file mode 100644 index 0000000..f3c0ab2 --- /dev/null +++ b/crt/memcpy.c @@ -0,0 +1,13 @@ +/* Public domain. */ +#include + +__attribute__(( section( ".text$B" ) )) +void * +memcpy (void *dest, const void *src, size_t len) +{ + char *d = dest; + const char *s = src; + while (len--) + *d++ = *s++; + return dest; +} diff --git a/crt/memset.c b/crt/memset.c new file mode 100644 index 0000000..dc6acd0 --- /dev/null +++ b/crt/memset.c @@ -0,0 +1,12 @@ +/* Public domain. */ +#include + +__attribute__(( section( ".text$B" ) )) +void * +memset (void *dest, int val, size_t len) +{ + unsigned char *ptr = dest; + while (len-- > 0) + *ptr++ = val; + return dest; +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3bd49c8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +click==8.1.7 +Mako==1.3.2 +MarkupSafe==2.1.5 +pefile==2023.2.7