| 
 | 
 
 
 
 
本篇文章是 WMI 攻击手法研究的第二篇,主要研究  WMI 中的 3 个组件,在整篇文章中,我们将交替使用 WMI 和 CIM cmdlet,以便熟悉这两种 cmdlet 类型。 
 
一、命名空间 
 
让我们简单回顾一下命名空间是什么: 
 
命名空间结构信息类似于文件系统中文件夹,但是,与物理位置 (例如磁盘上) 不同,它们本质上更具有逻辑。  
 
WMI 中的所有命名空间都是 __Namespace 系统类的实例,要获取 root 命名空间下所有命名空间的列表,可使用以下命令查询同一个类: 
 
- Get-WmiObject -Namespace root -Class __Namespace
 
  复制代码 
 
输出的内容包含了许多信息,为了过滤掉 "无用" 信息,可使用 PowerShell 中的 select: 
 
- Get-WmiObject -Namespace root -Class __Namespace | select name
 
  复制代码 
 
现在我们从系统中得到一个命名空间的列表,许多命名空间会是这样格式出现 root\<namespace>,比如 root\DEFAULT,root\CIM2 等等,因为它们是 root (本身也是一个命名空间) 下的命名空间。 
 
注意:一个奇怪而有趣的事实是,WMI 中的默认命名空间不是 root\DeFAULT 而是 root\CIMV2 (自 Windows 2000 以来一直是这样)。  
使用 CIM cmdlet Get-CimInstance 可以实现相同目的: 
 
- Get-CimInstance -Namespace root -ClassName __Namespace
 
  复制代码 
 
 
OK,上面已整整齐齐列出来了,那嵌套的名称空间呢?我们已经看到 root 命名空间下有几个命名空间,只需要编写一个脚本,递归地获取名称空间 (来自 PSMag) 
 
- Function Get-WmiNamespace {
 
 -     Param (
 
 -         $Namespace='root'
 
 -     )
 
 -     Get-WmiObject -Namespace $Namespace -Class __NAMESPACE | ForEach-Object {
 
 -             ($ns = '{0}\{1}' -f $_.__NAMESPACE,$_.Name)
 
 -             Get-WmiNamespace $ns
 
 -     }
 
 - }
 
  复制代码 
 
注意:类和命名空间可能因机器而异,具体取决于可用硬件、安装的应用程序和许多其它因素。  
二、类 
 
现在我们有一个可用的命名空间列表,让我们来看看类,那么什么是类? 
 
WMI 类表示系统中的特定项,它可以是从系统进程到硬件 (比如网卡)、服务等任何内容。  
类分为 3 个主要类型 (这是 CIM 标准的要求): 
 
- Core classes (核心类):适用于所有管理领域,并提供很少的基本功能,它们通常以双下划线开头 (比如 __SystemSecrity);
 - Common classes (公共类):这些是核心类的扩展,适用于特定的管理领域,以 CIM_ 为前缀 (比如 CIM_TemperatureSensor);
 - Extended classes (扩展类):这些是对基于技术堆栈的常见类的额外添加 (例如 Win32_Process);
 
 
  
类进一步分为以下类型: 
 
- Abstract classes (抽象类):定义新类的模板;
 - Static classes (静态类):主要用于存储数据;
 - Dynamic classes (动态类):从 Provider 取回数据,代表 WMI 托管资源,我们最感兴趣的是这种类型的类;
 - Association classes (关联类):描述类和托管资源之间的关系;
 
 
  
2.1 列出类 
 
有了足够的理论支撑,让我们尝试寻找一些类,我们可以使用 Get-WmiObject cmdlet 列出可用的类: 
 
- Get-WmiObject -Class * -List
 
  复制代码 
上面这条命令将会列出所有类,但为了举例,假设我们对系统上的用户感兴趣。可以使用以下命令来缩小范围,该命令列出了用于获取或操作用户信息的所有可用类: 
 
- Get-WmiObject -Class *user* -List
 
  复制代码 
 
 
同样也可以使用 Get-CimClass 命令也能实现同样的效果,如下所示: 
 
- Get-CimClass -ClassName *user*
 
  复制代码 
 
 
注意:有关所有 Win32 类的列表,可以参考 Microsoft 的类文档。 Win32 Provider 提供 4 个不同类别的类:计算机系统硬件类、操作系统类、性能计数器类和 WMI 服务管理类。  
若要获取动态类,可以使用 Get-CimClass cmdlet 的 -QualiferName 参数: 
 
- Get-CimClass -ClassName "user" -QualifierName dynamic
 
  复制代码 
 
 
看起来不错,下一步该如何操作?查询类以从中获取更多东西。 
 
2.2 获取类 
 
我们对 Win32_UserAccount 类感兴趣,通过如下命令可简单获取数据: 
 
- Get-WmiObject -Class Win32_UserAccount
 
  复制代码 
 
提示:要获得更详细的输出,可以将上述命令通过管道传输到 Powershell 的 Format-List 或 fl 中,例如:Get-WmiObject -Class Win32_UserAccount | fl *   
CIM cmdlet Get-CimInstance 能获取相同的信息: 
 
