介绍RPC Investigator - Trail of Bits博客
新工具助力Windows RPC研究
Trail of Bits发布了一款用于探索Windows上RPC客户端和服务端的新工具。RPC Investigator是一款基于NtApiDotNet平台的.NET应用程序,支持枚举、反编译/解析任意RPC服务器并进行通信。我们新增了可视化功能和附加特性,为探索RPC提供了全新方式。
RPC是Windows中的重要通信机制,不仅因其为软件开发人员提供的灵活性和便利性,更因其实现者为漏洞利用开发者提供的著名攻击面。虽然已有大量关于RPC服务器、接口和协议的研究发表,但我们认为始终需要更多工具来帮助安全从业者更轻松地探索和理解这种多产的通信技术。
下文将介绍该领域的背景研究,详细描述RPC Investigator的功能,并讨论未来的工具开发计划。若希望直接查看代码,请访问Github上的RPC Investigator。
背景
微软远程过程调用(MSRPC)是一种流行的通信机制,为定义服务器/客户端接口提供了可扩展框架。MSRPC在几乎所有Windows系统活动中都有涉及,从登录笔记本电脑到打开文件。正因如此,数十年来它一直是防御和攻击性信息安全社区的热门研究目标。
几年前,开源.NET库NtApiDotNet的开发者James Foreshaw更新了库功能,支持反编译、构建客户端并与任意RPC服务器交互。在一篇优秀的博客文章中(重点介绍通过PowerShell脚本和其NtObjectManager包中的cmdlet使用新NtApiDotNet功能),他简要介绍了如何使用PowerShell脚本为给定RPC服务器生成C#客户端代码,并将其编译成C#应用程序。
我们在开发RPC Investigator(RPCI)时基于这一概念,构建了一个.NET/C# Windows Forms UI应用程序,为NtApiDotNet平台的现有核心RPC功能提供可视化界面:
- 枚举所有活动的ALPC RPC服务器
- 从任何PE文件解析RPC服务器
- 从进程及其加载模块(包括服务)解析RPC服务器
- 集成符号服务器
- 将服务器定义导出为序列化.NET对象以供自定义脚本使用
除了可视化这些核心功能,RPCI还提供额外能力:
- 客户端工作台允许通过右键点击感兴趣的RPC服务器动态创建和执行RPC客户端二进制文件。工作台包含C#代码编辑器窗格,可实时编辑客户端并观察代码中执行的RPC过程结果。
- 发现的RPC服务器被组织到具有可定制搜索界面的库中,允许以有用方式透视RPC服务器数据,例如通过所有服务器的所有RPC过程搜索有趣例程。
- RPC嗅探器工具增加了对RPC相关Windows事件追踪(ETW)数据的可见性,提供活动RPC调用的近实时视图。通过将ETW数据与NtApiDotNet的RPC服务器数据结合,我们可以更全面地了解正在进行的RPC活动。
功能
免责声明:与系统服务交互时请务必谨慎。若未正确使用RPCI,可能导致系统状态损坏或系统崩溃。
先决条件和系统要求
目前,RPCI需要以下条件:
- Windows操作系统
- .NET Framework 4.8或更新版本
- 安装有Windows调试工具组件的Windows SDK
- 管理员访问权限
默认情况下,RPCI会自动发现Windows调试工具安装目录,并配置自身使用公共Windows符号服务器。可通过点击编辑 -> 设置修改这些设置。在设置对话框中,可指定调试工具DLL(dbghelp.dll)的路径,并根据需要自定义符号服务器和本地符号目录(例如,可指定路径srv*c:\symbols*https://msdl.microsoft.com/download/symbols)。
若要观察写入RPCI日志的调试输出,请在设置窗口中设置适当的跟踪级别。RPCI日志及所有相关文件写入当前用户的应用程序数据文件夹,通常为C:\Users\(user)\AppData\Roaming\RpcInvestigator。查看此文件夹只需导航至视图 -> 日志。但建议禁用跟踪以提高性能。
需注意RPCI的位数必须与系统匹配:若在64位系统上运行32位RPCI,则只能访问托管在32位进程或二进制文件中的RPC服务器(很可能没有)。
搜索RPC服务器
首先需要查找系统上运行的RPC服务器。最直接的方法是查询RPC端点映射器,这是操作系统提供的持久服务。由于大多数本地RPC服务器实际上是ALPC服务器,此查询通过文件 -> 所有RPC ALPC服务器…菜单项暴露。
发现的服务器根据托管进程列在表格视图中,如上图所示。此表格视图是在RPCI中导航RPC服务器的起点之一。双击特定服务器将打开另一个标签页,列出所有端点及其对应的接口ID。双击端点将打开另一个标签页,列出可在该端点接口上调用的所有过程。右键点击端点将打开上下文菜单,提供其他有用快捷方式,其中之一是创建新客户端连接到此端点接口。我们将在后续章节描述该功能。
可通过选择文件 -> 从二进制文件加载…并定位磁盘上的镜像,或选择文件 -> 从服务加载…并选择感兴趣的服务(这将解析服务进程中加载的所有模块中的所有服务器),来定位未运行(或非ALPC)的其他RPC服务器。
探索库
导航RPC服务器的另一个起点是加载库视图。库是一个文件,包含使用RPCI时发现的每个RPC服务器的序列化.NET对象。只需选择菜单项库 -> 服务器查看所有发现的RPC服务器,或库 -> 过程查看所有服务器接口的所有发现过程。两个菜单项将在新标签页中打开。要在任一标签页中执行快速关键字搜索,只需右键点击任何行并在文本框中输入搜索词。下图显示关键字搜索"()“以快速查看具有零参数的过程,这些是实验接口的有用起点。
首次运行RPCI时,需要初始化库。为此,导航至库 -> 刷新,RPCI将尝试从所有具有注册ALPC服务器的进程的所有加载模块中解析RPC服务器。请注意,此过程可能需要相当长的时间并使用几百兆内存;这是因为有数千个此类模块,且在此过程中二进制文件被重新映射到内存中并查询公共Microsoft符号服务器。更糟糕的是,Dbghelp API是单线程的,且怀疑Microsoft的公共符号服务器具有速率限制逻辑。
可定期刷新数据库以捕获任何新服务器。刷新操作仅添加新发现的服务器。若需要从头重建库(例如,因为符号错误),可使用菜单项库 -> 擦除或手动删除当前用户漫游应用程序数据文件夹中的数据库文件(rpcserver.db)。请注意,使用文件 -> 从二进制文件加载…和文件 -> 从服务加载…菜单项发现的RPC服务器会自动添加到库中。
还可通过选择库 -> 导出为文本将整个库导出为文本。
创建新RPC客户端
RPCI最强大的功能之一是能够动态与正在运行的感兴趣RPC服务器交互。这是通过在客户端工作台窗口中创建新客户端实现的。要打开客户端工作台窗口,从库服务器或过程标签页右键点击感兴趣的服务器并选择新建客户端。
工作台窗口分为三个窗格:
- 静态RPC服务器信息
- 包含动态客户端输出的文本框
- 包含客户端代码和过程标签页的标签控件
客户端代码标签页包含由NtApiDotNet生成的RPC客户端的C#源代码。代码已修改为包含"Run"函数,这是客户端的"入口点”。过程标签页是所选RPC服务器接口中可用例程的快捷参考,因为源代码可能浏览起来很麻烦(我们正在努力改进!)。
生成和运行客户端的过程很简单:
- 修改"Run"函数以调用RPC服务器接口暴露的一个或多个过程;如需可打印结果。
- 点击"运行"按钮。
- 观察"Run"产生的任何输出。
在上面的屏幕截图中,我选择了"主机网络服务"RPC服务器,因为它暴露了一些名称暗示有趣管理员能力的过程。通过几次对RPC端点的函数调用,我能够与服务交互以转储似乎与Azure容器隔离相关的默认虚拟网络的名称。
使用ETW数据嗅探RPC流量
RPCI的另一个有用功能是提供对RPC相关ETW数据的可见性。ETW是内置于操作系统中的诊断能力。多年前ETW非常简陋,但自从终端检测与响应(EDR)市场在过去十年爆发以来,Microsoft已将ETW发展为关于系统活动的极其丰富的信息源。ETW的工作原理是,ETW提供程序(通常是服务或操作系统组件)以"事件"数据包形式发出结构良好的数据,应用程序可以消费这些事件以诊断性能问题。
RPCI注册为Microsoft-RPC(MSRPC)ETW提供程序的此类事件的消费者,并实时以表格或图形格式显示这些事件。要启动RPC嗅探器工具,导航至工具 -> RPC嗅探器…并点击工具栏中的"播放"按钮。随着事件开始到达,表格和图形将每几秒更新一次。
MSRPC提供程序发出的事件相当简单。事件记录RpcClientCall和RpcServerCall开始和停止任务对中客户端和服务器之间的RPC调用结果。开始事件包含关于RPC服务器接口的详细信息,如协议、过程编号、选项和调用中使用的身份验证。停止事件通常不太有趣,但包含状态代码。通过关联特定RPC服务器和请求进程之间的调用开始/停止事件,我们可以开始理解系统上正在进行的操作。在表格视图中,当ETW数据按ActivityId分组时(点击工具栏中的"分组"按钮),更容易看到这些事件对,如下所示。
数据可能令人不知所措,因为ETW设计上相当嘈杂,但图形视图可以帮助您梳理噪音。要使用图形视图,只需在跟踪期间的任何时间点击工具栏中的"节点"按钮。要切换回表格视图,再次点击"节点"按钮。
长时间运行的跟踪将产生繁忙的图形,如上所示。可以平移、缩放和更改图形布局类型以深入查看有趣的服务器活动。我们正在探索改进此可视化的其他方法!
在上面的放大屏幕截图中,我们可以看到与系统服务(如基础过滤引擎(BFE,Windows Defender防火墙服务)、NSI和LSASS)交互的各个服务进程。
使用RPC嗅探器工具时,请记住以下其他有用提示:
- 在设置中保持RPCI诊断跟踪禁用。
- 不要启用ETW调试事件;这些会产生大量噪音并可能在几分钟后耗尽进程内存。
- 为获得最佳性能,使用RPCI的发布版本。
- 考虑将主窗口停靠在嗅探器窗口旁边,以便在ETW数据和库数据之间导航(右键点击表格行并选择在库中打开,或在图形视图中点击任何RPC节点)。
- 记住图形视图将每几秒刷新一次,如果您正在缩放和平移,可能会失去位置。图形视图的最佳用途是在固定时间窗口内捕获并在捕获停止后探索图形。
下一步计划
我们计划在继续开发RPCI时完成以下工作:
- 改进客户端工作台中的代码编辑器
- 改进自动生成名称使其更直观
- 引入更多开发者友好的编码功能
- 改进未在端点映射器注册的RPC/ALPC服务器的覆盖范围
- 引入自动化ALPC端口连接器/扫描器
- 改进搜索体验
- 扩展图形视图使其更具交互性
相关研究与进一步阅读
由于MSRPC十多年来一直是热门研究话题,有太多相关资源和研究工作无法在此一一列举。我们在构建此工具时遇到的一些如下:
- @tiraniddo的使用NtObjectManager查找运行中的RPC服务器信息
- @clearbluejar的[从NtObjectManager到PetitPotam](https://