unknown 2 tahun lalu
induk
melakukan
e30c1ed8ee

+ 48 - 0
KIT/TaskScheduler/README.md

@@ -0,0 +1,48 @@
+# TaskScheduler
+This tool can be used to create or delete a scheduled task. 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.
+* `programPath`: Path to the program that you want to run like: `C:\Windows\System32\cmd.exe`.
+* `programArguments`: Arguments that you want to pass to the program like: `"/c C:\Windows\System32\calc.exe"` or `""` to leave it empty.
+* `triggerType`: The trigger that signals the execution like: `onetime`, `daily`, `logon`, `startup`, `lock`, `unlock`. For more information, check the TRIGGER OPTIONS below.
+
+## Supported trigger options
+* `onetime`: Create task with trigger "On a schedule: one time".
+* `daily`: Create task with trigger "On a schedule: daily."
+* `logon`: Create task with trigger "At log on" (requires admin privs if set for another user or all users).
+* `startup`: Create task with trigger "At startup" (requires admin privs).
+* `lock`: Create task with trigger "On workstation lock" (requires admin privs if set for another user or all users).
+* `unlock`: Create task with trigger "On workstation unlock" (requires admin privs if set for another user or all users).
+
+## Trigger specific parameters
+* `startTime`: Start time of the trigger in format: 2023-03-24T12:08:00.
+* `expireTime`: Expiration time of the trigger in format: 2023-03-24T12:08:00.
+* `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).
+
+## Usage
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" onetime <startTime>`
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>`
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" logon <(optional) userID>`
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" startup <(optional) delay>`
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" lock <(optional) userID> <(optional) delay>`
+`taskscheduler create <taskName> <programPath> "<(optional) programArguments>" unlock <(optional) userID> <(optional) delay>`
+`taskscheduler delete <taskName>`
+
+## 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 C:\Users\Public\Downloads\legit.exe "" logon Testdomain\Administrator`
+`taskscheduler create OneDrive C:\Data\OneDrive.exe "" unlock "" PT5M`
+`taskscheduler delete TestTask`
+
+## 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/TaskScheduler/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/TaskScheduler/bofcompile.bat

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

+ 492 - 0
KIT/TaskScheduler/taskscheduler.c

