Skip to content

Commit

Permalink
Merge pull request #1 from physics-sp/master
Browse files Browse the repository at this point in the history
Don't unhook the DLL where Beacon is
  • Loading branch information
rsmudge authored Mar 6, 2021
2 parents 45586bc + 6893663 commit fa3c8d8
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 15 deletions.
4 changes: 0 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
31 changes: 29 additions & 2 deletions src/refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/refresh.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 7 additions & 2 deletions src/unhook.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
11 changes: 5 additions & 6 deletions unhook.cna
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
alias unhook {
local('$barch $handle $data $stomp');
local('$barch $handle $data $stomp $args');

# figure out the arch of this session
$barch = barch($1);

# 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(
Expand Down
Binary file modified unhook.x64.o
100755 → 100644
Binary file not shown.
Binary file modified unhook.x86.o
100755 → 100644
Binary file not shown.

0 comments on commit fa3c8d8

Please sign in to comment.