![](/style/images/good.png)
![](/style/images/bad.png)
渗透基础——Windows下计划任务的使用
source link: https://3gstudent.github.io/3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-Windows%E4%B8%8B%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1%E7%9A%84%E4%BD%BF%E7%94%A8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
![neoserver,ios ssh client](/neoserver-download.png)
0x00 前言
在渗透测试中,尤其是域渗透,常常会用到Windows系统的计划任务,一是用于远程启动程序,二是用于程序的自启动
那么,计划任务具体有哪些使用技巧呢?是否对权限有要求?一定需要管理员权限才能运行吗?
0x01 简介
本文将要介绍以下内容:
- 命令行实现
- c++实现
- 不同权限下创建计划任务的区别
- COM组件ITaskService能否提权运行
- 命令行开启和关闭计划任务
0x02 简介
官方说明文档:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446802(v=vs.85).aspx
需要开启服务Task Scheduler
可在以下情况触发:
- When a specific system event occurs.
- At a specific time.
- At a specific time on a daily schedule.
- At a specific time on a weekly schedule.
- At a specific time on a monthly schedule.
- At a specific time on a monthly day-of-week schedule.
- When the computer enters an idle state.
- When the task is registered.
- When the system is booted.
- When a user logs on.
- When a Terminal Server session changes state.
计划任务创建后,会在C:\Windows\System32\Tasks
保存XML格式的配置文件
0x03 计划任务的配置方式
1、界面操作
执行taskschd.msc,如下图
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/2-1.png)
选中Task Scheduler Library
,右键 -> Create Task...
弹出界面,逐个配置即可,如下图
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/2-2.png)
2、命令行配置
(1) at 命令
(管理员权限)
at 23:53 notepad.exe
默认以system权限启动,适用于Win7
从Win8开始不再支持at命令,所以不过多介绍
(2) schtasks命令
支持Win7-Win10
1.每天固定时间,以普通权限启动notepad.exe
命令如下:
schtasks /Create /TN TestService1 /SC DAILY /ST 01:02 /TR notepad.exe
C:\Windows\System32\Tasks
产生新文件TestService1,内容如下:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2018-05-23T17:21:00</Date>
<Author>a</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2018-05-23T01:02:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>notepad.exe</Command>
</Exec>
</Actions>
<Principals>
<Principal id="Author">
<UserId>WIN-R7MM90ERBMD\a</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
</Task>
值得注意的是<RunLevel>LeastPrivilege</RunLevel>
,代表权限为普通用户
2.每天固定时间,以system权限启动notepad.exe
命令如下(管理员权限):
schtasks /Create /TN TestService2 /SC DAILY /ST 01:02 /TR notepad.exe /RL HIGHEST
C:\Windows\System32\Tasks
产生新文件TestService2,内容如下:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2018-05-23T17:23:23</Date>
<Author>a</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2018-05-23T01:02:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<RunLevel>HighestAvailable</RunLevel>
<UserId>WIN-R7MM90ERBMD\a</UserId>
<LogonType>InteractiveToken</LogonType>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>notepad.exe</Command>
</Exec>
</Actions>
</Task>
值得注意的是<RunLevel>HighestAvailable</RunLevel>
,代表权限为最高,一般为System权限
3.每天固定时间,以system权限启动notepad.exe,通过导入xml文件的方式
以文件TestService2作为模板,修改启动时间,保存为1.xml,内容如下:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2018-05-23T17:23:23</Date>
<Author>a</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2018-05-23T01:03:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<RunLevel>HighestAvailable</RunLevel>
<UserId>WIN-R7MM90ERBMD\a</UserId>
<LogonType>InteractiveToken</LogonType>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>notepad.exe</Command>
</Exec>
</Actions>
</Task>
通过xml文件导入配置,建立计划任务,以system权限启动,命令如下(管理员权限):
schtasks /create /xml c:\test\1.xml /tn TestService3
注:
如果是一个新的系统,修改<Author>
、<Date>
、<StartBoundary>
、<UserId>
和<Command>
即可
4.每天固定时间,以普通权限启动notepad.exe,通过导入xml文件的方式
修改1.xml:
<RunLevel>HighestAvailable</RunLevel>
改为<RunLevel>LeastPrivilege</RunLevel>
即可
导入配置的命令如下:
schtasks /create /xml c:\test\1.xml /tn TestService4
补充:schtasks的其他命令用法
查看服务状态:
schtasks /Query /TN TestService1
删除服务:
schtasks /Delete /TN TestService1 /F
注:
服务执行成功后不会自动删除
0x04 编写程序实现
官方文档:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa383614(v=vs.85).aspx
c++定时启动程序的实现实例:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa383624(v=vs.85).aspx
程序实现了在特定时间启动notepad.exe
通过分析源码,发现是调用了COM组件ITaskService
于是产生了一个新问题,能否通过COM组件ITaskService越权执行?
答案是不能,原因如下:
首先,在c代码中能够找到CLSID_TaskScheduler
对应的GUID,位于taskschd.h文件中
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/3-1.png)
GUID为"0f87369f-a4e5-4cfc-bd3e-73e6154572dd"
查看注册表信息,路径为HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}
信息如下图
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/3-2.png)
未发现注册表项Elevation
,也就是说这个COM组件ITaskService不支持使用COM Elevation Moniker提升权限
那么,能否通过添加注册表项Elevation
实现COM组件提升权限呢?
答案也是不可以,测试如下:
修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}
,需要TrustedInstaller权限
关于如何获得TrustedInstaller权限可参考文章《渗透技巧——Token窃取与利用》
接下来添加注册表项Elevation
,值为1
添加LocalizedString
,值为C:\Windows\system32\taskschd.dll
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/3-3.png)
修改官方的实例代码,添加使用COM Elevation Moniker提升权限的代码,关键代码如下:
HWND hwnd = GetConsoleWindow();
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2( CLSID_TaskScheduler,wszCLSID,sizeof(wszCLSID)/sizeof(wszCLSID[0]));
hr = StringCchPrintf(wszMonikerName,sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),L"Elevation:Administrator!new:%s", wszCLSID);
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
hr = CoGetObject(wszMonikerName, &bo, IID_PPV_ARGS(&pService));
程序报错,而且没有弹出需要提升权限的UAC对话框,对其跟踪调试,如下图
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/3-4.png)
提示(ERROR_INVALID_DATA) : 数据无效
通过IDA静态分析taskschd.dll,查看Function
没有发现提升权限的函数(关键词Elevated、Admin)
接下来尝试将LocalizedString
修改为其他可用的路径
LocalizedString
设置为@%SystemRoot%\system32\shell32.dll,-50176
(COM组件IFileOperation的值)
执行过程弹出需要提升权限的UAC对话框,接下来报错,如下图
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/3-5.png)
提示REGDB_E_CLASSNOTREG Class not registered
表示这个组件不支持ITaskService::Connect
和预期的一样,shell32.dll不包含函数ITaskService::Connect
综上,不能简单的通过修改注册表就能使一个普通的COM组件支持权限提升
接下来介绍一下C++代码在实现上的细节
1、添加计划任务,定时以普通权限执行程序
直接参考示例代码即可,地址如下:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa383624(v=vs.85).aspx
修改源代码的启动时间,去掉结束时间
2、添加计划任务,定时以system权限执行程序
需要管理员权限
上面的代码直接以管理员权限运行是不可以的,这是因为并没有指定以最高权限启动
![Alt text](https://raw.githubusercontent.com/3gstudent/BlogPic/master/2018-5-24/4-1.png)
需要修改源代码,添加指定以HIGHEST权限启动
关键代码如下:
// ------------------------------------------------------
// Create the principal for the task - these credentials
// are overwritten with the credentials passed to RegisterTaskDefinition
IPrincipal *pPrincipal = NULL;
hr = pTask->get_Principal( &pPrincipal );
if( FAILED(hr) )
{
printf("\nCannot get principal pointer: %x", hr );
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
}
// Set up principal logon type to interactive logon
hr = pPrincipal->put_LogonType( TASK_LOGON_INTERACTIVE_TOKEN );
// pPrincipal->Release();
if( FAILED(hr) )
{
printf("\nCannot put principal info: %x", hr );
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
}
//
hr = pPrincipal->put_RunLevel( TASK_RUNLEVEL_HIGHEST );
pPrincipal->Release();
if( FAILED(hr) )
{
printf("\nCannot put principal info: %x", hr );
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
}
当然,以普通权限启动会提示权限不够,如下图
0x05 TaskScheduler日志
日志类别: Microsoft-Windows-TaskScheduler
保存位置: C:\Windows\System32\winevt\Logs
TaskScheduler日志功能默认关闭
开启方法:
注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-TaskScheduler/Operational
键Enabled设为1(默认为0)
cmd命令如下:
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-TaskScheduler/Operational" /v Enabled /t REG_DWORD /d 1 /f
统计日志列表,查询所有日志信息,包含时间,数目:
wevtutil gli Microsoft-Windows-TaskScheduler/Operational
查看日志内容:
wevtutil qe Microsoft-Windows-TaskScheduler/Operational
删除该类日志所有内容:
wevtutil cl Microsoft-Windows-TaskScheduler/Operational
删除单条日志:
该部分放在之后的文章进行详细介绍
0x06 小结
本文介绍了计划任务的常用内容,包括多种创建计划任务的方法,不同权限创建计划任务的区别,经测试得出了一个结论,COM组件ITaskService无法提权运行
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK