提权技术
第六章 提权技术
进程访问令牌权限提升
访问令牌
访问令牌 是描述进程或线程的安全上下文的对象。令牌中的信息包括与进程或线程关联的用户帐户的标识和特权。当用户登录时,系统会通过将密码与存储在安全数据库中的信息进行比较来验证用户的密码。如果密码经过身份验证,系统会生成访问令牌,并且代表该用户执行的每个进程都拥有该令牌的一个副本。该令牌标识用户、用户所属组和用户的特权。 系统使用该令牌控制对可保护对象的访问,并控制用户在本地计算机上执行各种系统相关操作的能力。有两种类型的访问令牌,主要令牌和模拟。
当线程与安全对象交互或尝试执行需要特权的系统任务时,系统使用访问令牌标识用户。 访问令牌包含以下信息:
- 用户帐户 的安全标识符 (SID)
- 用户所属组的 SID
- 标识当前登录会话的登录 SID
- 用户或用户组持有 的特权 列表
- 所有者 SID
- 主组的 SID
- 当用户创建安全对象时系统使用的默认 DACL ,而无需指定 安全描述符
- 访问令牌的源
- 令牌是 主要 令牌还是 模拟 令牌
- 限制 SID 的可选列表
- 当前模拟级别
- 其他统计信息
实现原理
要想提升访问令牌权限,首先就要获取进程的访问令牌,然后将访问令牌的权限修改为指定权限。但是系统内部并不直接识别权限名称
而是识别LUID值,所以需要根据权限名称获取对应的LUID值,之后传递给系统,实现进程访问令牌权限的修改。
具体实现步骤如下所示:
首先,程序需要调用OpenProcessToken函数打开指定的进程令牌,并获取TOKEN_ADJUST_PRIVILEGES权限的令牌句柄。之所以要指定进程令牌权限为TOKEN_ADJUST_PRIVILEGES,是因为AdjustTokenPrivileges函数要求有此权限,方可修改进程令牌的访问权限。
1 | |
再接着调用LookupPrivilegeValue函数,获取本地系统指定特权名称的LUID值,这个LUID值相当于该特权的身份标识号。
1 | |
接着,程序就开始对进程令牌特权结构体TOKEN_PRIVILEGES进行赋值,设置新特权的数量、特权对应的LUID值以及特权的属性状态。
1 | |
最后,程序调用AdjustTokenPrivileges函数对进程令牌的特权进行修改,将上面设置好的新特权设置到进程令牌中,这样就完成了进程访问令牌的修改工作。
1 | |
代码实现
1 | |
Bypass UAC
自从VISTA系统开始引人了UAC(用户账户控制),涉及权限操作时都会有弹窗提示,只有用户点击确认后,方可继续操作。所以,VISTA之后的提权操作主要是针对UAC不弹窗静默提权,即BypassUAC。
触发UAC时,系统会创建一个consent.exe进程,该进程通过白名单和用户选择来判断是否创建管理员权限进程。请求进程将要请求的进程cmdline和进程路径通过LPC接口传递给appinfo和RAiLuanchAdminProcess函数。该函数首先验证路径是否在白名单中,并将结果传递给consent.exe进程,该进程验证请求进程的签名以及发起者的权限是否符合要求后,决定是否弹出UAC窗口让用户确认。这个UAC窗口会创建新的安全桌面,屏蔽之前的界面。同时这个UAC窗口进程时系统权限进程,其他普通进程无法和其进行通信交互。用户确认之后,会调用CreateProcessAsUser函数以管理员身份启动请求的进程。
Bypass UAC提权技术主要利用白名单机制以及COM组件接口技术来实现。
基于白名单程序的Bypass UAC
有些系统程序是直接获取管理员权限,而不触发UAC弹框的,这类程序称为白名单程序。可以通过DLL劫持、注入或是修改注册表执行命令等方式,利用这些白名单程序启动目标程序,实现BypassUAC提权操作。
选取CompMgmtLauncher.exe进行详细分析。
分析发现,CompMgmtLauncher.exe进程会先查询注册表HKCU\Software\Classes\mscfile\shell\open\command中的数据,发现该路路径不存在后,继续查询注册表HKCR\mscfile\shell\open\command(Default)中的数据并读取,该注册表路径中存储着mmc.exe进程的路径信息。然后执行mmc.exe。

所以我们可以在HKCU\Software\Classes\mscfile\shell\open\command中写入数据。手动添加该注册表路径,并设置默认数据为C:\Windows\System32\cmd.exe,并运行CompMgmtLauncher.exe。

结果cmd并未以管理员权限运行。推测是windows更新,对相关功能进行修改。
基于COM组件接口的Bypass UAC
COM提升名字对象(COM Elevation Moniker)技术允许运行在用户账户控制下的应用程序用提升权限的方法来激活COM类,以提升COM接口权限。
同时,ICMLuaUtil接口提供了ShellExec方法来执行命令,创建指定进程。因此,我们可以利用COM提升名字对象来对ICMLuaUtil接口提权,之后通过接口调用ShellExec方法来创建指定进程,实现Bypass UAC。
实现过程
使用权限提升COM类的程序必须通过调用CoCreatelnstanceAsAdmin函数来创建COM类,下面给出的是函数的改进代码,它增加了初始化COM环境的代码。
1 | |
通过上述方法创建并激活提升权限的COM类创建后,直接调用ICMLuaUtil接口的ShellExec方法来创建指定进程,完成BypassUAC操作。
1 | |
如果执行COM提升名称代码的程序身份是不可信的,还是会触发UAC弹窗;若是可信程序,则不会触发UAC弹窗。因此,必须使这段代码在WIndows可信程序中运行。可信程序有计算器、记事本、资源管理器、rundll32.exe等。可以通过DLL注入或是劫持技术,将这段代码注入到这些可信程序的进程空间当中。最简单的莫过于直接通过rundll32.exe来加载DLL,执行COM提升名称的代码。
1 | |
测试

总结
实现Bypass UAC的方法很多,并不局限于白名单程序和COM接口技术。对于不同的Bypass UAC方法,其具体的实现过程大都不一样。随着操作系统的升级更新,现在对于Bypass UAC成功的方法,可能在以后不再适用,但也会有新的BypassUAC方法出现,攻与防是相互博奔的过程。