Skip to main content

WMI

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

wmi.WMI 基础

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

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

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

列举所有命名空间,需要提升特权:

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

image.png

列举 root\cimv2 中的命名空间:

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

image.png

罗列有关 Win32_process 的类,如果不指定命名空间,默认是 root\cimv2

Get-WmiObject -Recurse -List -class win32_process*

image.png

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

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

image.png

调用 Win32_process 类以查看进程的相关信息

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

image.png

调用 Win32_process 类的 Create 方法来创建新的进程:

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

image.png

 

wmic.exe

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

image.png

image.png

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

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

image.png

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

image.png

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

image.png

C2 

remote-exec wmi

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

image.png

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

image.png


第三方工具

Impacket

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

image.png

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

image.png

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