WMI内部机制Part2:逆向分析WMIProvider

admin 2026-03-09 01:44:33 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章以Register-ScheduledTask为例,详细展示了从PowerShell命令追踪至底层COM方法调用的逆向分析全过程。通过解析CDXML映射、定位WMIProvider二进制文件schedprov.dll,利用IDA分析确认WMI类最终调用了ITaskService::NewTask方法。该分析揭示了WMI封装COM接口的机制,有助于攻防人员深入理解系统底层交互原理。 综合评分: 88 文章分类: 逆向分析,二进制安全,实战经验


cover_image

WMI 内部机制 Part 2:逆向分析 WMI Provider

Jonathan Johnson Jonathan Johnson

securitainment

2026年3月7日 23:09 中国香港

| 原文链接 | 作者 | | — | — | | https://jonny-johnson.medium.com/wmi-internals-part-2-522f3e97709a | Jonathan Johnson |

在上一篇文章 WMI Internals Part 1: Understanding the Basics 中,我梳理了 WMI 的一些基础内部机制。那篇文章旨在为理解本文奠定必要的背景知识——本文将深入剖析 WMI 类调用 COM 方法来完成请求操作的常见模式。

掌握如何拆解这些技术并通过二进制分析观察它们之间的交互流程,有助于我们更深入地理解依赖这些技术的攻击手法。这对防御方和攻击方的安全研究人员同样重要。

注意:最初构思本文时,我计划从一个 WMI 类出发,逐步分解各个函数直至 COM 方法的调用过程。然而在寻找合适的示例时,我发现了一个最终会调用 WMI 类的 PowerShell 函数,因此我们将从这个函数开始分析。

分析流程

步骤 1:确定 PowerShell 命令。在本示例中,我们将聚焦于计划任务,具体来说是 Register-ScheduledTask:

上面的命令表明 Register-ScheduledTask 是一个函数 (function),而非 PS cmdlet。为了进一步理解这个函数,我们可以通过 Get-Command来提取相关信息。查看该函数的代码后可以确定,调用完成后将返回类型为 Microsoft.Management.Infrastructure.CimInstance#MSFT_ScheduledTask的输出对象。但进一步分析可以发现,该函数默认使用 ParameterSetName “User”,最终会调用 RegisterByUser方法,而这个方法似乎是通过 PS_ScheduledTask类来实现的。

在此之前我从未遇到过这种模式的 PowerShell 命令,于是我向 Matt Graeber 请教。他告诉我这是 cmdlet 定义 XML (CDXML)。简单来说,CDXML 文件定义了 PowerShell cmdlet 与 WMI 类/方法之间的映射关系。CDXML 本质上是 WMI 类的自动生成脚本封装。

步骤 2:找到 CDXML 文件:

经过一番查找,我发现 PS_ScheduledTask 的 cdxml 文件位于 _C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ScheduledTasks\_PS_ScheduledTask_v1.0.cdxml。该文件显示 WMI 类名为 PS_ScheduledTask,位于 _Root/Microsoft/Windows/TaskScheduler_WMI 命名空间中。

步骤 3:查找 PS_ScheduledTask 类的 WMI Provider:

Get-CimClass -Namespace root/Microsoft/Windows/TaskScheduler -ClassName PS_ScheduledTask | Select-Object -ExpandProperty CimClassQualifiers

以下命令会查询 TaskScheduler命名空间并筛选 provider 名称。当匹配到 ScheduledTaskProv时,会输出一个 GUID 值。这个 GUID 就是 CLSID,通过它可以定位到 WMI Provider 对应的二进制文件。

步骤 4:获取 WMI Provider 二进制文件:

现在我们知道 schedprov.dll 就是 PS_ScheduledTask:RegisterByUser方法对应的 WMI Provider。

注意:这是一种快捷的查询方式,通过查询注册表也可以达到同样的目的。

步骤 5:分析 WMI Provider (schedprov.dll):

