文章总结: 本文是WindowsIPC系列第八部分,深入介绍了三种RPC内部研究工具:RPCView、NtObjectManager和RPCMon。RPCView作为GUI工具可查看系统进程暴露的RPC服务器信息;NtObjectManager是PowerShell模块,用于解析RPC服务器和创建客户端;RPCMon则监控进程间RPC通信。作者通过一个简单RPC服务器示例展示了这些工具的实际应用,强调了它们在RPC研究和本地权限提升中的价值。这些工具各有优劣,结合使用能更有效地进行安全研究。
综合评分: 89
文章分类: 二进制安全,内网渗透,安全工具,WEB安全,漏洞分析
Windows 进程间通信深度剖析 – 超越表面 – 第 8 部分
sud0ru
securitainment
2025年11月18日 10:24
中国香港
欢迎来到 IPC 系列的新篇章,本篇原本应该是我大约三个月前开始的第一波系列的最终章节。然而,我将这一波扩展到了另外一部分,届时我将讨论 RPC 服务器的逆向工程。
本篇是上一篇文章的延续,在上一篇中我们讨论了 RPC 研究工具。在那篇文章中,我们提到了在研究过程中可以使用的外部工具集。今天,我们将继续这一旅程,讨论内部研究工具。
正如我之前提到的,您使用的环境(外部或内部)会改变研究的最终目标。内部 RPC 研究最有趣的目标是本地权限提升。虽然外部工具主要依赖于 Impacket,但内部工具基于不同的编程语言,每个工具都有不同的用途。
在本篇博客文章中,我不会深入探讨这些工具的内部工作原理,因为它相当复杂。我会在第二波系列中进行解释,届时我们将讨论 RPC 模型的动态分析。
相反,我们今天的工作流程将很简单。我们将使用一个作为可执行文件运行的基础 RPC 服务器,并在该服务器上测试所有工具,以了解我们可以从每个工具中获取哪些信息以及在哪种场景下每个工具是有用的。
我们将从一个名为 RPCView的工具开始,这是一个 GUI 工具,可让您查看所有系统进程中暴露的 RPC 服务器。之后,我们将研究 NtObjectManager模块以及如何将其用于 RPC 研究。接下来,我们将检查 RPCMon,这是一个解析整个系统中 RPC 日志的工具。
那么让我们开始吧…
测试环境 (Testbed):
我们的测试环境很简单。我们将使用之前在另一篇博客文章中使用过的 RPC 服务器之一。您可以在这里找到它。该服务器是基础的:它暴露一个接口,并且该接口暴露一个函数。
该函数从客户端接收一个字符串并返回一个整数,在我们的例子中是 3。
IDL 文件中的函数定义如下所示:
interface ExampleInter
{
int PrintString([in, string] const char* str);
}
接口 UUID 是:
12345678-1234-1234-1234-123456789abc
并且服务器通过 ALPC 端口暴露一个端点 (endpoint)。ALPC 端口的名称是 example_endpoint。
这就是我们需要了解的关于服务器的所有信息。所以让我们编译它并开始测试我们之前提到的每个工具。
RPCView:
RPCView 是一个免费且开源的工具,它可以让您查看系统进程暴露的所有 RPC 接口。它还显示有关每个接口的有用详细信息,例如其端点 (endpoints)、可用函数和基本属性。其最有用的功能之一是反编译选项卡 (decompilation tab),您可以在其中查看暴露的函数、它们的参数以及它们使用的数据类型。
该工具的内部逻辑超出了本文的范围,但有一个很好的博客解释了它的工作原理。简而言之,该工具扫描系统上的每个进程,并读取 RPC runtime库内的 RPC 结构体以收集有关 RPC 服务器的信息。
现在让我们用我们的服务器测试它。在运行服务器后,我们打开该工具。
RPCView 界面显示接口信息
如您所见,RPCView 正确识别了接口 UUID、过程 (procedures) 的数量以及接口所在的位置。它还显示注册标志 (registration flags),即 0x20。这与我们的代码匹配,其中我们使用 C_IF_ALLOW_LOCAL_ONLY。RPCView 还检测到端点类型和端点名称。
另一个有用的功能是反编译选项卡 (decompilation tab),它几乎重建了原始的 IDL 文件。要打开它,右键单击接口 UUID 并选择 Decompile。
RPCView 反编译选项卡
结果非常接近实际的 IDL 文件。
从中,我们可以清楚地看到该函数接收一个字符串并返回一个整数。
RPCView 还提供其他有用的窗口。例如,Interface Properties显示诸如回调地址 (callback address) (如果存在) 之类的内容,并将标志值从十六进制转换为可读字符串。Procedures窗口提供有关每个函数的更多详细信息,包括其内存地址。
RPCView 过程窗口
这个工具能够提取如此多的信息令人印象深刻。然而,正如我之前提到的,我们将在该系列的第二波中学习如何手动执行此操作。
当您想要快速获取有关 RPC 服务器的信息而不进行深度逆向工程时,RPCView 非常有用。它为您提供构建客户端所需的一切:如何访问服务器、接口 UUID、注册标志以及如何正确调用函数。
在我们的示例中,该函数使用简单类型,但我也用更复杂的数据结构测试了 RPCView,在大多数情况下它运行良好。
唯一的缺点是 RPCView 最适合手动检查。当处理大量 RPC 服务器时,它变得更难使用。
NtObjectManager:
我在我的博客和研究中多次提到过 NtObjectManager。它是 Windows 研究中最有用的工具之一。它支持许多 Windows 内部功能,它作为 PowerShell 模块工作 (因此您不需要编译任何东西),最重要的是,它是开源的。
NtObjectManager 也支持 RPC。这意味着您可以使用它来解析 RPC 服务器、提取接口,甚至生成或创建 RPC 客户端。该模块中的 RPC 功能通过在将二进制文件加载到内存后解析特定的数据结构来工作。
有一篇博客解释了这在内部是如何工作的,我们稍后也会在本系列的下一部分中介绍这一点。
许多博客文章展示了如何在 RPC 研究中使用此模块,我强烈建议查看这篇以了解所有可用选项。
现在让我们用我们的服务器测试该模块。安装和运行该模块超出了本博客文章的范围,但它非常简单,您可以按照我之前分享的链接进行操作。
到目前为止,我们的分析将是静态的,这意味着我们不需要运行 RPC 服务器。
需要记住的一个重要事项:
如果您将服务器编译为 32 位,则需要使用 32 位 PowerShell。如果服务器是 64 位,请使用 64 位 PowerShell。
我们将使用的第一个命令是 Get-RpcServer,它从 DLL 或 EXE 中提取接口。
Get-RpcServer 命令输出
从输出中可以看到,它成功识别了暴露的 UUID 和过程的数量。我们可以使用 fl *显示服务器对象的更多属性。
服务器对象的详细属性
如照片所示,该模块未能提取端点,并且它还报告该 EXE 没有 RPC 客户端。
我们还可以提取有关过程的信息。在我们的例子中,我们只有一个。
过程信息输出
从输出中,我们可以看到该过程有一个类型为 string的输入参数,并且它返回一个 long值。
在我们讨论创建客户端之前,我们必须解决一个问题:
NtObjectManager 未能检测到端点。
使用 NtObjectManager 有几种方法可以获取端点。其中之一是使用 WinAPIs 在本地查询端点映射器服务 (endpoint mapper service)。命令 Get-RpcEndpoint与端点映射器数据库交互以搜索特定接口的端点。
Get-RpcEndpoint 命令输出
然而,正如我们所知,并非所有 RPC 服务器都在端点映射器数据库中注册它们的端点。此外,服务器必须正在运行才能使此方法工作,而在我们的静态分析中情况并非如此。
现在让我们看看如何使用从 server.exe提取的信息创建客户端。
创建 RPC 客户端
客户端已创建,但我们必须提供端点并将其连接到服务器。
不要忘记此时启动服务器。
要连接客户端,请使用 Connect-RpcClient命令:
Connect-RpcClient $client -StringBinding "ncalrpc:[example_endpoint]"
这里我们手动添加了端点。
连接后,我们可以通过查看 Connected属性来检查客户端状态。然后我们可以列出支持的过程。
连接后的客户端状态和可用过程
如您所见,Proc0是服务器接口暴露的函数,我们现在可以从 PowerShell 调用它。
调用 Proc0 函数
函数调用成功,服务器按预期返回了 3。
如果我们检查服务器输出,我们可以看到我们作为函数参数发送的字符串。
服务器输出显示接收到的字符串
如您所见,在运行时解析服务器并连接到客户端非常容易。您不需要编写或编译任何代码,这在 RPC 研究或构建模糊测试器 (fuzzer) 时非常有帮助。
主要问题是端点提取。如果您正在处理一个或两个服务器,手动查找端点很容易。但是当您需要自动化时,缺失的端点会成为真正的挑战。
RPCMon:
开发者在 GitHub 上这样描述 RPCMon:
RPCMon 可以帮助研究人员获得进程间 RPC 通信的高层视图。它的构建类似于 Procmon,易于使用,并使用 James Forshaw 的 .NET RPC 库。RPCMon 可以向您显示正在调用的 RPC 函数、调用它们的进程以及其他相关信息。RPCMon 使用硬编码的 RPC 字典进行快速处理,其中包含有关许多 RPC 模块的信息。它还提供了一个选项来构建您自己的 RPC 数据库,以便该工具可以从您的系统更新缺失的详细信息。
我认为这个描述已经清楚地说明了该工具的作用。简而言之,它显示两个进程之间通过 RPC 的通信,包括调用了哪些函数。它还有一个内置数据库,可以将接口和函数编号映射到可读名称,这使得调试变得更加容易。
该工具依赖于 ETW(Event Tracing for Windows),RPC 通信日志存储在其中。
一个非常有用的功能是能够为特定进程过滤,无论它是作为客户端还是服务器。
让我们看看该工具的实际效果。
RPCMon 用户界面
用户界面非常简单。最重要的按钮是 Start、Stop和 Filter按钮。您可以按 PID、进程名称或其他几个条件进行过滤。
RPCMon 过滤选项
在我们的例子中,我们将过滤进程名称 server.exe。
应用过滤器后,我们启动捕获,然后运行服务器和客户端。
有时您可能会注意到输出中没有出现事件 (就像我们的客户端和服务器所发生的那样)。这种情况在此工具中经常发生,可能是因为系统上的 ETW 事件数量很大。然而,在许多情况下它对我仍然非常有用,特别是当我不控制服务器或客户端,并且我想监视 RPC 调用而无需手动打开 ETW 日志时。
RPCMon 捕获的事件输出
这是输出中的一个示例。您可以看到来自不同进程的事件,并查看详细信息,例如端点、协议、调用的函数、模拟级别 (impersonation level)、线程 ID 以及正在使用的接口。该工具还支持导出捕获的数据。
如您所见,它还根据其内部数据库翻译函数名称,这非常有用。
如您所见,当涉及到内部工具时,可用的选项并不多,而且没有一个是完美的。但是当您将所有这些工具结合起来时,您的研究目标就变得更加容易实现。
最后,在这篇博客文章中,我原本想讨论在这里开发的 RPC 模糊测试器 (fuzzer)。然而,我意识到它引入了许多我们还没有涵盖的新概念。所以我决定把它留到以后,在我们解释了一些更重要的想法之后。
下一篇见!
Windows Inter Process Communication A Deep Dive Beyond the Surface – Part 8
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:securitainment sud0ru《Windows 进程间通信深度剖析 – 超越表面 – 第 8 部分》