如何滥用Access Tokens UIAccess绕过UAC

原文:https://tyranidslair.blogspot.com/2019/02/accessing-access-tokens-for-uiaccess.html

0x00 前言

我在之前的文章中提到过,Windows RS5最终结束了攻击者对Access Tokens(访问令牌)的滥用,使其无法通过Access Token提升到管理员权限。这一点的确有点烦人,但我并不在意。然而,我在Twitter上了解到与UAC相关的一些信息,令我感到惊讶的是,之前竟然没有人将这两种技术点联系在一起,也没意识到即使无法直接获得管理员权限,我们也能利用之前的令牌窃取技巧获得UIAccess。本文介绍了UIAccess相关的一些知识,也介绍了如何让我们自己的代码以UIAccess方式运行。

在本文中,我介绍了如何利用UIAccess进程实现同样的令牌窃取目标,这个过程不会弹出权限提升对话框,然后我们可以自动化利用特权进程的UI来绕过UAC。大家可以在我的Github上找到PowerShell示例脚本。

0x01 UIAccess

首先,什么是UIAccess?与UAC有关的一个功能是User Interface Privilege Isolation(UIPI,用户界面特权隔离)。UIPI会限制进程与高权限(higher integrity level,高完整性级别)进程窗口的交互,阻止恶意应用自动化操作特权UI来提升权限。虽然几年来人们在这方面挖掘出了一些漏洞,但这个整体原则还是合理的。然而这里存在一个大问题,辅助技术(Assistive Technologies)怎么办?许多人们需要依赖屏幕键盘、屏幕阅读器等,如果用户无法读取并自动化操作特权UI,那么这些程序就无法正常工作。如果是这样,那么盲人就没办法成为管理员了。微软的解决方法是为UIPI开设了一个后门,往Access Tokens添加了一个特殊的标志(flag):UIAccess。设置该标志时,WIN32K的大多数UIPI限制都会有所放松。

0x02 滥用UIAccess

从权限提升角度来看,如果我们具备UIAccess,那么就可以自动化操作高权限进程的窗口,比如我们可以利用管理员命令提示符以及该权限来绕过后续的UAC提示窗口。我们可以调用SetTokenInformation,在某个令牌上设置UIAccess标志,然后传入TokenUIAccess信息类。如果我们执行该操作,就会发现我们无法像普通用户那样设置标志,我们需要SeTcbPrivilege权限,而该权限通常只授予SYSTEM。如果我们需要一个“上帝”权限来设置该标志,那么怎么才能在普通操作中设置UIAccess呢?

我们需要利用AppInfo服务,以适当的标志集或直接调用ShellExecute来运行我们的进程。由于服务以SYSTEM权限运行,并且具备SeTcbPrivilege权限,因此可以在启动时设置UIAccess标志。虽然这个过程会生成Consent.exe进程,但不会弹出UAC对话框(否则没有什么意义)。AppInfo服务会生成管理员UAC进程,然后如果我们在自己的manifest中将uiAccess属性设置为true,那么该服务就会以UIAccess方式来运行我们的进程。但事情并没有那么简单,根据此处参考资料,我们的可执行文件需要签名(这很简单,我们可以自签名),但必须位于安全位置(如System32或者Program Files,这一点比较难)。为了阻止恶意应用生成UIAcess进程并将代码注入该进程,AppInfo服务会将令牌完整性调整为High级别(适用于管理员)或者在当前完整性级别基础上加16(适用于普通用户)。这种调整过的完整性级别可以阻止调用方对新进程的读写访问。

当然这里存在一些bug,比如2014年我就发现过一个bug(现已被修复),攻击者可以滥用目录NTFS命令流来绕过系统对安全位置的检查。UACME也实现了滥用UIAccess的一种利用技术(即此文中提到的第32种方法),如果我们可以找到可写的一个安全位置目录,或者可以滥用已有的IFileOperation技巧来将某个文件写入合适的位置就可以使用这种利用方法。UIAccess是Access Token的一种属性,由于操作系统没有清除该标志,因此我们可以从已有的某个UIAccess进程那获取令牌,然后利用该令牌创建新的进程,然后自动化操作特权窗口。

总结一下,在默认安装的Windows 10 RS5及较低版本系统中,我们可以使用如下步骤来滥用UIAccess:

1、寻找或启动一个UIAccess进程(如屏幕键盘OSK.EXE)。由于AppInfo不会弹出UIAccess请求窗口,因此这个步骤可以相对隐蔽地完成;

2、以PROCESS_QUERY_LIMITED_INFORMATION访问权限打开该进程。只要我们具备该进程的任何访问权限,我们就可以执行该操作。我们甚至可以利用低权限进程完成该操作,虽然Windows 10 RS5上部署了一些沙箱缓解措施,但我们应该能在Windows 7上顺利完成该操作;

3、以TOKEN_DUPLICATE访问权限打开进程令牌,然后将该令牌复制为新的可写主令牌;

4、设置新令牌的完整性级别,以匹配当前令牌的完整性级别;

5、在CreateProcessAsUser中使用该令牌来生成带有UIAccess标志的新进程;

6、自动化操作UI,完成我们的最终任务。

如果大家看过我之前的博客,可能会好奇为什么以前我只能仿冒令牌,现在却能用该令牌创建新进程?对于UIAccess而言,AppInfo服务只会修改调用方的令牌副本,而不会使用链接令牌(linked token)。这意味着系统将UIAccess令牌当成桌面上其他进程的兄弟(sibling)单元,因此只要完整性级别等于或低于当前完整性级别,就可以分配主令牌。

我上传了一个PowerShell脚本,可以利用这种攻击技术,使用SendKeys类将任意命令写入桌面上的前台命令提示符窗口(获得命令提示符的方法不在此赘述)。

获得UIAccess后,我们还有其他利用方式。比如,如果管理员设置了“用户帐户控制: 允许UIAccess 应用程序在不使用安全桌面的情况下提升权限”组策略,那么我们有可能利用UIAccess进程金庸安全桌面,自动提升权限。

0x03 总结

总而言之,虽然之前的管理员令牌窃取方法已不再有效,但这并不意味着这种方法没有价值。通过滥用UIAccess程序,我们基本上可以稳定绕过UAC。当然UAC并非安全边界,并且充满漏洞,因此可能有些人不会关心这方面内容。

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