- Get-CimInstance -ClassName Win32_UserAccount
 
  复制代码 
 
 
现在我们有了系统上所有用户帐户的列表! 
 
让我们将注意力转向系统上运行的进程,Win32_Process 类为我们提供了系统上运行的进程列表: 
 
- Get-WmiObject -Class Win32_Process
 
  复制代码 
许多进程在系统上运行,这可能会使终端上显示的内容无休止地滚动,这种情况并不少见!为了避免这种情况,我们可以使用 -Filter 参数来获取我们正在寻找的特定进程 (这里选择了 lsass.exe): 
 
- Get-WmiObject -Class Win32_Process -Filter 'name="lsass.exe"'
 
  复制代码 
 
 
在这种情况下,CIM cmdlet 替代方法 Get-CimInstance 提供了更短、更全面的输出 (并且它还支持 -Filter 参数): 
 
 
 
对 WQL 执行相同操作的表达式如下: 
 
- Get-WmiObject -Query 'select * from win32_process where name="lsass.exe"'
 
  复制代码 
现在我们知道在 WMI 中列出、获取和过滤类的实例,让我们看看在 WMI 中删除实例是如何工作的。 
 
2.3 删除类实例 
 
Remove-WmiObject (WMI cmdlet) 和 Remove-CimInstance (CIM cmdlet) 是两个具有删除实例功能的 cmdlet。可以将相关命令的输出通过管道传输到 cmdlet。为了快速演示,运行计算器应用程序并列出过程。 
 
 
 
如果我们通过管道将命令传递给 Remove-CimInstance 会发生什么? 进程被杀死! 
 
- Get-CimInstance -ClassName Win32_Process -Filter 'name="calculator.exe"' | Remove-CimInstance
 
  复制代码 
 
 
这在处理 Registry 时非常有用,或者更好,在我们创建自己的类来存储我们的 Payloads 的情况下,我们可以简单地使用 cmdlet 列出类下的所有项目,从而将它们全部清理干净,一气呵成。 
 
三、方法 
 
方法可操作 WMI 对象,如果向上滚动到我们列出所有可用类的位置,你会注意到一个名为 Methods 的列,其中列出了可用的方法。 
 
3.1 列出方法 
 
要重复我们的工作并列出所有可用的方法,可以执行以下操作: 
 
- Get-CimClass -MethodName *
 
  复制代码 
为了过滤掉允许我们执行特定方法的实例,可以传递一个方法名称,例如 Create (这总是很有趣,因为它可能允许我们创建一些东西): 
 
- Get-CimClass -MethodName Create
 
  复制代码 
 
 
进一步缩小范围,列出特定类的可用方法,需要使用 Powershell 的 select 和 -ExpandProperty 参数: 
 
- Get-WmiObject -Class Win32_Process -List | select -ExpandProperty Methods
 
 - Get-CimClass -ClassName Win32_Process | select -ExpandProperty CimClassMethods
 
  复制代码 
 
 
注意:传递给 select 语句的值是我们在列出类时得到的列的名称。如果你感到困惑,请向上滚动到我们列出类的部分,并观察 WMI 和 CIM cmdlet 输出之间的差异。  
因此,对于 Win32_Process 类,我们有 Create、Terminate、GetOwner、GetOwnerSid 等方法。现在让我们看看如何使用方法。 
 
提示:要使用一个方法,我们需要知道调用该方法时需要提供哪些参数。要列出所有可用参数,我们可以结合使用 Powershell,或者更好地阅读 文档。  
3.2 使用方法 
Invoke-WmiMethod (WMI) 和 Invoke-CimMethod (CIM cmdlet) 允许我们使用特定类的方法。又是拿计算器开刀   : 
 
- Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList calc.exe
 
  复制代码 
 
 
要使用 CIM cmdlet,语法略有不同: 
 
- Invoke-CimMethod -ClassName Win32_Process -MethodName create -Arguments @{commandline="calc.exe"}
 
  复制代码 
 
 
四、设置对象属性 
 
最后但并非最不重要的一点,我们应该看看更新类的实例。但是,重要的是要记住实例应该是可写的。通过编写一些脚本,我们可以编写一个获取类的所有可写属性的方法。这是脚本 (来自 PSMag): 
 
- $class = [wmiclass]'<class_name>'
 
 - $class.Properties | ForEach-Object {
 
 -     foreach ($qualifier in $_.Qualifiers) {
 
 -         if ($qualifier.Name -eq "Write") {
 
 -             $_.Name
 
 -         }
 
 -     }
 
 - }
 
  复制代码 
对于我们的示例,我们将使用 Win32_OperatingSystem 类,该类具有一个名为 Description 的可写属性。 
 
 
 
让我们使用 Set-WmiInstance 将属性名称更新为 PewOS: 
 
 
 
使用 Set-CimInstance 也可以实现相同的效果,但这留给读者去探索。 
 
五、结论 
 
哇,又是一篇长文!到目前为止,我们已经对 WMI 和 CIM cmdlet 以及如何使用它们实现对系统的重要控制打下了坚实的基础,干杯!  
 
 
 
 |   
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册 
 
 
 
x
 
 
 
 
 |