@@ -0,0 +1,492 @@
+#include <stdio.h>
+#include <windows.h>
+#include <taskschd.h>
+#include <combaseapi.h>
+#include "taskscheduler.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);
+
+	return hr;
+}
+
+
+HRESULT SetDailyTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* startTime, wchar_t* expireTime, int daysInterval, wchar_t* delay) {
+	IID IIDIDailyTrigger = {0x126c5cd8, 0xb288, 0x41d5, {0x8d, 0xbf, 0xe4, 0x91, 0x44, 0x6a, 0xdc, 0x5c}};
+	ITrigger* pTrigger = NULL;
+	
+	hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_DAILY, &pTrigger);
+	if (SUCCEEDED(hr)) {
+		IDailyTrigger* pDailyTrigger = NULL;
+		
+		hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDIDailyTrigger, (void**)&pDailyTrigger);
+		if (SUCCEEDED(hr)) {
+			BSTR startTimeBstr = OLEAUT32$SysAllocString(startTime);
+			BSTR expireTimeBstr = OLEAUT32$SysAllocString(expireTime);
+			BSTR delayBstr = OLEAUT32$SysAllocString(delay);
+
+			pDailyTrigger->lpVtbl->put_StartBoundary(pDailyTrigger, startTimeBstr); 
+			pDailyTrigger->lpVtbl->put_EndBoundary(pDailyTrigger, expireTimeBstr); 
+			pDailyTrigger->lpVtbl->put_DaysInterval(pDailyTrigger, daysInterval); 
+			pDailyTrigger->lpVtbl->put_RandomDelay(pDailyTrigger, delayBstr); 
+			pDailyTrigger->lpVtbl->Release(pDailyTrigger);
+			
+			OLEAUT32$SysFreeString(startTimeBstr);
+			OLEAUT32$SysFreeString(expireTimeBstr);
+			OLEAUT32$SysFreeString(delayBstr);
+		}
+		pTrigger->lpVtbl->Release(pTrigger);
+	}
+	pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+	
+	return hr;
+}
+
+
+HRESULT SetLogonTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID) {
+	IID IIDILogonTrigger = {0x72dade38, 0xfae4, 0x4b3e, {0xba, 0xf4, 0x5d, 0x00, 0x9a, 0xf0, 0x2b, 0x1c}};
+    ITrigger* pTrigger = NULL;
+    
+    hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_LOGON, &pTrigger);
+    if (SUCCEEDED(hr)) {
+        ILogonTrigger* pLogonTrigger = NULL;
+        
+        hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDILogonTrigger, (void**)&pLogonTrigger);
+        if (SUCCEEDED(hr)) {
+            BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
+            
+            pLogonTrigger->lpVtbl->put_UserId(pLogonTrigger, userIDBstr); 
+            pLogonTrigger->lpVtbl->Release(pLogonTrigger);
+			
+			OLEAUT32$SysFreeString(userIDBstr);
+        }
+        pTrigger->lpVtbl->Release(pTrigger);
+    }
+    pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+
+    return hr;
+}
+
+
+
+HRESULT SetStartUpTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* delay) {
+    IID IIDIBootTrigger = {0x2a9c35da, 0xd357, 0x41f4, {0xbb, 0xc1, 0x20, 0x7a, 0xc1, 0xb1, 0xf3, 0xcb}};
+    ITrigger* pTrigger = NULL;
+    
+    hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_BOOT, &pTrigger);
+    if (SUCCEEDED(hr)) {
+        IBootTrigger* pBootTrigger = NULL;
+        
+        hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDIBootTrigger, (void**)&pBootTrigger);
+        if (SUCCEEDED(hr)) {
+            BSTR delayBstr = OLEAUT32$SysAllocString(delay);
+            
+            pBootTrigger->lpVtbl->put_Delay(pBootTrigger, delayBstr);
+			pBootTrigger->lpVtbl->Release(pBootTrigger);
+            
+            OLEAUT32$SysFreeString(delayBstr);
+        }
+        pTrigger->lpVtbl->Release(pTrigger);
+    }
+    pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+
+    return hr;
+}
+
+
+
+HRESULT SetLockTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID, wchar_t* delay) {
+    IID IIDISessionStateChangeTrigger = {0x754da71b, 0x4385, 0x4475, {0x9d, 0xd9, 0x59, 0x82, 0x94, 0xfa, 0x36, 0x41}};
+    ITrigger* pTrigger = NULL;
+    
+    hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_SESSION_STATE_CHANGE, &pTrigger);
+    if (SUCCEEDED(hr)) {
+        ISessionStateChangeTrigger* pSessionStateChangeTrigger = NULL;
+        
+        hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDISessionStateChangeTrigger, (void**)&pSessionStateChangeTrigger);
+        if (SUCCEEDED(hr)) {
+            BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
+            BSTR delayBstr = OLEAUT32$SysAllocString(delay);
+            
+            pSessionStateChangeTrigger->lpVtbl->put_StateChange(pSessionStateChangeTrigger, TASK_SESSION_LOCK);
+            pSessionStateChangeTrigger->lpVtbl->put_UserId(pSessionStateChangeTrigger, userIDBstr);
+            pSessionStateChangeTrigger->lpVtbl->put_Delay(pSessionStateChangeTrigger, delayBstr);
+            
+            OLEAUT32$SysFreeString(userIDBstr);
+            OLEAUT32$SysFreeString(delayBstr);
+            
+            pSessionStateChangeTrigger->lpVtbl->Release(pSessionStateChangeTrigger);
+        }
+        pTrigger->lpVtbl->Release(pTrigger);
+    }
+    pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+
+    return hr;
+}
+
+
+HRESULT SetUnlockTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID, wchar_t* delay) {
+    IID IIDISessionStateChangeTrigger = {0x754da71b, 0x4385, 0x4475, {0x9d, 0xd9, 0x59, 0x82, 0x94, 0xfa, 0x36, 0x41}};
+    ITrigger* pTrigger = NULL;
+    
+    hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_SESSION_STATE_CHANGE, &pTrigger);
+    if (SUCCEEDED(hr)) {
+        ISessionStateChangeTrigger* pSessionStateChangeTrigger = NULL;
+        
+        hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDISessionStateChangeTrigger, (void**)&pSessionStateChangeTrigger);
+        if (SUCCEEDED(hr)) {
+            BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
+            BSTR delayBstr = OLEAUT32$SysAllocString(delay);
+            
+            pSessionStateChangeTrigger->lpVtbl->put_StateChange(pSessionStateChangeTrigger, TASK_SESSION_UNLOCK);
+            pSessionStateChangeTrigger->lpVtbl->put_UserId(pSessionStateChangeTrigger, userIDBstr);
+            pSessionStateChangeTrigger->lpVtbl->put_Delay(pSessionStateChangeTrigger, delayBstr);
+            
+            OLEAUT32$SysFreeString(userIDBstr);
+            OLEAUT32$SysFreeString(delayBstr);
+            
+            pSessionStateChangeTrigger->lpVtbl->Release(pSessionStateChangeTrigger);
+        }
+        pTrigger->lpVtbl->Release(pTrigger);
+    }
+    pTriggerCollection->lpVtbl->Release(pTriggerCollection);
+
+    return hr;
+}
+
+
+BOOL CreateScheduledTask(char* triggerType, wchar_t* taskName, wchar_t* programPath, wchar_t* programArguments, wchar_t* startTime, wchar_t* expireTime, int daysInterval, wchar_t* delay, wchar_t* userID) {
+    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;
+    }
+	
+	//Vserver can hold remote host > Requires further testing
+	VARIANT Vserver;
+	VARIANT VNull;
+	OLEAUT32$VariantInit(&Vserver);
+	OLEAUT32$VariantInit(&VNull);
+	hr = pTaskService->lpVtbl->Connect(pTaskService, Vserver, 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);
+
+    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;
+    }
+	
+    IPrincipal* pPrincipal = NULL;
+    hr = pTaskDefinition->lpVtbl->get_Principal(pTaskDefinition, &pPrincipal);
+    if (SUCCEEDED(hr)) {
+        pPrincipal->lpVtbl->put_LogonType(pPrincipal, TASK_LOGON_INTERACTIVE_TOKEN);
+        pPrincipal->lpVtbl->Release(pPrincipal);
+    }
+
+    ITriggerCollection* pTriggerCollection = NULL;
+    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;
+    }
+
+	//trigger options
+	if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
+		hr = SetOneTimeTask(hr, pTriggerCollection, startTime);
+	} else if (MSVCRT$strcmp(triggerType, "daily") == 0) {
+		hr = SetDailyTask(hr, pTriggerCollection, startTime, expireTime, daysInterval, delay); 
+	} else if (MSVCRT$strcmp(triggerType, "logon") == 0) {
+		hr = SetLogonTask(hr, pTriggerCollection, userID); 
+	} else if (MSVCRT$strcmp(triggerType, "startup") == 0) {
+		hr = SetStartUpTask(hr, pTriggerCollection, delay); 
+	} else if (MSVCRT$strcmp(triggerType, "lock") == 0) {
+		hr = SetLockTask(hr, pTriggerCollection, userID, delay); 
+	} else if (MSVCRT$strcmp(triggerType, "unlock") == 0) {
+		hr = SetUnlockTask(hr, pTriggerCollection, userID, delay); 
+	} 
+	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;
+	}
+	
+	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;
+    }
+	
+    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;
+    }
+
+	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;
+    }
+	
+	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;
+    }
+	OLEAUT32$SysFreeString(programPathBstr);
+	
+	
+	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;
+    }
+	OLEAUT32$SysFreeString(programArgumentsBstr);
+	
+    pExecAction->lpVtbl->Release(pExecAction);
+    pAction->lpVtbl->Release(pAction);
+	
+    IRegisteredTask* pRegisteredTask = NULL;
+	hr = pTaskFolder->lpVtbl->RegisterTaskDefinition(pTaskFolder, taskName, pTaskDefinition, TASK_CREATE_OR_UPDATE, VNull, VNull, TASK_LOGON_INTERACTIVE_TOKEN, VNull, &pRegisteredTask);
+
+	if (FAILED(hr)) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to register the scheduled task with error code: %x\n", hr);
+    } 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(&Vserver);
+	OLEAUT32$VariantClear(&VNull);
+	OLE32$CoUninitialize();
+
+	return actionResult;
+}
+
+
+BOOL DeleteScheduledTask(wchar_t* taskName) {
+    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 Vserver;
+	VARIANT VNull;
+	OLEAUT32$VariantInit(&Vserver);
+	OLEAUT32$VariantInit(&VNull);
+	
+	hr = pTaskService->lpVtbl->Connect(pTaskService, Vserver, 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(&Vserver);
+	OLEAUT32$VariantClear(&VNull);
+	OLE32$CoUninitialize();
+
+    return actionResult;
+}
+
+
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	datap parser;
+	
+	CHAR *action; //create or delete
+    WCHAR *taskName; 
+    WCHAR *programPath; 
+    WCHAR *programArguments  = L""; 
+	CHAR *triggerType; //onetime, daily, logon , startup, lock, unlock
+	WCHAR *startTime; 
+    WCHAR *expireTime = L""; 
+	int daysInterval = 0; 
+	WCHAR *delay = L"";
+	WCHAR *userID  = L""; 
+	
+	BeaconDataParse(&parser, args, len);
+	action = BeaconDataExtract(&parser, NULL);
+	taskName = 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, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID);
+	}
+	else if (MSVCRT$strcmp(action, "delete") == 0) {
+		res = DeleteScheduledTask(taskName);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR,"Please specify one of the following options: create | delete\n");
+		return 0;
+	}
+	
+	return 0;
+}
+
+

