欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

Windows Vista安全原理深入探索

 

本文是对盆盆以前发表过的文章《UAC功能浅析》一文的改写和扩充。一方面老的那篇文章是根据Build 5231而写,内容比较陈旧,所以这次根据Windows Vista正式版本进行改写;另一方面,本文绝非简单的改写,盆盆还特地加入了自己最新探索和学习到的一些知识,希望能够让读者朋友满意。

盆盆评注 笔者在探索和学习Windows Vista安全理论的过程,深受《Windows Internals》一书的启发。该书由Mark Russinovich和David Solomon所著,堪称IT Pro和Dev的圣经。

参考

用户帐户控制(UAC),是Windows Vista新引入的安全机制。管理员登录Windows时,系统会同时创建两个访问令牌,其中一个是完全的管理员访问令牌(Full Token),另一个是经过“过滤”的访问令牌,叫做标准用户访问令牌,如附图所示。当Windows系统启动Shell进程(Explorer.exe)时,LSA会把标准用户访问令牌连接到Shell进程,所以Windows Vista启动的用户进程,默认都只具有标准用户权限。如果某个进程需要管理员权限,则系统会提示权限提升,得到用户亲自确认后,系统会把完全的管理员访问令牌连接到该进程上。
 单击看大图
准备知识

在《Windows Internals》的第八章“安全”部分,介绍了一个实例:当我们在Windows XP里启动“日期和时间”控制面板组件时,实际上启动的是“rundll32”进程,由该进程加载“Timedate.cpl”控制面板组件。用Process Explorer检查该“rundll32”进程的访问令牌,可以发现“SeSystemTimePrivilege”特权处于启用状态,如附图所示。
单击看大图
“SeSystemTimePrivilege”是“更改系统时间”特权的内部名称,所有特权都保存在LSA的策略数据库中,该数据库会加载到HKLM\SECURITY注册表分支,用户登录系统时,LSA会读取这些特权值。

对于Windows XP专业版,我们可以通过“本地安全策略”管理单元查看用户所具有的特权。可以看到,“更改系统时间”特权仅授予管理员组和Power Users组用户,如附图所示,这就是为什么在Windows XP下,标准用户无法修改系统时间和时区的原因。
单击看大图
盆盆评注 笔者曾经写过一个连载,介绍帐户的登录权利所对应的HKLM\SECURITY注册表键值。可以用同样方法得出特权所对应的注册表键值。

实验准备

现在我们已经知道,要修改系统时间,当前帐户必须具备“更改系统时间”特权。但是在Windows Vista下,默认不是只有标准用户权限吗,这时候应该没有“更改系统时间”特权!那么系统是如何获得“更改系统时间”特权的呢?我们用实验来进行验证。

1. 实验工具

本实验在Windows Vista中文旗舰版上进行,测试帐户为Admin,是管理员组成员。为了查看进程的访问令牌,需要采用先前提到的Process Explorer工具,下载地址如下:

http://www.microsoft.com/technet/sysinternals/utilities/ProcessExplorer.mspx

还有一个Process Monitor工具,下载地址如下:

http://www.microsoft.com/technet/sysinternals/utilities/processmonitor.mspx

2. 禁用安全桌面

由于“用户帐户控制”对话框默认运行在“安全桌面”上,这里的安全桌面就是我们按“Ctrl+Alt+Del”组合键所进入的桌面。但是为了改善用户体验,UAC的安全桌面并不是蓝绿色的背景,而是当前用户桌面桌面背景的截图快照(呈暗色显示)。

盆盆评注 参考盆盆翻译自Mark Russinovich的文章,了解如何强制用户必须按“Ctrl+Alt+Del”组合键,才能打开UAC的凭据输入对话框,这样可以确保凭据的安全。

之所以启用“安全桌面”,主要是因为考虑到安全因素,以防其他进程可以对“用户帐户控制”对话框进行操作。但是由于本实验需要用工具对UAC的过程进行全程监控,所以需要临时禁用“安全桌面”功能,方法如下。

运行“secpol.msc”并回车,打开“本地安全策略”对话框,然后在左侧的控制台树里定位到本地策略→安全选项,在右侧详细窗格里双击“用户帐户控制:提示提升时切换到安全桌面”策略项,并选中“已禁用”选项,如附图所示。
单击看大图

实验记录

1.查看rundll32进程访问令牌

