[译]逆向ALPC:如何发现Windows bugs和Sandbox escape?

介绍

当我还不是一个研究Windows的安全专家的时候,我通常挖掘漏洞的方法是:

  1. 在YouTube上查找和观看有趣的攻击面。
  2. 在找到感兴趣的主题后,我会尽可能地通过google去搜索有关该主题的所有内容。
  3. 分析和学习最低限度的知识,开始实验性地进行尝试。

写这篇文章的目的是为了讲述我发现漏洞的过程,而不是对任何特定知识的讲解。
如果您发现任何错误或需要更正的地方,请随时与我联系。另外,这是我的个人爱好,我并不是一个专业的安全研究员。

首先我要说的是:如何发现Windows bugs和Sandbox escape呢?
自从我看了Ben Nagy录制的视频:Windows Kernel Fuzzing for Intermediate Learners之后,我就对ALPC(Advanced Local Procedure Call)非常感兴趣。
在看了Clement Rouault和Thomas Imbert在hack.lu 2017上的议题:Hack.lu 2017 A view into ALPC-RPC by Clement Rouault and Thomas Imbert之后,我成功的拼凑起了足够的知识。
在此之前,通过hook NtAlpcSendWaitReceivePort,我做了一些尝试,但是没有什么收获。
我完成我上面提到的第三步的方式是很简单的:我试着重复我能想到的一切,并在不过度依赖技术的情况下提出问题。

Q:ALPC到底是怎么回事?
A:Advanced Local Procedure Call——一种Windows内部机制,允许在OS内运行的client进程向在同一OS中运行的server进程发起请求,要求server进程提供某些信息或执行某些操作。

Q:我们可以通过进程间通信来进行攻击吗?
A:可以,如果可以在低权限和高权限进程直接进行通信,这意味着我们从一个已经被攻击者控制的空间里,影响“其他的某些东西”。

Q:什么类型的通信将使用ALPC?
A:Local RPC将使用ALPC!Local RPC(Remote Procedure Call),它基本调用其他进程公开的函数,但由于某些原因,所有东西都需要有一个奇特的名字!我相信还有其他类型的通信使用ALPC,但是让我们关注RPC,因为资料丰富。

Q:我能在哪里找到这些基于ALPC的"Remote Procedure calls"?
A:看看上面我提到的RPC over ALPC视频,我们能使用RpcView!

我们需要做的就是选择一个interface(interface是我们可以使用RPC调用的一组函数)
并创建一个IDL(IDL提供了一个关于我们如何调用函数以及函数使用什么参数的模板,因此我们可以不需要逆向所有的东西。)
这是一个奇怪的COM-thingy,他们想要一些中间语言来在编程语言之间移植东西,但它基本上失败了,并没有成为新的行业标准。只有微软现在使用它!

Q:我们在rpcview中找到了所有信息并为interface创建了一个IDL,现在要做什么?
A: 我们可以将它复制粘贴到James Forshaw的PoC中,让它开始工作!哇噢!

Step-by-step

下载RpcView: https://ci.appveyor.com/project/silverf0x/rpcview/build/artifacts
在RpcView中设置符号
首先打开WinDbg并运行以下命令(下载Windows SDK for WinDbg):
symchk /s srv*c:\symbols*https://msdl.microsoft.com/download/symbols c:\windows\system32\*.dll
注意:这将花费很长时间!
之后在RpcView中选择Options > Configure Symbols

Step 1: 发现要逆向的interface

以管理员身份打开RpcView:默认情况下,它将列出所有的interface,选择系统进程。

寻找一个看上去很有趣的interface,如果单击某个interface,可以看到它所支持的功能,如果设置了符号,则可以看到里面的函数名称!我通常根据函数名称来决定是否深入研究。

Step 2: 在Forshaw PoC中编译IDL

首先,您要确保要逆向的的interface以SYSTEM权限运行,这可以在RpcView中看到。
确保epmapper已注册(interface将显示为绿色),否则会出现一些错误(如果有人知道如何调用未注册的interface,请告诉我)

出于教程的目的,我们将逆向background tasks infrastructure service(具有17个进程的服务)。

右键单击interface并按反编译,则会生成IDL。

复制粘贴在反编译窗口的文本,并打开以下的PoC :
https://github.com/SandboxEscaper/blogstuff/blob/master/templ.rar
这是基于Forshaw所写的PoC编写。

用我们从RpcView里复制的IDL覆盖rpc.idl

第一次尝试从background tasks infrastructure service构建IDL失败了:

它无法为函数5创建原型。因此,我们只是将其注释掉并尝试再次构建。如果我们真的想了解更多有关此函数的信息,我们可以稍后通过IDA逆向,并自行修复。

这次我们得到了不同的错误。这次似乎是Struct_28_t没有定义

RpcView创建的IDLs时常有很多问题并且需要做很多修复。让我们只定义一个标准的结构体,我们需要后面再去逆向和修复它。现在,我们只需要避免有函数使用这个结构体。

Step 3:打开IDA,并寻找有趣的method

在RpcView中,我们可以看到我们的interface位于bisrv.dll中

让我们在IDA和RpcView中打开DLL,让我们寻找一个我们应该进一步检查的method!

我们来看看RBiSrvResetActiveUserForPackage吧!
如果我们在我们的解决方案中查看rpc.idl,我们看到它只是将wchar_t作为参数,这意味着在没有大量逆向的情况下调用它很容易!


我们可以在IDA中轻松找到这个函数!

此时,您可以在IDA中的快速浏览一下这个函数,以确定是否值得进一步分析。
出于教程的目的,让我们看看如何调用此函数,点击此代码!
我们在runexploit()中将函数添加到我们的代码中; 在ALPC-TaskSched-LPE.cpp中 (我懒得更改名称)。

第一个参数是一个context handle或其他的什么,我不知道这是做什么,但是你必须把它放在那里。
之后我们要确定wchar_t参数是什么,你需要在IDA中逆向这个函数以找出它应该是什么。
一种快速的方法是在那里dump文件路径,并在procmon检查,以查看是否有任何文件系统事件发生!( A quick way is to dump a file path there and check in procmon to see if any file system stuff happens!)
现在我们只需要复制粘贴我们interface的UUID,这样我们就知道连接到哪个interface。你可以在rpc.idl的顶部找到它。

复制粘贴到这里:

接下来编译并运行它!好极了!您现在正在system进程中触发remote function!

Step 4:逆向methods
找到bug的最快方法是调用methods,并在procmon中查看它们,寻找非预期的createfile调用,这些通常是很有趣的。
我们也可以进行动态调试,因为我们经常需要某些特定参数才能触发正确的代码路径。
每个ALPC接口都在一个进程中运行,您可以在RpcView中找到PID:

只需将调试器attach到此PID,并在使用PoC调用的methods下断点。之后,您可以单步调试代码。
如果你看到它没有通过某些检查,你将不得不弄清楚原因,并相应地调整参数,这样你就可以执行到你想要触发的代码。

结论

除了junction/hard link滥用(参见task scheduler and delete bug)之外。
逆向函数,找出它们的作用,并查看它是否可能以非预期的方式被滥用将会很有趣。
我想证明你不需要有很多技术上的能力来发现bug,只需要长期去做。

Credits和参考

我不是很擅长逆向,所以我很高兴其他人已经做好了!

原文

源链接

Hacking more

...