win7下提权及降权运行程序
提权运行,申请管理员权限是很随意的,只需要一行代码即可,难的是降权运行。
有人就会说了,为什么会需要降权运行呢?一句话,为了安全。
比如我的程序,因为安装在了系统的program files目录下,为了在安装目录下保存一些配置或者其他文件,就需要管理员权限运行。但是,管理员权限是会继承到子进程的。如果程序中内嵌了一个网页,而网页有个弹窗,如果这时用户电脑上没有开启默认浏览器,我的程序将会以管理员权限创建一个浏览器进程,并打开网页弹窗,这是很危险的!
再比如,我曾经发现某度网盘的安装程序,在安装完毕后会在无任何提示的情况下重启用户的explorer进程,而安装包进程又是管理员权限,于是重启后的explorer也成了管理员权限,后果可想而知。(我at了它的官方微博提这个,他们没搭理我,但是在后面一次的更新中默默改进了。。)
说这么多,就是要说明,为了安全必须注意管理员权限的继承。
可是,提权容易,降权难啊。为了降权,甚至有人提出了用创建计划任务的方式启动程序,百度Google相关的东西都很少。通过综合几个搜索结果和查询msdn,最终还是搞定了。
具体步骤为:
- 判断系统是否为Vista或以上
- 获取一个普通权限的安全令牌(token)
- 使用这个token,通过CreateProcessAsUser或CreateProcessWithTokenW创建进程
第1步和第3步都很容易。第2步,找到的大部分资料都是通过各种手段查找explorer进程,比如遍历进程或者寻找桌面或托盘区窗口句柄,然后复制explorer进程的token。这种方法,虽然是可行的,但是不稳定,如果创建进程时explorer进程刚好被结束掉了呢?于是就继续找到了下面这种方法:
- 获取自身进程的token
- 复制这个token
- 修改token的完整性级别
具体代码如下:
// 获取Low或Medium(系统默认)安全级别的token HANDLE DuplicateTokenLevel(BOOL bIsLowLevel) { HANDLE hToken = NULL; HANDLE hDuplicatedToken = NULL; if (OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken)) { if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, 0, SecurityAnonymous, TokenPrimary, &hDuplicatedToken)) { SID sid = {0}; sid.Revision = SID_REVISION; sid.SubAuthorityCount = 1; sid.IdentifierAuthority.Value[5] = 16; sid.SubAuthority[0] = bIsLowLevel ? SECURITY_MANDATORY_LOW_RID : SECURITY_MANDATORY_MEDIUM_RID; TOKEN_MANDATORY_LABEL tokenIntegrityLevel = {0}; tokenIntegrityLevel.Label.Attributes = SE_GROUP_INTEGRITY; tokenIntegrityLevel.Label.Sid = &sid; SetTokenInformation(hDuplicatedToken, TokenIntegrityLevel, &tokenIntegrityLevel, sizeof (TOKEN_MANDATORY_LABEL) + GetLengthSid(&sid)); } } if (hToken) CloseHandle(hToken); return hDuplicatedToken; }
有了低权限的token,创建进程就很简单了。
这里有份示例代码和一个测试程序,如果需要的话可以下载。
参考资料:
- Windows Vista for Developers——第四部分:用户帐号控制(User Account Control,UAC)
- win7 创建进程 提权与降权
- VS与Win7共舞:系统服务的Session 0隔离
- Win7下超级管理员创建普通权限任务
近期评论