单击任务栏通知区域的时钟图标,然后单击底部的“更改日期和时间设置”链接,即可打开“日期和时间”窗口。正如您所预料的,这时候还不能对系统时间进行任何修改。同时可以在Process Explorer窗口中看到新增一个进程rundll32(呈绿色显示)。

双击该rundll32进程,即可打开其属性对话框。在“Image”标签页的“Command Line”文本框里可以看到“timedate.cpl”(“时间和日期”的控制面板扩展文件),如附图所示。这说明该rundll32.exe就是“时间和日期”控制面板组件的宿主进程。
单击看大图

切换到“Security”标签页里,就可以看到该rundll32进程的访问令牌,可以看到在下方的特权列表里,只有少得可怜的五个个特权,而其中并没有SeSystemTimePrivilege特权!这就是为什么在默认情况下,无法在管理员环境下修改系统时间的原因。
 单击看大图

2.提升权限

要能够修改系统时间,只需单击“日期和时间”窗口右下侧的“更改日期和时间”按钮,即可打开 “用户帐户控制”对话框,单击“继续”按钮,如附图所示。现在应该可以修改系统时间了。
 单击看大图
看来这个“用户帐户控制”对话框负责向系统传递消息,以便系统确认用户同意提升操作权限。其本质似乎应该是修改相关进程的访问令牌,就本例来说,应该是在rundll32进程的访问令牌里添加SeSystemTimePrivilege特权。那么果真是这样吗?

结果很让人沮丧,重新打开rundll32进程的属性对话框,并切换到“Security”标签页,发现其访问令牌没有任何改变(并没有新增SeSystemTimePrivilege特权)!

这是为什么呢?

3.查看dllhost进程的访问令牌

反复重新做实验后,终于发现在“用户帐户控制”对话框上单击“继续”按钮后,系统会新增一个dllhost进程,在其进程属性对话框的“Image”标签页的“Command Line”文本框里可以看到“/Processid: {9DF523B0-A6C0-4EA9-B5F1-F4565C3AC8B8}”参数,如附图所示。
单击看大图

搜索注册表得知,{9DF523B0-A6C0-4EA9-B5F1-F4565C3AC8B8}就是timedate.cpl的AppID,如附图所示。
单击看大图

在dllhost进程的属性对话框上,切换到“Security”标签页,不出所料,dllhost进程的访问令牌里果然有SeSystemTimePrivilege特权,而且是启用状态,如附图所示。
单击看大图

现在真相大白了,原来Windows Vista表面上让rundll32进程“明修栈道”,背地里却让dllhost进程“暗渡陈仓”,把完全的管理员令牌赋予该dllhost进程,真正让我们可以修改系统时间的是dllhost进程!

4.系统背后的动作

为了更好地对系统背后的动作进行监测,我们再启动Process Monitor,然后再重复上述的操作。

结果在Process Monitor里监测发现,单击“日期和时间”窗口右下侧的“更改日期和时间”按钮,发现由svchost进程(进程ID为1924)启动consent.exe进程,这个consent.exe进程就是“用户帐户控制”对话框,如附图所示。
单击看大图

盆盆评注 在Windows Vista下,应该用Process Monitor代替Filemon和Regmon,Process Monitor除了可以监控注册表和文件活动外,还可以监控进程的活动,包括其堆栈信息。

双击这条记录,在打开的属性对话框上切换到“stack”标签页。在其堆栈信息中发现一个“appinfo.dll”模块,其描述为“应用程序信息服务”,如附图所示。原来这就是Windows Vista系统的“Application Information”服务,当系统确认进程需要管理员权限时,就会由“Application Information”服务负责启动consent进程,以便打开“用户帐户控制”对话框。
单击看大图
在Process Explorer中打开consent进程的属性对话框,在“Image”标签页也可以发现consent的父进程的进程ID为“1924”(svchost进程),如附图所示。

单击看大图

打开进程ID为1924的svchost进程的属性对话框,并切换到“Services”标签页,可以看到其下有“Application Information”服务,该服务以“appinfo.dll”的形式运行在svchost进程中,如附图所示。
单击看大图

在“用户帐户控制”对话框上单击“继续”按钮后,系统获得来自用户的确认信息,接下来我们可以通过Process Monitor监测到由另一个svchost进程(进程ID为1376)加载dllhost的进程映像文件,如附图所示。
单击看大图

