| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- #include <stdio.h>
- #include <windows.h>
- #include <taskschd.h>
- #include <combaseapi.h>
- #include "enumtaskscheduler.h"
- #include "beacon.h"
- //START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
- #ifndef bufsize
- #define bufsize 8192
- #endif
- char *output = 0;
- WORD currentoutsize = 0;
- HANDLE trash = NULL;
- int bofstart();
- void internal_printf(const char* format, ...);
- void printoutput(BOOL done);
- int bofstart() {
- output = (char*)MSVCRT$calloc(bufsize, 1);
- currentoutsize = 0;
- return 1;
- }
- void internal_printf(const char* format, ...){
- int buffersize = 0;
- int transfersize = 0;
- char * curloc = NULL;
- char* intBuffer = NULL;
- va_list args;
- va_start(args, format);
- buffersize = MSVCRT$vsnprintf(NULL, 0, format, args);
- va_end(args);
-
- if (buffersize == -1) return;
-
- char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
- intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
- va_start(args, format);
- MSVCRT$vsnprintf(intBuffer, buffersize, format, args);
- va_end(args);
- if(buffersize + currentoutsize < bufsize)
- {
- MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
- currentoutsize += buffersize;
- } else {
- curloc = intBuffer;
- while(buffersize > 0)
- {
- transfersize = bufsize - currentoutsize;
- if(buffersize < transfersize)
- {
- transfersize = buffersize;
- }
- MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
- currentoutsize += transfersize;
- if(currentoutsize == bufsize)
- {
- printoutput(FALSE);
- }
- MSVCRT$memset(transferBuffer, 0, transfersize);
- curloc += transfersize;
- buffersize -= transfersize;
- }
- }
- KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
- KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
- }
- void printoutput(BOOL done) {
- char * msg = NULL;
- BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
- currentoutsize = 0;
- MSVCRT$memset(output, 0, bufsize);
- if(done) {MSVCRT$free(output); output=NULL;}
- }
- //END TrustedSec BOF print code.
- BOOL EnumScheduledTasks(wchar_t * host) {
- HRESULT hr = S_OK;
- hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
- if (FAILED(hr)) return FALSE;
- 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)) {
- return FALSE;
- }
-
- 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)) {
- goto cleanup;
- }
-
- ITaskFolder* pRootFolder = NULL;
- hr = pTaskService->lpVtbl->GetFolder(pTaskService, L"\\", &pRootFolder);
- if (FAILED(hr)) {
- goto cleanup;
- }
-
- IRegisteredTaskCollection* pTaskCollection = NULL;
- hr = pRootFolder->lpVtbl->GetTasks(pRootFolder, 0, &pTaskCollection);
- if (FAILED(hr)) {
- goto cleanup;
- }
- long numTasks = 0;
- hr = pTaskCollection->lpVtbl->get_Count(pTaskCollection, &numTasks);
- internal_printf("[+] Scheduled tasks in root folder:\n");
- internal_printf("=======================================================\n\n");
- for (long i = 1; i <= numTasks; i++) {
- IRegisteredTask* pRegisteredTask = NULL;
- VARIANT index;
- index.vt = VT_I4;
- index.lVal = i;
- hr = pTaskCollection->lpVtbl->get_Item(pTaskCollection, index, &pRegisteredTask);
- if (SUCCEEDED(hr)) {
- BSTR taskName = NULL;
- hr = pRegisteredTask->lpVtbl->get_Name(pRegisteredTask, &taskName);
- if (SUCCEEDED(hr)) {
- internal_printf("Task Name: %ls\n", taskName);
- OLEAUT32$SysFreeString(taskName);
- }
-
-
- ITaskDefinition* pTaskDef = NULL;
- hr = pRegisteredTask->lpVtbl->get_Definition(pRegisteredTask, &pTaskDef);
- if (SUCCEEDED(hr)) {
-
-
- // Fetching the Principal information and print the user account
- IPrincipal* pPrincipal = NULL;
- hr = pTaskDef->lpVtbl->get_Principal(pTaskDef, &pPrincipal);
- if (SUCCEEDED(hr)) {
- BSTR userId = NULL;
- hr = pPrincipal->lpVtbl->get_UserId(pPrincipal, &userId);
- if (SUCCEEDED(hr)) {
- internal_printf("- Task running as: %ls\n", userId);
- OLEAUT32$SysFreeString(userId);
- }
- pPrincipal->lpVtbl->Release(pPrincipal);
- }
- // Fetching Action Information
- ITaskDefinition* pTaskDef = NULL;
- hr = pRegisteredTask->lpVtbl->get_Definition(pRegisteredTask, &pTaskDef);
- if (SUCCEEDED(hr)) {
- IActionCollection* pActionColl = NULL;
- hr = pTaskDef->lpVtbl->get_Actions(pTaskDef, &pActionColl);
- if (SUCCEEDED(hr)) {
- long actionCount = 0;
- hr = pActionColl->lpVtbl->get_Count(pActionColl, &actionCount);
- if (SUCCEEDED(hr)) {
- for (long j = 1; j <= actionCount; j++) {
- IAction* pAction = NULL;
- long actionIndex = j;
- hr = pActionColl->lpVtbl->get_Item(pActionColl, actionIndex, &pAction);
- if (SUCCEEDED(hr)) {
- TASK_ACTION_TYPE actionType;
- hr = pAction->lpVtbl->get_Type(pAction, &actionType);
- if (SUCCEEDED(hr)) {
- WCHAR* actionTypes[] = {
- L"Start a program",
- L"Send an e-mail (Deprecated)",
- L"Display a message (Deprecated)"
- };
- WCHAR* actionTypeName = actionTypes[actionType]; // Using actionType as an index
- internal_printf("- Action type: %ls\n", actionTypeName);
- if (actionType == TASK_ACTION_EXEC) {
- IExecAction* pExecAction = (IExecAction*) pAction;
- BSTR execPath;
- hr = pExecAction->lpVtbl->get_Path(pExecAction, &execPath);
- if (SUCCEEDED(hr)) {
- internal_printf("- Executable path: %ls\n", execPath);
- OLEAUT32$SysFreeString(execPath);
- }
- }
- }
- pAction->lpVtbl->Release(pAction);
- }
- }
- }
- }
- }
-
- // Fetching Trigger Information
- ITriggerCollection* pTriggerColl = NULL;
- hr = pTaskDef->lpVtbl->get_Triggers(pTaskDef, &pTriggerColl);
- if (SUCCEEDED(hr)) {
- long triggerCount = 0;
- hr = pTriggerColl->lpVtbl->get_Count(pTriggerColl, &triggerCount);
- if (SUCCEEDED(hr)) {
- for (long j = 1; j <= triggerCount; j++) {
- ITrigger* pTrigger = NULL;
- long triggerIndex = j;
- hr = pTriggerColl->lpVtbl->get_Item(pTriggerColl, triggerIndex, &pTrigger);
- if (SUCCEEDED(hr)) {
- TASK_TRIGGER_TYPE2 triggerType;
- hr = pTrigger->lpVtbl->get_Type(pTrigger, &triggerType);
- if (SUCCEEDED(hr)) {
- static const WCHAR* triggerTypeNames[] = {
- L"On an event", // 1
- L"On a schedule", // 2
- L"Daily", // 3
- L"Weekly", // 4
- L"Monthly", // 5
- L"MonthlyDOW", // 6
- L"On idle", // 7
- L"At task creation/modification", // 8
- L"At startup", // 9
- L"At log on", // 10
- L"SessionStateChange (lock/unlock/connection)", // 11
- L"SessionStateChange (lock/unlock/connection)" // 12
- };
- const WCHAR* triggerTypeName = (triggerType >= 0 && triggerType < sizeof(triggerTypeNames) / sizeof(triggerTypeNames[0]))
- ? triggerTypeNames[triggerType]
- : L"Unknown";
- internal_printf("- Trigger type: %ls\n", triggerTypeName);
- }
- pTrigger->lpVtbl->Release(pTrigger);
- }
- }
- }
- pTriggerColl->lpVtbl->Release(pTriggerColl);
- }
- pTaskDef->lpVtbl->Release(pTaskDef);
- }
- if (pRegisteredTask) {
- pRegisteredTask->lpVtbl->Release(pRegisteredTask);
- }
- }
- internal_printf("----------------------------------------------------\n\n");
- }
- cleanup:
- if (pTaskCollection) {
- pTaskCollection->lpVtbl->Release(pTaskCollection);
- }
- if (pRootFolder) {
- pRootFolder->lpVtbl->Release(pRootFolder);
- }
- if (pTaskService) {
- pTaskService->lpVtbl->Release(pTaskService);
- }
- OLEAUT32$VariantClear(&Vhost);
- OLE32$CoUninitialize();
- return TRUE;
- }
- int go(char *args, int len) {
- BOOL res = NULL;
- datap parser;
- WCHAR *hostName = L"";
-
- BeaconDataParse(&parser, args, len);
- hostName = BeaconDataExtract(&parser, NULL);
- if(!bofstart()) return;
- res = EnumScheduledTasks(hostName);
- if(!res) BeaconPrintf(CALLBACK_ERROR, "Failed to enumerate scheduled tasks.\n");
- else {
- printoutput(TRUE);
- BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating!\n");
- }
- return 0;
- }
-
-
|