# WMI

WMIC (Windows 管理仪表) 是一项 Windows 管理功能，它为本地和远程访问 Windows 系统组件提供统一的环境。系统管理员可以创建 VBScript 或 PowerShell 脚本来管理本地和远程的 Windows 主机。WMI 也是横向移动和远程代码执行的原生方式，它需要本地管理员权限。

### **WMI 基础**

在 WMI 中，命名空间是类的逻辑容器，它允许以层次结构组织类，每个命名空间可以包含**类**、**类的实例**或**其他命名空间**。WMI 使用命名空间来避免类之间的命名冲突。WMI中的根命名空间是 **Root**，Root下有几个标准的命名空间，如 **CIMV2**、**Security**、**StandardCimv2** 等。

WMI 中的类是定义一种托管对象类型的架构，类似于数据库中的表。 每个类都有一个属性列表，这些属性定义了类实例的数据字段，以及可以在类实例上执行的操作的方法。例如，在 **Root\\CIMV2** 命名空间中，有一个名为 **Win32\_Process** 的类，它代表一个运行在 Windows 系统上的进程。 Win32\_Process 类具有 **Name** 和 **ProcessID** 等属性，提供有关每个进程的信息，以及 Create 和 Terminate 等可用于控制进程的方法。

通常，要执行 WMI 操作，我们需要指定包含要使用的**类的命名空间**以及**类的名称**。 例如，要创建一个新进程，我们可以使用 **Root\\CIMV2** 命名空间中的 **Win32\_Process** 类，并调用该类的 **Create** 方法。接下来，我们通过 PowerShell 命令熟悉一下 WMI。

列举所有命名空间，需要提升特权：

```powershell
Get-WmiObject -Class "__Namespace" -Namespace "Root" -List -Recurse 2> $null | select __Namespace | sort __Namespace
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/Mkkt5XkmzoVIqY8n-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/Mkkt5XkmzoVIqY8n-image.png)

列举 **root\\cimv2** 中的命名空间：

```powershell
Get-WmiObject -Class "__Namespace" -Namespace "root\cimv2" -List -Recurse 2> $null | select __Namespace | sort __Namespace
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/a3PH2cdsXHaSaq2l-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/a3PH2cdsXHaSaq2l-image.png)

罗列有关 **Win32\_process** 的类，如果不指定命名空间，默认是 **root\\cimv2**。

```powershell
Get-WmiObject -Recurse -List -class win32_process*
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/w6bhRiZsu6BQBYVg-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/w6bhRiZsu6BQBYVg-image.png)

WMI 还支持基于 SQL 语法的查询，我们可以用如下查询做到相同的事情：

```powershell
Get-WmiObject -Query 'Select * From Meta_Class WHERE __Class Like "win32_process%"'
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/UlIMQshDg1TKBP3G-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/UlIMQshDg1TKBP3G-image.png)

调用 **Win32\_process** 类以查看进程的相关信息

```powershell
Get-WmiObject -Class win32_process | select Name,ProcessId,CommandLine
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/OcjePxmihJbmf15D-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/OcjePxmihJbmf15D-image.png)

调用 Win32\_process 类的 Create 方法来创建新的进程：

```powershell
$process=[wmiclass]"win32_process"
$process.Create("calc.exe",$null,$null)
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/IylGFqyjbvfl3fcO-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/IylGFqyjbvfl3fcO-image.png)

###  

### **wmic.exe**

无论是枚举信息还是执行任务，wmic.exe 都很得心应手，wmic 对类添加了别名，例如 **Win32\_process** 在 wmic 里可以通过 **process** 进行访问。不提供任何选项，直接运行 wmi.exe 会进入交互式控制航，可以查看所有类。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/rUeUdaKTvXWg8K71-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/rUeUdaKTvXWg8K71-image.png)

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/x5vQoxqrriu9PLUi-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/x5vQoxqrriu9PLUi-image.png)

我们可以通过如下的原生命令给远程主机创建新的进程：

```powershell
wmic /node:<主机> /user:<用户名> /password:<密码> process call create "<命令>" 
```

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/4CMkKCmkCRcpa9s0-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/4CMkKCmkCRcpa9s0-image.png)

然后发现在目标主机上该进程确实存在了。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/X8GTWiUbpCV80bbt-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/X8GTWiUbpCV80bbt-image.png)

将要启动的进程换为载荷，便能实现横向移动了。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/P8RzYPv7DUfuiywc-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/P8RzYPv7DUfuiywc-image.png)

### **C2** 

##### **remote-exec wmi**

我们会发现没有 jump wmi 的选项，只有 **remote-exec wmi**。remote-exec 方法使用的其实就是 **process call create** 来执行任意命令。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/EdFvnrLBWZmwQ7At-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/EdFvnrLBWZmwQ7At-image.png)

因此，我们可以先上传载荷文件到目标主机上，再使用 remote-exec 来执行。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/dP4v36p7H7IpIBJ0-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/dP4v36p7H7IpIBJ0-image.png)

### **第三方工具**

##### **Impacket**

Impacket 中的 wmiexec 同样可用于横向移动，不过返回的是**半交互式 Shell**。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/BEGh38ZqGsn5BqkA-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/BEGh38ZqGsn5BqkA-image.png)

因为 wmiexec 会将输出写入文件，因此会带来 IoC，静默命令以及取消输出可以改善这一问题。

[![image.png](https://raven-medicine.com/uploads/images/gallery/2023-06/scaled-1680-/as0Ihynu3ARAGHU2-image.png)](https://raven-medicine.com/uploads/images/gallery/2023-06/as0Ihynu3ARAGHU2-image.png)

XiaoLi 修改后的 wmiexec 脚本 ([https://github.com/XiaoliChan/wmiexec-RegOut](https://github.com/XiaoliChan/wmiexec-RegOut)) 通过注册表读写输出，也是一个不错的方法。