win7下提权及降权运行程序

提权运行,申请管理员权限是很随意的,只需要一行代码即可,难的是降权运行。

有人就会说了,为什么会需要降权运行呢?一句话,为了安全。

比如我的程序,因为安装在了系统的program files目录下,为了在安装目录下保存一些配置或者其他文件,就需要管理员权限运行。但是,管理员权限是会继承到子进程的。如果程序中内嵌了一个网页,而网页有个弹窗,如果这时用户电脑上没有开启默认浏览器,我的程序将会以管理员权限创建一个浏览器进程,并打开网页弹窗,这是很危险的!

再比如,我曾经发现某度网盘的安装程序,在安装完毕后会在无任何提示的情况下重启用户的explorer进程,而安装包进程又是管理员权限,于是重启后的explorer也成了管理员权限,后果可想而知。(我at了它的官方微博提这个,他们没搭理我,但是在后面一次的更新中默默改进了。。)

说这么多,就是要说明,为了安全必须注意管理员权限的继承。

可是,提权容易,降权难啊。为了降权,甚至有人提出了用创建计划任务的方式启动程序,百度Google相关的东西都很少。通过综合几个搜索结果和查询msdn,最终还是搞定了。

 

具体步骤为:

  1. 判断系统是否为Vista或以上
  2. 获取一个普通权限的安全令牌(token)
  3. 使用这个token,通过CreateProcessAsUser或CreateProcessWithTokenW创建进程

第1步和第3步都很容易。第2步,找到的大部分资料都是通过各种手段查找explorer进程,比如遍历进程或者寻找桌面或托盘区窗口句柄,然后复制explorer进程的token。这种方法,虽然是可行的,但是不稳定,如果创建进程时explorer进程刚好被结束掉了呢?于是就继续找到了下面这种方法:

  1. 获取自身进程的token
  2. 复制这个token
  3. 修改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,创建进程就很简单了。
这里有份示例代码和一个测试程序,如果需要的话可以下载

 

参考资料:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

扫码去手机上看