双击这条记录,在打开的属性对话框上切换到“stack”标签页,在堆栈信息中发现一个“rpcss.dll”模块,其描述为“分布式COM服务”,如附图所示。原来这就是Windows Vista系统的“DCOM Server Process Launcher”服务,由该服务负责启动dllhost进程。
单击看大图

在Process Explorer中双击打开进程ID为1376的svchost进程的属性对话框,并切换到“Services”标签页,可以看到其下有“DCOM Server Process Launcher”服务,该服务以“rpcss.dll”的形式运行在svchost进程中,如附图所示。
单击看大图

盆盆评注 “Remote Procedure Call (RPC)”服务也是以“rpcss.dll”的形式运行在另外一个svchost进程中。但是两个并没有服务共享同一个svchost进程,这是因为这两个服务的启动帐户不同。“Remote Procedure Call (RPC)”服务的启动帐户是NETWORK SERVICE,而“DCOM Server Process Launcher”服务的启动帐户是SYSTEM。

接下来在Process Monitor中,我们可以看到dllhost进程检查HKCR\AppID\{9DF523B0-A6C0-4EA9-B5F1-F4565C3AC8B8}注册表键值,如附图所示。以便知道应该加载“Timedate.cpl”注册表组件,并最终允许修改系统时间。

单击看大图
5.比较前后访问令牌的SID列表

仔细观察前后两个进程(rundll32进程和dllhost进程)访问令牌中的SID列表,如附图所示,会发现有以下两个显著的不同。
单击看大图

(1) rundll32进程:Administrators组SID被标记为Deny,这表明该进程实际上不属于管理员组。同时访问令牌里只有五个特权,其中并没有“SeSystemTimePrivilege”特权。

访问令牌里包含一个名为“Mandatory Label\Medium Mandatory Level”的标签SID。

(2)dllhost进程:Administrators组SID被标记为Owner,这表明该进程属于管理员组。同时访问令牌里包含“SeSystemTimePrivilege”特权。

访问令牌里包含一个名为“Mandatory Label\High Mandatory Level” 的标签SID。

6.修改系统时区

大家知道,在Windows XP下,我们无法在标准用户下修改系统时区。但是在Windows Vista却可以,无需提升权限,不知道读者朋友有没有考虑过这个问题。

原来这是因为Windows Vista的标准用户多了一个“SeTimeZonePrivilege”(更改时区)特权,所以无需提升权限,就可以修改系统的时区,这给标准用户带来方便。

进一步研究发现,在打开“日期和时间”对话框时,其宿主进程rundll32的访问令牌中,虽然有“SeTimeZonePrivilege”,但是其状态为“Disabled”(如上图所示)。

而只有在单击“更改时区”按钮时,rundll32进程的“SeTimeZonePrivilege”特权才会被激活,如附图所示。
单击看大图

实验结论

1.UAC的实质

当管理员登录时,Explorer进程会获得一个“缩水”的访问令牌,也叫标准用户(Standard User)访问令牌。由于用户进程大多数都是由Explorer启动,所以这些进程会自动继承这份“缩水”的访问令牌(如本例的rundll32进程)。

凭借缩水的访问令牌,用户可以完成绝大多数工作,同时由于用户权限被大大缩小,这样用户进程就不会有意无意破坏系统的完整性,这样就可以大大减少受攻击面。

如果需要执行管理任务,系统会提醒用户进行确认,一旦认可,将会获得完全版本的管理员访问令牌(如本例的dllhost进程)。

用户帐户控制好比给Windows Vista穿上一件铁布衫,有了它的庇护,Windows系统不再奉行“不抵抗”政策,恶意网页胆敢再来“骚扰”,将被毫不犹豫地阻止。同时最终用户不再需要接受额外的培训,一切都由系统自动完成,只需要做出选择即可,您就没事偷着乐吧!

2.标签SID

至于前后两个进程的访问令牌中新出现的标签SID,其中一个是“Mandatory Label\Medium Mandatory Level”,另一个是“Mandatory Label\High Mandatory Level”。这两个帐户,既不能用来登录,似乎也不能用来,到底用来做什么?

原来这是用来标记访问令牌,这样系统看到访问令牌中包含“Mandatory Label\Medium Mandatory Level”的标签SID,马上就可以知道该令牌属于标准用户访问令牌;同样如果令牌中包含“Mandatory Label\High Mandatory Level”的标签SID,马上就知道其属于完全的管理员访问令牌。