+ 112 - 0
KIT/TaskScheduler/taskscheduler.cna

@@ -0,0 +1,112 @@
+# author REDMED-X
+
+beacon_command_register(
+	"taskscheduler", "Create or delete a scheduled task.\n",
+	"INFO:\nCreate or delete a scheduled task.\n\n" .
+	"BASIC PARAMETERS:\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[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 PARAMETERS:\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> <programPath> \"<(optional) programArguments>\" onetime <startTime>\ntaskscheduler create <taskName> <programPath> \"<(optional) programArguments>\" daily <startTime> <(optional) expireTime> <(optional) daysInterval> <(optional) delay>\ntaskscheduler create <taskName> <programPath> \"<(optional) programArguments>\" logon <(optional) userID>\ntaskscheduler create <taskName> <programPath> \"<(optional) programArguments>\" startup <(optional) delay>\ntaskscheduler create <taskName> <programPath> \"<(optional) programArguments>\" lock <(optional) userID> <(optional) delay>\ntaskscheduler create <taskName> <programPath> \"<(optional) programArguments>\" unlock <(optional) userID> <(optional) delay>\ntaskscheduler delete <taskName>\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 C:\\Users\\Public\\Downloads\\legit.exe \"\" logon Testdomain\\Administrator\ntaskscheduler create OneDrive C:\\Data\\OneDrive.exe \"\" unlock \"\" PT5M\ntaskscheduler delete TestTask\n\n");
+	
+alias taskscheduler {
+    $bid = $1;
+    $action = $2;
+	$taskName = $3; 
+    $programPath = $4;
+    $programArguments = $5;
+	$triggerType = $6; 
+	$optionalArg1 = $7;
+	$optionalArg2 = $8;
+	$optionalArg3 = $9;
+	$optionalArg4 = $10;
+
+
+	# 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, "zZ", $action, $taskName);
+	   blog($bid, "Tasked to delete scheduled task..");
+    }
+	else {
+		blog($bid, "Tasked to create scheduled task..");
+		if ($triggerType eq "onetime") {
+			$arg_data  = bof_pack($bid, "zZZZzZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1);
+		}
+		if ($triggerType eq "daily") {
+			$arg_data  = bof_pack($bid, "zZZZzZZiZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2, $optionalArg3, $optionalArg4);
+		}
+		if ($triggerType eq "logon") {
+			$arg_data  = bof_pack($bid, "zZZZzZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1);
+		}
+		if ($triggerType eq "startup") {
+			$arg_data  = bof_pack($bid, "zZZZzZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1);
+		}
+		if ($triggerType eq "lock") {
+			$arg_data  = bof_pack($bid, "zZZZzZZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
+		}
+		if ($triggerType eq "unlock") {
+			$arg_data  = bof_pack($bid, "zZZZzZZ", $action, $taskName, $programPath, $programArguments, $triggerType, $optionalArg1, $optionalArg2);
+		}
+	}
+	
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+
+}
+
+
+

+ 16 - 0
KIT/TaskScheduler/taskscheduler.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);
+
+
+

TEMPAT SAMPAH
KIT/TaskScheduler/taskscheduler.o