addtaskscheduler.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <taskschd.h>
  4. #include <combaseapi.h>
  5. #include "addtaskscheduler.h"
  6. #include "beacon.h"
  7. HRESULT SetOneTimeTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* startTime, wchar_t* repeatTask) {
  8. IID IIDITimeTrigger = {0xb45747e0, 0xeba7, 0x4276, {0x9f, 0x29, 0x85, 0xc5, 0xbb, 0x30, 0x00, 0x06}};
  9. ITrigger* pTrigger = NULL;
  10. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_TIME, &pTrigger);
  11. if (SUCCEEDED(hr)) {
  12. ITimeTrigger* pTimeTrigger = NULL;
  13. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDITimeTrigger, (void**)&pTimeTrigger);
  14. if (SUCCEEDED(hr)) {
  15. BSTR startTimeBstr = OLEAUT32$SysAllocString(startTime);
  16. pTimeTrigger->lpVtbl->put_StartBoundary(pTimeTrigger, startTimeBstr);
  17. IRepetitionPattern* pRepetitionPattern = NULL;
  18. hr = pTimeTrigger->lpVtbl->get_Repetition(pTimeTrigger, &pRepetitionPattern);
  19. if (SUCCEEDED(hr)) {
  20. BSTR repeatTaskBstr = OLEAUT32$SysAllocString(repeatTask);
  21. BSTR durationBstr = OLEAUT32$SysAllocString(L""); // Indefinite duration
  22. pRepetitionPattern->lpVtbl->put_Interval(pRepetitionPattern, repeatTaskBstr);
  23. pRepetitionPattern->lpVtbl->put_Duration(pRepetitionPattern, durationBstr);
  24. pRepetitionPattern->lpVtbl->Release(pRepetitionPattern);
  25. OLEAUT32$SysFreeString(repeatTaskBstr);
  26. OLEAUT32$SysFreeString(durationBstr);
  27. }
  28. pTimeTrigger->lpVtbl->put_Repetition(pTimeTrigger, pRepetitionPattern);
  29. OLEAUT32$SysFreeString(startTimeBstr);
  30. pTimeTrigger->lpVtbl->Release(pTimeTrigger);
  31. }
  32. pTrigger->lpVtbl->Release(pTrigger);
  33. }
  34. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  35. return hr;
  36. }
  37. HRESULT SetDailyTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* startTime, wchar_t* expireTime, int daysInterval, wchar_t* delay) {
  38. IID IIDIDailyTrigger = {0x126c5cd8, 0xb288, 0x41d5, {0x8d, 0xbf, 0xe4, 0x91, 0x44, 0x6a, 0xdc, 0x5c}};
  39. ITrigger* pTrigger = NULL;
  40. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_DAILY, &pTrigger);
  41. if (SUCCEEDED(hr)) {
  42. IDailyTrigger* pDailyTrigger = NULL;
  43. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDIDailyTrigger, (void**)&pDailyTrigger);
  44. if (SUCCEEDED(hr)) {
  45. BSTR startTimeBstr = OLEAUT32$SysAllocString(startTime);
  46. BSTR expireTimeBstr = OLEAUT32$SysAllocString(expireTime);
  47. BSTR delayBstr = OLEAUT32$SysAllocString(delay);
  48. pDailyTrigger->lpVtbl->put_StartBoundary(pDailyTrigger, startTimeBstr);
  49. pDailyTrigger->lpVtbl->put_EndBoundary(pDailyTrigger, expireTimeBstr);
  50. pDailyTrigger->lpVtbl->put_DaysInterval(pDailyTrigger, daysInterval);
  51. pDailyTrigger->lpVtbl->put_RandomDelay(pDailyTrigger, delayBstr);
  52. pDailyTrigger->lpVtbl->Release(pDailyTrigger);
  53. OLEAUT32$SysFreeString(startTimeBstr);
  54. OLEAUT32$SysFreeString(expireTimeBstr);
  55. OLEAUT32$SysFreeString(delayBstr);
  56. }
  57. pTrigger->lpVtbl->Release(pTrigger);
  58. }
  59. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  60. return hr;
  61. }
  62. HRESULT SetLogonTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID) {
  63. IID IIDILogonTrigger = {0x72dade38, 0xfae4, 0x4b3e, {0xba, 0xf4, 0x5d, 0x00, 0x9a, 0xf0, 0x2b, 0x1c}};
  64. ITrigger* pTrigger = NULL;
  65. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_LOGON, &pTrigger);
  66. if (SUCCEEDED(hr)) {
  67. ILogonTrigger* pLogonTrigger = NULL;
  68. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDILogonTrigger, (void**)&pLogonTrigger);
  69. if (SUCCEEDED(hr)) {
  70. BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
  71. pLogonTrigger->lpVtbl->put_UserId(pLogonTrigger, userIDBstr);
  72. pLogonTrigger->lpVtbl->Release(pLogonTrigger);
  73. OLEAUT32$SysFreeString(userIDBstr);
  74. }
  75. pTrigger->lpVtbl->Release(pTrigger);
  76. }
  77. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  78. return hr;
  79. }
  80. HRESULT SetStartUpTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* delay) {
  81. IID IIDIBootTrigger = {0x2a9c35da, 0xd357, 0x41f4, {0xbb, 0xc1, 0x20, 0x7a, 0xc1, 0xb1, 0xf3, 0xcb}};
  82. ITrigger* pTrigger = NULL;
  83. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_BOOT, &pTrigger);
  84. if (SUCCEEDED(hr)) {
  85. IBootTrigger* pBootTrigger = NULL;
  86. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDIBootTrigger, (void**)&pBootTrigger);
  87. if (SUCCEEDED(hr)) {
  88. BSTR delayBstr = OLEAUT32$SysAllocString(delay);
  89. pBootTrigger->lpVtbl->put_Delay(pBootTrigger, delayBstr);
  90. pBootTrigger->lpVtbl->Release(pBootTrigger);
  91. OLEAUT32$SysFreeString(delayBstr);
  92. }
  93. pTrigger->lpVtbl->Release(pTrigger);
  94. }
  95. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  96. return hr;
  97. }
  98. HRESULT SetLockTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID, wchar_t* delay) {
  99. IID IIDISessionStateChangeTrigger = {0x754da71b, 0x4385, 0x4475, {0x9d, 0xd9, 0x59, 0x82, 0x94, 0xfa, 0x36, 0x41}};
  100. ITrigger* pTrigger = NULL;
  101. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_SESSION_STATE_CHANGE, &pTrigger);
  102. if (SUCCEEDED(hr)) {
  103. ISessionStateChangeTrigger* pSessionStateChangeTrigger = NULL;
  104. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDISessionStateChangeTrigger, (void**)&pSessionStateChangeTrigger);
  105. if (SUCCEEDED(hr)) {
  106. BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
  107. BSTR delayBstr = OLEAUT32$SysAllocString(delay);
  108. pSessionStateChangeTrigger->lpVtbl->put_StateChange(pSessionStateChangeTrigger, TASK_SESSION_LOCK);
  109. pSessionStateChangeTrigger->lpVtbl->put_UserId(pSessionStateChangeTrigger, userIDBstr);
  110. pSessionStateChangeTrigger->lpVtbl->put_Delay(pSessionStateChangeTrigger, delayBstr);
  111. OLEAUT32$SysFreeString(userIDBstr);
  112. OLEAUT32$SysFreeString(delayBstr);
  113. pSessionStateChangeTrigger->lpVtbl->Release(pSessionStateChangeTrigger);
  114. }
  115. pTrigger->lpVtbl->Release(pTrigger);
  116. }
  117. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  118. return hr;
  119. }
  120. HRESULT SetUnlockTask(HRESULT hr, ITriggerCollection* pTriggerCollection, wchar_t* userID, wchar_t* delay) {
  121. IID IIDISessionStateChangeTrigger = {0x754da71b, 0x4385, 0x4475, {0x9d, 0xd9, 0x59, 0x82, 0x94, 0xfa, 0x36, 0x41}};
  122. ITrigger* pTrigger = NULL;
  123. hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_SESSION_STATE_CHANGE, &pTrigger);
  124. if (SUCCEEDED(hr)) {
  125. ISessionStateChangeTrigger* pSessionStateChangeTrigger = NULL;
  126. hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IIDISessionStateChangeTrigger, (void**)&pSessionStateChangeTrigger);
  127. if (SUCCEEDED(hr)) {
  128. BSTR userIDBstr = OLEAUT32$SysAllocString(userID);
  129. BSTR delayBstr = OLEAUT32$SysAllocString(delay);
  130. pSessionStateChangeTrigger->lpVtbl->put_StateChange(pSessionStateChangeTrigger, TASK_SESSION_UNLOCK);
  131. pSessionStateChangeTrigger->lpVtbl->put_UserId(pSessionStateChangeTrigger, userIDBstr);
  132. pSessionStateChangeTrigger->lpVtbl->put_Delay(pSessionStateChangeTrigger, delayBstr);
  133. OLEAUT32$SysFreeString(userIDBstr);
  134. OLEAUT32$SysFreeString(delayBstr);
  135. pSessionStateChangeTrigger->lpVtbl->Release(pSessionStateChangeTrigger);
  136. }
  137. pTrigger->lpVtbl->Release(pTrigger);
  138. }
  139. pTriggerCollection->lpVtbl->Release(pTriggerCollection);
  140. return hr;
  141. }
  142. BOOL IsElevated() {
  143. BOOL fIsElevated = FALSE;
  144. HANDLE hToken = NULL;
  145. if (ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
  146. TOKEN_ELEVATION elevation;
  147. DWORD dwSize;
  148. if (ADVAPI32$GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) {
  149. fIsElevated = elevation.TokenIsElevated;
  150. }
  151. }
  152. if (hToken) {
  153. KERNEL32$CloseHandle(hToken);
  154. }
  155. return fIsElevated;
  156. }
  157. 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) {
  158. BOOL actionResult = FALSE;
  159. HRESULT hr = S_OK;
  160. hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
  161. if (FAILED(hr)) return actionResult;
  162. IID CTaskScheduler = {0x0f87369f, 0xa4e5, 0x4cfc, {0xbd,0x3e,0x73,0xe6,0x15,0x45,0x72,0xdd}};
  163. IID IIDITaskService = {0x2faba4c7, 0x4da9, 0x4013, {0x96, 0x97, 0x20, 0xcc, 0x3f, 0xd4, 0x0f, 0x85}};
  164. ITaskService *pTaskService = NULL;
  165. hr = OLE32$CoCreateInstance(&CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IIDITaskService, (void**)&pTaskService);
  166. if (FAILED(hr)) {
  167. //MSVCRT$printf("Failed to create ITaskService: %x\n", hr); //DEBUG
  168. return actionResult;
  169. }
  170. VARIANT Vhost;
  171. VARIANT VNull;
  172. OLEAUT32$VariantInit(&Vhost);
  173. OLEAUT32$VariantInit(&VNull);
  174. Vhost.vt = VT_BSTR;
  175. Vhost.bstrVal = OLEAUT32$SysAllocString(host);
  176. hr = pTaskService->lpVtbl->Connect(pTaskService, Vhost, VNull, VNull, VNull);
  177. if (FAILED(hr)) {
  178. //MSVCRT$printf("ITaskService::Connect failed: %x\n", hr); //DEBUG
  179. goto cleanup;
  180. }
  181. ITaskFolder* pTaskFolder = NULL;
  182. BSTR folderPathBstr = OLEAUT32$SysAllocString(L"\\");
  183. hr = pTaskService->lpVtbl->GetFolder(pTaskService, folderPathBstr, &pTaskFolder);
  184. if (FAILED(hr)) {
  185. //MSVCRT$printf("ITaskService::GetFolder failed: %x\n", hr); //DEBUG
  186. goto cleanup;
  187. }
  188. OLEAUT32$SysFreeString(folderPathBstr);
  189. ITaskDefinition* pTaskDefinition = NULL;
  190. hr = pTaskService->lpVtbl->NewTask(pTaskService, 0, &pTaskDefinition);
  191. if (FAILED(hr)) {
  192. goto cleanup;
  193. }
  194. IPrincipal* pPrincipal = NULL;
  195. hr = pTaskDefinition->lpVtbl->get_Principal(pTaskDefinition, &pPrincipal);
  196. if (SUCCEEDED(hr)) {
  197. if (IsElevated()) {
  198. BeaconPrintf(CALLBACK_OUTPUT, "[*] Running in elevated context and setting \"Run whether user is logged on or not\" security option!\n");
  199. BSTR systemUser = OLEAUT32$SysAllocString(L"SYSTEM");
  200. pPrincipal->lpVtbl->put_UserId(pPrincipal, systemUser);
  201. OLEAUT32$SysFreeString(systemUser);
  202. }else {
  203. pPrincipal->lpVtbl->put_LogonType(pPrincipal, TASK_LOGON_INTERACTIVE_TOKEN);
  204. }
  205. pPrincipal->lpVtbl->Release(pPrincipal);
  206. }
  207. ITriggerCollection* pTriggerCollection = NULL;
  208. hr = pTaskDefinition->lpVtbl->get_Triggers(pTaskDefinition, &pTriggerCollection);
  209. if (FAILED(hr)) {
  210. //MSVCRT$printf("ITaskDefinition::get_Triggers failed: %x\n", hr); //DEBUG
  211. goto cleanup;
  212. }
  213. //trigger options
  214. if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
  215. hr = SetOneTimeTask(hr, pTriggerCollection, startTime, repeatTask);
  216. } else if (MSVCRT$strcmp(triggerType, "daily") == 0) {
  217. hr = SetDailyTask(hr, pTriggerCollection, startTime, expireTime, daysInterval, delay);
  218. } else if (MSVCRT$strcmp(triggerType, "logon") == 0) {
  219. hr = SetLogonTask(hr, pTriggerCollection, userID);
  220. } else if (MSVCRT$strcmp(triggerType, "startup") == 0) {
  221. hr = SetStartUpTask(hr, pTriggerCollection, delay);
  222. } else if (MSVCRT$strcmp(triggerType, "lock") == 0) {
  223. hr = SetLockTask(hr, pTriggerCollection, userID, delay);
  224. } else if (MSVCRT$strcmp(triggerType, "unlock") == 0) {
  225. hr = SetUnlockTask(hr, pTriggerCollection, userID, delay);
  226. }
  227. else {
  228. //MSVCRT$printf("[-] [%ls] is not a supported trigger type\n", triggerType); //DEBUG
  229. goto cleanup;
  230. }
  231. IActionCollection* pActionCollection = NULL;
  232. hr = pTaskDefinition->lpVtbl->get_Actions(pTaskDefinition, &pActionCollection);
  233. if (FAILED(hr)) {
  234. goto cleanup;
  235. }
  236. IAction* pAction = NULL;
  237. hr = pActionCollection->lpVtbl->Create(pActionCollection, TASK_ACTION_EXEC, &pAction);
  238. if (FAILED(hr)) {
  239. goto cleanup;
  240. }
  241. IID IIDIExecAction = {0x4c3d624d, 0xfd6b, 0x49a3, {0xb9, 0xb7, 0x09, 0xcb, 0x3c, 0xd3, 0xf0, 0x47}};
  242. IExecAction* pExecAction = NULL;
  243. hr = pAction->lpVtbl->QueryInterface(pAction, &IIDIExecAction, (void**)&pExecAction);
  244. if (FAILED(hr)) {
  245. goto cleanup;
  246. }
  247. BSTR programPathBstr = OLEAUT32$SysAllocString(programPath);
  248. hr = pExecAction->lpVtbl->put_Path(pExecAction, programPathBstr);
  249. if (FAILED(hr)) {
  250. goto cleanup;
  251. }
  252. OLEAUT32$SysFreeString(programPathBstr);
  253. BSTR programArgumentsBstr = OLEAUT32$SysAllocString(programArguments);
  254. hr = pExecAction->lpVtbl->put_Arguments(pExecAction, programArgumentsBstr);
  255. if (FAILED(hr)) {
  256. goto cleanup;
  257. }
  258. OLEAUT32$SysFreeString(programArgumentsBstr);
  259. pExecAction->lpVtbl->Release(pExecAction);
  260. pAction->lpVtbl->Release(pAction);
  261. IRegisteredTask* pRegisteredTask = NULL;
  262. hr = pTaskFolder->lpVtbl->RegisterTaskDefinition(pTaskFolder, taskName, pTaskDefinition, TASK_CREATE_OR_UPDATE, VNull, VNull, TASK_LOGON_INTERACTIVE_TOKEN, VNull, &pRegisteredTask);
  263. if (FAILED(hr)) {
  264. BeaconPrintf(CALLBACK_ERROR, "Failed to register the scheduled task with error code: %x\n", hr);
  265. } else {
  266. BeaconPrintf(CALLBACK_OUTPUT, "[+] Scheduled task '%ls' created successfully!\n", taskName);
  267. actionResult = TRUE;
  268. }
  269. cleanup:
  270. if (pRegisteredTask) {
  271. pRegisteredTask->lpVtbl->Release(pRegisteredTask);
  272. }
  273. if (pActionCollection) {
  274. pActionCollection->lpVtbl->Release(pActionCollection);
  275. }
  276. if (pTaskDefinition) {
  277. pTaskDefinition->lpVtbl->Release(pTaskDefinition);
  278. }
  279. if (pTaskFolder) {
  280. pTaskFolder->lpVtbl->Release(pTaskFolder);
  281. }
  282. if (pTaskService) {
  283. pTaskService->lpVtbl->Release(pTaskService);
  284. }
  285. OLEAUT32$VariantClear(&Vhost);
  286. OLEAUT32$VariantClear(&VNull);
  287. OLE32$CoUninitialize();
  288. return actionResult;
  289. }
  290. int go(char *args, int len) {
  291. BOOL res = NULL;
  292. datap parser;
  293. WCHAR *taskName;
  294. WCHAR *hostName = L"";
  295. WCHAR *programPath;
  296. WCHAR *programArguments = L"";
  297. CHAR *triggerType; //onetime, daily, logon , startup, lock, unlock
  298. WCHAR *startTime;
  299. WCHAR *expireTime = L"";
  300. int daysInterval = 0;
  301. WCHAR *delay = L"";
  302. WCHAR *userID = L"";
  303. WCHAR *repeatTask = L"";
  304. BeaconDataParse(&parser, args, len);
  305. taskName = BeaconDataExtract(&parser, NULL);
  306. hostName = BeaconDataExtract(&parser, NULL);
  307. programPath = BeaconDataExtract(&parser, NULL);
  308. programArguments = BeaconDataExtract(&parser, NULL);
  309. triggerType = BeaconDataExtract(&parser, NULL);
  310. if (MSVCRT$strcmp(triggerType, "onetime") == 0) {
  311. startTime = BeaconDataExtract(&parser, NULL);
  312. repeatTask = BeaconDataExtract(&parser, NULL);
  313. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  314. }
  315. else if (MSVCRT$strcmp(triggerType, "daily") == 0) {
  316. startTime = BeaconDataExtract(&parser, NULL);
  317. expireTime = BeaconDataExtract(&parser, NULL);
  318. daysInterval = BeaconDataInt(&parser);
  319. delay = BeaconDataExtract(&parser, NULL);
  320. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  321. }
  322. else if (MSVCRT$strcmp(triggerType, "logon") == 0) {
  323. userID = BeaconDataExtract(&parser, NULL);
  324. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  325. }
  326. else if (MSVCRT$strcmp(triggerType, "startup") == 0) {
  327. delay = BeaconDataExtract(&parser, NULL);
  328. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  329. }
  330. else if (MSVCRT$strcmp(triggerType, "lock") == 0) {
  331. userID = BeaconDataExtract(&parser, NULL);
  332. delay = BeaconDataExtract(&parser, NULL);
  333. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  334. }
  335. else if (MSVCRT$strcmp(triggerType, "unlock") == 0) {
  336. userID = BeaconDataExtract(&parser, NULL);
  337. delay = BeaconDataExtract(&parser, NULL);
  338. res = CreateScheduledTask(triggerType, taskName, hostName, programPath, programArguments, startTime, expireTime, daysInterval, delay, userID, repeatTask);
  339. }
  340. else {
  341. BeaconPrintf(CALLBACK_ERROR, "Specified triggerType is not supported.\n");
  342. }
  343. return 0;
  344. }