| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- #include <stdio.h>
- #include <windows.h>
- #include <taskschd.h>
- #include <combaseapi.h>
- #include "enumtaskscheduler.h"
- #include "beacon.h"
- //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)); // Clear print buffer.
- }
- 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;
- }
- 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);
- BeaconPrintToStreamW(L"[+] Scheduled tasks in root folder:\n");
- BeaconPrintToStreamW(L"=======================================================\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)) {
- BeaconPrintToStreamW(L"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)) {
- BeaconPrintToStreamW(L"- 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
- BeaconPrintToStreamW(L"- Action type: %s\n", actionTypeName);
- if (actionType == TASK_ACTION_EXEC) {
- IExecAction* pExecAction = (IExecAction*) pAction;
- BSTR execPath;
- hr = pExecAction->lpVtbl->get_Path(pExecAction, &execPath);
- if (SUCCEEDED(hr)) {
- BeaconPrintToStreamW(L"- 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";
- BeaconPrintToStreamW(L"- Trigger type: %s\n", triggerTypeName);
- }
- pTrigger->lpVtbl->Release(pTrigger);
- }
- }
- }
- pTriggerColl->lpVtbl->Release(pTriggerColl);
- }
- pTaskDef->lpVtbl->Release(pTaskDef);
- }
- if (pRegisteredTask) {
- pRegisteredTask->lpVtbl->Release(pRegisteredTask);
- }
- }
- BeaconPrintToStreamW(L"----------------------------------------------------\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);
- res = EnumScheduledTasks(hostName);
- if(!res) BeaconPrintf(CALLBACK_ERROR, "Failed to enumerate scheduled tasks.\n");
- else {
- BeaconOutputStreamW();
- BeaconPrintf(CALLBACK_OUTPUT, "[+] Done enumerating!\n");
- }
- return 0;
- }
-
-
|