Win32 UAC用户账户控制 (提权)
最近写程序时遇到一个问题,就是当一个程序需要管理员权限才能正常运行该怎么办?
通过查阅多方资料,我总结出来几个比较实用的办法!(每种办法实现方法不同,同时功能上也有一些小小的差异。)
一、方法一(批处理脚本)
1 | @echo off |
这个批处理脚本代码可以以管理员身份启动,并且会以文件所在位置为工作环境。
所以,只要用这个脚本启动你的程序即可以管理员身份启动你的程序。
缺点:
- 会有一个命令提示符窗口一闪而过;
- 程序启动入口是个批处理文件。
二、方法二(manifest)
在 VS 编辑器里这样设置项目属性后再编译出来的程序就会有个 UAC 盾,以后你的程序只要运行就都会请示管理员权限。
三、方法三(动态提权)
所谓动态提权,就是一个没有管理员权限的程序进程在他认为合适的时候创建一个有管理员权限的程序进程,代码很简单:
1 | HINSTANCE ShellExecuteA( |
其中 INT nShowCmd 参数具体可参考 Microsoft Docs - ShowWindow function,
具体函数详情参考 Microsoft Docs - ShellExecuteA function。
四、方法四(利用微软 Windows 的漏洞)
这些方法因为不推荐使用,所以不多介绍了。有 Windows UAC 漏洞,但是微软会想办法去修补的,所以这类方法容易失效。
五、补充资料
基本概念:
- 进程的权限是继承的,也就是说,有管理员权限的程序创建的进程也有管理员权限,没有管理员权限的程序创建进程就没有管理员权限(但高权限进程创建进程必须是高权限不是绝对的)
- Windows Shell进程explorer本身没有管理员权限,如果explorer有管理员权限,大家可以想一下,那么它创建的进程都有管理员权限,那UAC不就形同虚设了吗
- 没有权限的进程不能创建有权限的进程!是的,你没有听错,就是不能,这是Windows操作系统规定的。但你可能会问“那么如何提权?你不是说连explorer都没有权限吗?”,答案是:Windows系统中有一个开机自启的AppInfo服务,它直接以系统权限运行,在一个管理员用户登录时,系统会保留一份当前用户的高权限令牌并传给AppInfo服务,提权的过程本身就是一个进程通过进程通信把要提权的程序传给AppInfo服务,AppInfo服务会运行一个UI进程,UI进程会接收用户响应,如果用户同意这次提权,AppInfo服务就使用高权限令牌在当前用户会话的交互窗口站的当前桌面创建管理员权限的进程,创建时将进程的父进程替换为请求提权的进程。这样我们看起来就好像是“没权限进程创建有权限进程”了,其实高权限进程不是它创建的。
参考文档
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SeaEpoch!
评论