那么为什么不在访问令牌中新增一个标志位?例如等于0时就是标准用户令牌,等于1时就是完全权限令牌?这样的话,就不需要新增标签SID了。也许是为了兼容性,毕竟增加一个标志位,就等于要修改访问令牌的数据结构,这可不是一个好主意,而添加几个SID,则相对简单得多。

标签SID的作用很大,当进程需要管理员权限时,系统会根据其父进程的标签SID,来判定是否需要弹出“用户帐户控制”对话框。如果其父进程的标签SID是“Mandatory Label\Medium Mandatory Level”,系统就会弹出“用户帐户控制”对话框。如果父进程的标签SID是“Mandatory Label\High Mandatory Level”,就不会弹出“用户帐户控制”对话框,而是直接运行该目标进程。

由于绝大多数用户进程的父进程是Explorer,所以会弹出“用户帐户控制”对话框。

除此之外, Windows安全子系统还用标签SID来帮助判断一个进程是否可以访问特定的资源对象,是否可以访问某个特定的进程。

盆盆评注 有关标签SID的详细作用,可以参考盆盆发表在ITECN博客上的文章《Windows Vista有趣的标签SID》:http://blogs.itecn.net/blogs/ahpeng/archive/2007/02/27/labelsid.aspx

写在最后

《Windows Internals》能够帮助我们更好地了解Windows的内部运作原理,不管是IT Pro,还是Dev,都可以从中获取有用的信息。期待由潘爱民老师翻译的中文版《Windows Internals》尽快上市。

已发表 2007年3月2日 19:41 作者 ahpeng
归档在:

评论通知

如果您想在帖子更新时接到邮件通知,请先登录。这里

订阅帖子评论使用 RSS

评论

# Windows Vista安全原理深入探索

2007年3月2日 19:58 by 盆盆的博客

在探索和学习Windows Vista的过程中,盆盆从《Windows Internals》一书中深受启发,本文虽然改写自盆盆以前的文章,但是绝非简单的改写,盆盆还特地加入了自己最新探索和学习到的一些知识。

# re: Windows Vista安全原理深入探索

2007年3月3日 16:00 by yanguhong

在盆盆这里真是学到了很多东西,让我大开眼界,谢谢!!

# re: Windows Vista安全原理深入探索

2007年3月4日 10:36 by seekf

非常感谢盆盆老师的精彩分析及实验

# re: Windows Vista安全原理深入探索

2007年3月6日 7:48 by ahpeng

感谢两位对ITECN的支持,盆盆会继续努力。

# re: Windows Vista安全原理深入探索

2007年3月9日 16:06 by 逍遥海儿

深入!--!真够深入的

# Windows Vista的UAC对话框果真是在会话0吗?

2007年4月14日 12:30 by 盆盆的博客

小青蛙s老大新发表的 雄文 ,可以让读者朋友对UAC安全桌面的切换机理又加深了印象。例如读者朋友们可以知道,为了防止用户进程干扰UAC的对话框,可以让它运行在安全桌面上。而大家知道,安全桌面(Winlogon桌面)默认是蓝绿色背景的,为了改善用户体验,微软特地对当前用户桌面截图,并以截图作为安全桌面的背景,这样看上去稍微舒服一些。这个原理,在盆盆的拙作

# Windows Vista的UAC对话框果真是在会话0吗?

2007年4月14日 12:36 by 盆盆的博客

小青蛙s新发表的文章,可以帮助读者朋友进一步了解UAC安全桌面的机理。本文要讨论的是,默认启用安全桌面后,UAC对话框真的运行在会话0上面吗?本文用实验来查看,并试图给出原理解释。

# re: Windows Vista安全原理深入探索

2007年12月3日 23:24 by wang

强呀,佩服呀

# re: Windows Vista安全原理深入探索

2008年4月13日 3:27 by F

偶还是有点不懂,每天我都会来等您的答案的!

第一点 :TOKEN的概念不理解!

第二点:SYSTEM LOGON SESSION对应的是不是就是SYSTEM帐户,这个SYSTEMN帐户到底存在不?如果存在那它对应的SIM值是多少!

说说您的看法?

(必填) 
必填 
(必填)