在 IDA 中打开该文件后,打开函数窗口并搜索 _RegisterByUser_,可以看到一个名为 PS_ScheduledTask_Invoke_RegisterByUser的函数。

可以看到,该函数会立即跳转到另一个名为 ScheduledTask_Invoke_RegisterByUser的函数。分析这个函数块后,我们会发现其中有一处调用了 CoCreateInstance。

该函数负责创建 COM 类对象,共有 5 个参数,其中我们重点关注以下 3 个:

  • rclsid (参数 1) — “与用于创建对象的数据和代码相关联的 CLSID。”
  • rrid (参数 4) — “用于与对象通信的接口标识符的引用。”
  • ppv (参数 5) — “接收 riid 中所请求接口指针的指针变量地址。”

可以看到,IDA 已经将 CLSID (CLSID_TaskScheduler — 0F87369F-A4E5-4CFC-BD3E-73E6154572DD) 的值填充为正确的符号。接下来,我们看到一个 GUID,它表示该操作所属的 COM 接口。通过 OleViewDotNet 可以确认该值对应的是 ITaskService。

最后,如果我们想要确定调用了哪些 COM 方法,就需要跟踪 ppv。假设 CoCreateInstance 调用成功,程序会跳转到另一个代码块。跟踪前面的代码可以发现,ppv 的特定偏移量被调用了,这说明在应用正确的结构体之后,我们应该能够识别出被调用的具体方法。下面分别展示反编译和汇编两种视角的示例。

在确认 ITaskServices 接口被调用之后,我开始专门查找与创建新任务相关的调用。在跳转进入几个 CreateNewTaskDefnition函数后,最终找到了被调用的 NewTask 方法,如下所示。

反编译示例

如果我们知道 ppv 保存了被调用 COM 方法的偏移量,就可以将对应的结构体应用到 ppv 上,从而看到具体调用了哪些方法。

应用结构体后可以看到,调用的是 ITaskService::NewTask

汇编示例

PPV 和 var_218 指向同一内存位置。可以看到 var_218 被解引用两次,随后调用了偏移 50h 处的内容。这个偏移量对应的是 ITaskService接口中被调用的 COM 方法。

在确保加载了正确的类型库后,我们可以添加结构体类型 ITaskServiceVtbl_。将鼠标悬停在 50h 上并应用结构体偏移,可以看到它对应的是ITaskServiceVtbl.Connect_ 方法。沿用相同的分析方法,可以发现代码后续还调用了 _ITaskServiceVtbl.NewTask_。

通过搜索 ITaskService::NewTask,我找到了描述该 COM 方法的 Microsoft 官方文档:

综合分析

通过对 WMI Provider 二进制文件 (schedprov.dll) 进行二进制分析,我们确认了 WMI 类 PS_ScheduledTask最终调用的是 COM 方法 _NewTask::ITaskService_。我们今天分析过程中经历的函数调用流程如下所示:

本文旨在揭示某些技术在底层是如何调用其他技术来完成任务的。需要注意的是,并非所有 WMI 类都遵循这种模式——尽管 WMI 是基于 COM 构建且采用类似 COM 的结构,某些 WMI 类可能只是调用 Win32 API 来完成其任务。攻击依赖于操作系统暴露的技术接口,理解这些底层概念有助于我们更深入地理解相关技术,进而更好地理解利用这些技术的攻击手法。

如果你在跟随代码或 MSFT 文档同步阅读,可能会好奇在这之后是否还有更深层的组件。答案是肯定的。下一篇博客将进一步讲解如何从 COM 方法的调用追踪到 RPC 方法的调用。

致谢

感谢 Matt Graeber 和 Alex Ionescu 审阅本文。一如既往地感谢你们抽出时间、乐于帮助他人成长!


免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:securitainment Jonathan Johnson Jonathan Johnson《WMI 内部机制 Part 2:逆向分析 WMI Provider》

评论:0   参与:  0