【提权】利用AppInfo RPC服务的UAC Bypass技术详解
概述: 利用 AppInfo RPC 服务的 UAC ByPass 提权流程
0x01 前言
在阅读本文之前确保大家已经基本了 UAC 的大致流程。
UAC 的请求都是交由 AppInfo 这个系统服务来处理的,AppInfo 的进程为 svchost。 在提权流程中,Appinfo 也仅仅是作为中间连接的一环,一方面处理应用程序请求来的UAC请求,另一方面拉起consent.exe 来处理用户操作,最后将用户操反馈给应用程序。这就是 UAC 的大致流程。本文着重Appinfo 的相关流程来说明一下如何利用 Appinfo 进程 UAC Bypass。
0x02 AppInfo 调用说明
操作:可以调试 Appinfo 的进程,然后通过启动 UAC 进程观察一个程序的uac请求到了 AppInfo 之后的流程。结合IDA的 exports 可以在一些关键函数打上断点然后进行调试。当然因为网上已经有大量的分析和调用流程说明了,所以这一步骤可以省略直接在一些关键的函数上打断点调试查看堆栈和参数。
因为UAC的提权都需要创建UI进程来让用户进行操作,这个UI进行就是 consent.exe,所以直接观察 consent.exe 的创建和调用即可。
这里直接对 AiLaunchConsentUI 打断点然后查看堆栈。
consent.exe的创建
AppInfo 服务收到rpc消息后,最终通过 CreateProcessAsUser 创建。
这篇文章讲的比较细致:UAC逆向
调用堆栈如下所示:
1 |
|
1 |
|
如上所示可以看到 consent.exe 的命令行传递了三个参数,分别为父进程id,结构体长度和结构体地址。那么基本上可以确定,uac的相关信息就在该结构体中,consent通过读写父进程的地址空间,将用户操作结果写入到对结构体对应的地址中。(这里有兴趣的同学还可以看一下consent.exe的调用流程。)
查看相关参数解析的部分如下所示:
可以看到命令行参数3的结构体对应的是 _CONSENTUI_PARAM_HEADER
,目前在网上找不到相关的结构,不过这里都不重要,大致了解这个过程和流程即可。
consentui.exe 的鉴权与回传
这里主要观察一下 consent.ui 拿到参数之后是如何工作的,又是如何将获取的权限写回的。
在 WinMain 函数结束的地方调用了 NtWriteVirtualMemory 写入了 TargetHandle ,而这个 TargetHandle 就是在 CuiGetTokenForApp 中获取到的管理员 token 句柄。最后又把这个这个句柄写回到了 _CONSENTUI_PARAM_HEADER+7 的位置。
consentui 的弹窗逻辑
通过分析找到了决定是否弹窗的关键函数为:
如果上述判断需要弹窗的话,最终跳转到 CuiStartBackgroundWindowAndSwitchToSecureDesktop 函数去执行操作。下面就 CuiCheckElevationAutoApprovalMedium 函数展开看一下判断的逻辑。如下所示,在函数内部首先是判断com组件是不是自提升的组件,调用的 CuiIsCOMClassAutoApprovable 并且传入了COM组件的GUID。
判断完成之后还需要几次跳转才能到弹窗的函数。以上就是 consent.exe 的弹窗逻辑了。
关键点大概就是以上三点,通过 RAiLuanchAdminProcess 创建 consent.exe,consent.exe 通过CuiIsCOMClassAutoApprovable 检查 com组件 权限,CuiStartBackgroundWindowAndSwitchToSecureDesktop 创建界面ui获取权限,NtWriteVirtualMemory 写内存方式写入获取到权限的句柄。