之前写过《红队视角下的Windows RPC》,本文来聊聊ScheduleTask(计划任务),在红队视角里的一些利用,本文并不是像之前的文章十分正式,以看懂为准,所以大量使用GPT-4来帮助编写(节省时间)。
Windows 计划任务(Task Scheduler)是 Microsoft Windows 系统内置的一种服务,用于在预定时间或在特定事件发生时自动执行程序或脚本。这是一种基础的自动化工具,可以用来执行各种系统和非系统任务,例如创建备份、运行系统维护任务、启动第三方应用程序等。
计划任务的用户界面可以通过控制面板或管理工具(如 taskschd.msc
)访问。这个界面提供了创建和管理任务的各种功能,包括启动和停止任务、查看任务的运行历史、配置任务的属性等。
在计划任务中创建新任务时,你需要配置以下信息:
此外,计划任务还提供了一个命令行工具 schtasks.exe
,你可以使用这个工具在命令行界面或脚本中创建和管理任务。
使用计划任务时,你需要注意以下几点:
在 Windows 系统中,有多种方法可以用来添加计划任务:
你可以使用 Windows 的 "任务计划程序" 工具来创建计划任务。这是一个图形用户界面工具,你可以通过以下步骤来使用它:
taskschd.msc
并按回车。 Windows 也提供了一个命令行工具 schtasks
,你可以使用这个工具来创建计划任务。例如,以下命令会创建一个每天早上 9 点运行 Notepad 的任务:
schtasks /create /tn "MyTask" /tr "notepad.exe" /sc daily /st 09:00
在这个命令中,/tn
参数是任务的名称,/tr
参数是任务要执行的操作,/sc
参数是任务的调度(如每日、每周等),/st
参数是任务的开始时间。
你也可以使用 PowerShell 来创建计划任务。以下是一个创建计划任务的 PowerShell 脚本示例:
$Action = New-ScheduledTaskAction -Execute "notepad.exe"
$Trigger = New-ScheduledTaskTrigger -At 9am -Daily
Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName "MyTask" -Description "Run Notepad every day at 9am"
在这个脚本中,New-ScheduledTaskAction
创建了一个新的任务操作,New-ScheduledTaskTrigger
创建了一个新的任务触发器,Register-ScheduledTask
注册了新的计划任务。
以上就是在 Windows 中添加计划任务的一些常见方法。需要注意的是,创建计划任务通常需要管理员权限。如果你在创建计划任务时遇到问题,你应该检查你是否有足够的权限。
上面都是正常人添加计划任务的一些方法,但是红队中,一般不是正常人,需要用到一些脱裤子放屁的方法来绕过一些规则或是杀软的监控。
一般大家添加计划任务大都为了权限维持,是我们的程序在目标主机常驻,下面列举一些公开的添加计划任务的方法。
上面GPT-4帮我们说了,有定时执行任务还有事件驱动执行任务,使用COM接口ITaskService
,可以编写程序添加一个计划任务。
时间触发器的例子:
https://learn.microsoft.com/en-us/windows/win32/taskschd/time-trigger-example--scripting-?source=recommendations
登录触发器的例子:
https://learn.microsoft.com/en-us/windows/win32/taskschd/logon-trigger-example--c---?source=recommendations
程序功能分为三部分,首先是初始化,其次是添加计划任务,最后添加了删除计划任务功能。
为了获取到获取 ITaskService 对象以及 ITaskFolder 对象
首先初始化COM接口
// 初始化 COM
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // 设置 COM security levels.
hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);
// 创建Task Service对象
hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
// 连接到Task Service
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
首先创建任务定义对象,进行任务创建操作
hr = pService->NewTask(0, &pTask);
接着设置注册信息
hr = pTask->get_RegistrationInfo(&pRegInfo);
//作者
hr = pRegInfo->put_Author(_bstr_t(wszAuthor));
//描述
hr = pRegInfo->put_Description(_bstr_t(wszDescription));
设置主体信息
hr = pTask->get_Principal(&pPrincipal);
// 设置登陆类型
hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); // 设置运行权限
hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
设置任务相关信息
hr = pTask->get_Settings(&pSettings); hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
hr = pSettings->get_IdleSettings(&pIdleSettings);
创建触发器
hr = pTask->get_Triggers(&pTriggerCollection);
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
设置执行操作
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
//设置程序路径等信息
hr = pExecAction->put_Path(_bstr_t(wszProgramPath));
......
在ITaskFolder对象注册
hr = pRootFolder->RegisterTaskDefinition(_bstr_t(wszTaskName), pTask, TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask);
直接根据事先写好的名字删除即可
hr = pRootFolder->DeleteTask(_bstr_t(TaskName), 0);
实际上COM添加计划任务最终是由RPC接口ITaskSchedulerService
来实现的,以前写过:《Windows RPC之MS-TSCH添加计划任务》
需要UAC后进行调用。
头像哥的这个非常之牛逼,参考文章:https://www.zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html
利用一个IElevatedFactoryServer
COM接口达到使用计划任务Bypass UAC的效果,同时因为进程外COM的缘故,天然也是一个断链技术。
在实战中使用也是非常好用:
可以挖掘一些白文件是否存在此类问题。
通过RPC接口ITaskSchedulerService
同样RPC bind到远程主机就可以实现横向移动,有不错的免杀性。
本文只是介绍下目前公开的一些计划任务在红队中的利用,很多人可能会说其中的很多方法可能过不了某些杀软之类的,其中提到的方法均有对抗杀软的办法比如360核晶,权限维持的很多方法(不局限于计划任务)绕过什么核晶对很多兄弟是很简单的事情,所以本文并不关注这些技术的杀软绕过方法。
可以进入星球多补补课