mirror of
https://github.com/tdeerenberg/InlineWhispers3.git
synced 2025-07-17 00:44:17 +00:00
371 lines
14 KiB
C
371 lines
14 KiB
C
/*
|
|
* Beacon Object Files (BOF)
|
|
* -------------------------
|
|
* A Beacon Object File is a light-weight post exploitation tool that runs
|
|
* with Beacon's inline-execute command.
|
|
*
|
|
* Additional BOF resources are available here:
|
|
* - https://github.com/Cobalt-Strike/bof_template
|
|
*
|
|
* Cobalt Strike 4.x
|
|
* ChangeLog:
|
|
* 1/25/2022: updated for 4.5
|
|
* 7/18/2023: Added BeaconInformation API for 4.9
|
|
* 7/31/2023: Added Key/Value store APIs for 4.9
|
|
* BeaconAddValue, BeaconGetValue, and BeaconRemoveValue
|
|
* 8/31/2023: Added Data store APIs for 4.9
|
|
* BeaconDataStoreGetItem, BeaconDataStoreProtectItem,
|
|
* BeaconDataStoreUnprotectItem, and BeaconDataStoreMaxEntries
|
|
* 9/01/2023: Added BeaconGetCustomUserData API for 4.9
|
|
* 3/21/2024: Updated BeaconInformation API for 4.10 to return a BOOL
|
|
* Updated the BEACON_INFO data structure to add new parameters
|
|
* 4/19/2024: Added BeaconGetSyscallInformation API for 4.10
|
|
* 4/25/2024: Added APIs to call Beacon's system call implementation
|
|
*/
|
|
#ifndef _BEACON_H_
|
|
#define _BEACON_H_
|
|
#include <windows.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif // __cplusplus
|
|
|
|
/* 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 char * BeaconDataPtr(datap * parser, 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 BeaconFormatAppend(formatp * format, const char * text, int len);
|
|
DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, const char * fmt, ...);
|
|
DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size);
|
|
DECLSPEC_IMPORT void BeaconFormatFree(formatp * format);
|
|
DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value);
|
|
|
|
/* Output Functions */
|
|
#define CALLBACK_OUTPUT 0x0
|
|
#define CALLBACK_OUTPUT_OEM 0x1e
|
|
#define CALLBACK_OUTPUT_UTF8 0x20
|
|
#define CALLBACK_ERROR 0x0d
|
|
#define CALLBACK_CUSTOM 0x1000
|
|
#define CALLBACK_CUSTOM_LAST 0x13ff
|
|
|
|
|
|
DECLSPEC_IMPORT void BeaconOutput(int type, const char * data, int len);
|
|
DECLSPEC_IMPORT void BeaconPrintf(int type, const char * fmt, ...);
|
|
|
|
|
|
/* 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 BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
|
|
DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
|
|
|
|
/* Utility Functions */
|
|
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max);
|
|
|
|
/* Beacon Information */
|
|
/*
|
|
* ptr - pointer to the base address of the allocated memory.
|
|
* size - the number of bytes allocated for the ptr.
|
|
*/
|
|
typedef struct {
|
|
char * ptr;
|
|
size_t size;
|
|
} HEAP_RECORD;
|
|
#define MASK_SIZE 13
|
|
|
|
/* Information the user can set in the USER_DATA via a UDRL */
|
|
typedef enum {
|
|
PURPOSE_EMPTY,
|
|
PURPOSE_GENERIC_BUFFER,
|
|
PURPOSE_BEACON_MEMORY,
|
|
PURPOSE_SLEEPMASK_MEMORY,
|
|
PURPOSE_BOF_MEMORY,
|
|
PURPOSE_USER_DEFINED_MEMORY = 1000
|
|
} ALLOCATED_MEMORY_PURPOSE;
|
|
|
|
typedef enum {
|
|
LABEL_EMPTY,
|
|
LABEL_BUFFER,
|
|
LABEL_PEHEADER,
|
|
LABEL_TEXT,
|
|
LABEL_RDATA,
|
|
LABEL_DATA,
|
|
LABEL_PDATA,
|
|
LABEL_RELOC,
|
|
LABEL_USER_DEFINED = 1000
|
|
} ALLOCATED_MEMORY_LABEL;
|
|
|
|
typedef enum {
|
|
METHOD_UNKNOWN,
|
|
METHOD_VIRTUALALLOC,
|
|
METHOD_HEAPALLOC,
|
|
METHOD_MODULESTOMP,
|
|
METHOD_NTMAPVIEW,
|
|
METHOD_USER_DEFINED = 1000,
|
|
} ALLOCATED_MEMORY_ALLOCATION_METHOD;
|
|
|
|
/**
|
|
* This structure allows the user to provide additional information
|
|
* about the allocated heap for cleanup. It is mandatory to provide
|
|
* the HeapHandle but the DestroyHeap Boolean can be used to indicate
|
|
* whether the clean up code should destroy the heap or simply free the pages.
|
|
* This is useful in situations where a loader allocates memory in the
|
|
* processes current heap.
|
|
*/
|
|
typedef struct _HEAPALLOC_INFO {
|
|
PVOID HeapHandle;
|
|
BOOL DestroyHeap;
|
|
} HEAPALLOC_INFO, *PHEAPALLOC_INFO;
|
|
|
|
typedef struct _MODULESTOMP_INFO {
|
|
HMODULE ModuleHandle;
|
|
} MODULESTOMP_INFO, *PMODULESTOMP_INFO;
|
|
|
|
typedef union _ALLOCATED_MEMORY_ADDITIONAL_CLEANUP_INFORMATION {
|
|
HEAPALLOC_INFO HeapAllocInfo;
|
|
MODULESTOMP_INFO ModuleStompInfo;
|
|
PVOID Custom;
|
|
} ALLOCATED_MEMORY_ADDITIONAL_CLEANUP_INFORMATION, *PALLOCATED_MEMORY_ADDITIONAL_CLEANUP_INFORMATION;
|
|
|
|
typedef struct _ALLOCATED_MEMORY_CLEANUP_INFORMATION {
|
|
BOOL Cleanup;
|
|
ALLOCATED_MEMORY_ALLOCATION_METHOD AllocationMethod;
|
|
ALLOCATED_MEMORY_ADDITIONAL_CLEANUP_INFORMATION AdditionalCleanupInformation;
|
|
} ALLOCATED_MEMORY_CLEANUP_INFORMATION, *PALLOCATED_MEMORY_CLEANUP_INFORMATION;
|
|
|
|
typedef struct _ALLOCATED_MEMORY_SECTION {
|
|
ALLOCATED_MEMORY_LABEL Label; // A label to simplify Sleepmask development
|
|
PVOID BaseAddress; // Pointer to virtual address of section
|
|
SIZE_T VirtualSize; // Virtual size of the section
|
|
DWORD CurrentProtect; // Current memory protection of the section
|
|
DWORD PreviousProtect; // The previous memory protection of the section (prior to masking/unmasking)
|
|
BOOL MaskSection; // A boolean to indicate whether the section should be masked
|
|
} ALLOCATED_MEMORY_SECTION, *PALLOCATED_MEMORY_SECTION;
|
|
|
|
typedef struct _ALLOCATED_MEMORY_REGION {
|
|
ALLOCATED_MEMORY_PURPOSE Purpose; // A label to indicate the purpose of the allocated memory
|
|
PVOID AllocationBase; // The base address of the allocated memory block
|
|
SIZE_T RegionSize; // The size of the allocated memory block
|
|
DWORD Type; // The type of memory allocated
|
|
ALLOCATED_MEMORY_SECTION Sections[8]; // An array of section information structures
|
|
ALLOCATED_MEMORY_CLEANUP_INFORMATION CleanupInformation; // Information required to cleanup the allocation
|
|
} ALLOCATED_MEMORY_REGION, *PALLOCATED_MEMORY_REGION;
|
|
|
|
typedef struct {
|
|
ALLOCATED_MEMORY_REGION AllocatedMemoryRegions[6];
|
|
} ALLOCATED_MEMORY, *PALLOCATED_MEMORY;
|
|
|
|
/*
|
|
* version - The version of the beacon dll was added for release 4.10
|
|
* version format: 0xMMmmPP, where MM = Major, mm = Minor, and PP = Patch
|
|
* e.g. 0x040900 -> CS 4.9
|
|
* 0x041000 -> CS 4.10
|
|
*
|
|
* sleep_mask_ptr - pointer to the sleep mask base address
|
|
* sleep_mask_text_size - the sleep mask text section size
|
|
* sleep_mask_total_size - the sleep mask total memory size
|
|
*
|
|
* beacon_ptr - pointer to beacon's base address
|
|
* The stage.obfuscate flag affects this value when using CS default loader.
|
|
* true: beacon_ptr = allocated_buffer - 0x1000 (Not a valid address)
|
|
* false: beacon_ptr = allocated_buffer (A valid address)
|
|
* For a UDRL the beacon_ptr will be set to the 1st argument to DllMain
|
|
* when the 2nd argument is set to DLL_PROCESS_ATTACH.
|
|
* heap_records - list of memory addresses on the heap beacon wants to mask.
|
|
* The list is terminated by the HEAP_RECORD.ptr set to NULL.
|
|
* mask - the mask that beacon randomly generated to apply
|
|
*
|
|
* Added in version 4.10
|
|
* allocatedMemory - An ALLOCATED_MEMORY structure that can be set in the USER_DATA
|
|
* via a UDRL.
|
|
*/
|
|
typedef struct {
|
|
unsigned int version;
|
|
char * sleep_mask_ptr;
|
|
DWORD sleep_mask_text_size;
|
|
DWORD sleep_mask_total_size;
|
|
|
|
char * beacon_ptr;
|
|
HEAP_RECORD * heap_records;
|
|
char mask[MASK_SIZE];
|
|
|
|
ALLOCATED_MEMORY allocatedMemory;
|
|
} BEACON_INFO, *PBEACON_INFO;
|
|
|
|
DECLSPEC_IMPORT BOOL BeaconInformation(PBEACON_INFO info);
|
|
|
|
/* Key/Value store functions
|
|
* These functions are used to associate a key to a memory address and save
|
|
* that information into beacon. These memory addresses can then be
|
|
* retrieved in a subsequent execution of a BOF.
|
|
*
|
|
* key - the key will be converted to a hash which is used to locate the
|
|
* memory address.
|
|
*
|
|
* ptr - a memory address to save.
|
|
*
|
|
* Considerations:
|
|
* - The contents at the memory address is not masked by beacon.
|
|
* - The contents at the memory address is not released by beacon.
|
|
*
|
|
*/
|
|
DECLSPEC_IMPORT BOOL BeaconAddValue(const char * key, void * ptr);
|
|
DECLSPEC_IMPORT void * BeaconGetValue(const char * key);
|
|
DECLSPEC_IMPORT BOOL BeaconRemoveValue(const char * key);
|
|
|
|
/* Beacon Data Store functions
|
|
* These functions are used to access items in Beacon's Data Store.
|
|
* BeaconDataStoreGetItem returns NULL if the index does not exist.
|
|
*
|
|
* The contents are masked by default, and BOFs must unprotect the entry
|
|
* before accessing the data buffer. BOFs must also protect the entry
|
|
* after the data is not used anymore.
|
|
*
|
|
*/
|
|
|
|
#define DATA_STORE_TYPE_EMPTY 0
|
|
#define DATA_STORE_TYPE_GENERAL_FILE 1
|
|
|
|
typedef struct {
|
|
int type;
|
|
DWORD64 hash;
|
|
BOOL masked;
|
|
char* buffer;
|
|
size_t length;
|
|
} DATA_STORE_OBJECT, *PDATA_STORE_OBJECT;
|
|
|
|
DECLSPEC_IMPORT PDATA_STORE_OBJECT BeaconDataStoreGetItem(size_t index);
|
|
DECLSPEC_IMPORT void BeaconDataStoreProtectItem(size_t index);
|
|
DECLSPEC_IMPORT void BeaconDataStoreUnprotectItem(size_t index);
|
|
DECLSPEC_IMPORT size_t BeaconDataStoreMaxEntries();
|
|
|
|
/* Beacon User Data functions */
|
|
DECLSPEC_IMPORT char * BeaconGetCustomUserData();
|
|
|
|
/* Beacon System call */
|
|
/* Syscalls API */
|
|
typedef struct
|
|
{
|
|
PVOID fnAddr;
|
|
PVOID jmpAddr;
|
|
DWORD sysnum;
|
|
} SYSCALL_API_ENTRY, *PSYSCALL_API_ENTRY;
|
|
|
|
typedef struct
|
|
{
|
|
SYSCALL_API_ENTRY ntAllocateVirtualMemory;
|
|
SYSCALL_API_ENTRY ntProtectVirtualMemory;
|
|
SYSCALL_API_ENTRY ntFreeVirtualMemory;
|
|
SYSCALL_API_ENTRY ntGetContextThread;
|
|
SYSCALL_API_ENTRY ntSetContextThread;
|
|
SYSCALL_API_ENTRY ntResumeThread;
|
|
SYSCALL_API_ENTRY ntCreateThreadEx;
|
|
SYSCALL_API_ENTRY ntOpenProcess;
|
|
SYSCALL_API_ENTRY ntOpenThread;
|
|
SYSCALL_API_ENTRY ntClose;
|
|
SYSCALL_API_ENTRY ntCreateSection;
|
|
SYSCALL_API_ENTRY ntMapViewOfSection;
|
|
SYSCALL_API_ENTRY ntUnmapViewOfSection;
|
|
SYSCALL_API_ENTRY ntQueryVirtualMemory;
|
|
SYSCALL_API_ENTRY ntDuplicateObject;
|
|
SYSCALL_API_ENTRY ntReadVirtualMemory;
|
|
SYSCALL_API_ENTRY ntWriteVirtualMemory;
|
|
SYSCALL_API_ENTRY ntReadFile;
|
|
SYSCALL_API_ENTRY ntWriteFile;
|
|
SYSCALL_API_ENTRY ntCreateFile;
|
|
} SYSCALL_API, *PSYSCALL_API;
|
|
|
|
/* Additional Run Time Library (RTL) addresses used to support system calls.
|
|
* If they are not set then system calls that require them will fall back
|
|
* to the Standard Windows API.
|
|
*
|
|
* Required to support the following system calls:
|
|
* ntCreateFile
|
|
*/
|
|
typedef struct
|
|
{
|
|
PVOID rtlDosPathNameToNtPathNameUWithStatusAddr;
|
|
PVOID rtlFreeHeapAddr;
|
|
PVOID rtlGetProcessHeapAddr;
|
|
} RTL_API, *PRTL_API;
|
|
|
|
typedef struct
|
|
{
|
|
PSYSCALL_API syscalls;
|
|
PRTL_API rtls;
|
|
} BEACON_SYSCALLS, *PBEACON_SYSCALLS;
|
|
|
|
DECLSPEC_IMPORT BOOL BeaconGetSyscallInformation(PBEACON_SYSCALLS info, BOOL resolveIfNotInitialized);
|
|
|
|
/* Beacon System call functions which will use the current system call method */
|
|
DECLSPEC_IMPORT LPVOID BeaconVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
|
|
DECLSPEC_IMPORT LPVOID BeaconVirtualAllocEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
|
|
DECLSPEC_IMPORT BOOL BeaconVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
|
|
DECLSPEC_IMPORT BOOL BeaconVirtualProtectEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
|
|
DECLSPEC_IMPORT BOOL BeaconVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
|
|
DECLSPEC_IMPORT BOOL BeaconGetThreadContext(HANDLE threadHandle, PCONTEXT threadContext);
|
|
DECLSPEC_IMPORT BOOL BeaconSetThreadContext(HANDLE threadHandle, PCONTEXT threadContext);
|
|
DECLSPEC_IMPORT DWORD BeaconResumeThread(HANDLE threadHandle);
|
|
DECLSPEC_IMPORT HANDLE BeaconOpenProcess(DWORD desiredAccess, BOOL inheritHandle, DWORD processId);
|
|
DECLSPEC_IMPORT HANDLE BeaconOpenThread(DWORD desiredAccess, BOOL inheritHandle, DWORD threadId);
|
|
DECLSPEC_IMPORT BOOL BeaconCloseHandle(HANDLE object);
|
|
DECLSPEC_IMPORT BOOL BeaconUnmapViewOfFile(LPCVOID baseAddress);
|
|
DECLSPEC_IMPORT SIZE_T BeaconVirtualQuery(LPCVOID address, PMEMORY_BASIC_INFORMATION buffer, SIZE_T length);
|
|
DECLSPEC_IMPORT BOOL BeaconDuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions);
|
|
DECLSPEC_IMPORT BOOL BeaconReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
|
|
DECLSPEC_IMPORT BOOL BeaconWriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
|
|
|
|
/* Beacon Gate APIs */
|
|
DECLSPEC_IMPORT VOID BeaconDisableBeaconGate();
|
|
DECLSPEC_IMPORT VOID BeaconEnableBeaconGate();
|
|
|
|
/* Beacon User Data
|
|
*
|
|
* version format: 0xMMmmPP, where MM = Major, mm = Minor, and PP = Patch
|
|
* e.g. 0x040900 -> CS 4.9
|
|
* 0x041000 -> CS 4.10
|
|
*/
|
|
|
|
#define DLL_BEACON_USER_DATA 0x0d
|
|
#define BEACON_USER_DATA_CUSTOM_SIZE 32
|
|
typedef struct
|
|
{
|
|
unsigned int version;
|
|
PSYSCALL_API syscalls;
|
|
char custom[BEACON_USER_DATA_CUSTOM_SIZE];
|
|
PRTL_API rtls;
|
|
PALLOCATED_MEMORY allocatedMemory;
|
|
} USER_DATA, * PUSER_DATA;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif // __cplusplus
|
|
#endif // _BEACON_H_
|