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

Windows Vista用户帐户控制、PsExec和安全边界

 

文章原著 Mark Russinovich
翻译作者 盆盆 [ITECN博客站长]  
http://blogs.itecn.net/blogs/ahpeng
盆盆导读 本文由Mark Russinovich所著,由盆盆所翻译。由于原文偏重于原理的阐述,所以为了加深大家对文章的理解,盆盆还特地加注了大量对原理注释和相关示例。这篇文章主要描述:对用户帐户控制、IE保护模式、UIPI和MIC等的安全意义和不足之处进行描述。为了保证原汁原味,翻译文章保留第一人称,文中的“我”就是指Mark Russinovich。

大约一年半以前,我给PsExec命令新设计了一个“-l”参数,这样我们就可以方便地在Windows XP的管理员帐户下,以标准用户的权限启动某个进程。在《Running as Limited User – The Easy Way》这篇文章里,我介绍了PsExec如何调用CreateRestrictedToken的API函数来创建安全上下文,该安全上下文来自于当前的登录帐户,但是排除了本地管理员组的成员关系,同时还排除了仅分配给管理员的特权(例如“调试程序”特权)。运行在该安全上下文中的进程,拥有标准用户的特权和访问权限,防止该进程修改系统文件和注册表键值,同时防止该进程使用只有管理员才能拥有的特权,例如“加载和卸载设备驱动程序”特权。

盆盆评注 在Windows Vista下,不仅可以用PsExec命令以标准用户权限运行进程。还可以用软件限制策略、“运行方式”、以及DropMyRights命令等方法,以更低权限运行进程,具体可见盆盆的文章《IE浏览器的最佳安全保护》

在受限令牌所形成的隔离沙盒中,唯一的缺陷是:在隔离沙盒中的进程是以当前用户的身份运行的,所以只要当前用户有权读写的文件、注册表键值、甚至别的进程,该进程都能访问。这样就能打穿隔离沙盒的墙壁,如果恶意代码是专门为这种受限环境而编写的,那么它就可以利用这种手段,绕过隔离沙盒的限制,从而窃取完全的管理员权限。对于恶意程序来说,很有一个很简单的方法,只需使用OpenProcess函数,就可以读写隔离沙盒外的某个进程,并用自己的代码感染该进程,再插入一个线程,就可以执行代码。因为其他进程是以当前用户身份运行的,而Windows安全机制默认允许当前用户可以完全访问所有用户进程,因此沙盒里的进程也可以打开沙盒外的用户进程。还有一个方法,受限进程可以给正常进程(例如Explorer)发送窗口消息,用定制的鼠标和键盘输入来控制该正常进程,这样就能按照恶意程序的意图执行代码。

盆盆评注 粉碎攻击等就是利用这种代码注入的方法提升权限。

既然有那么多漏洞,为什么还要推荐大家使用这个PsExec参数?这是因为使用这种隔离沙盒的用户并不多,所以恶意程序的作者一般不愿意花费精力编写代码,绕开这种隔离沙盒的限制。

然而在Windows Vista下,情况发生了变化,这是因为采用了用户帐户控制和IE保护模式,隔离沙盒的安全得到了很大的增强。接下来我们一起探讨一下Windows Vista里的隔离沙盒,如何借助PsExec的最新版本,让进程运行在Windows Vista的最新隔离沙盒中,同时还将描述其安全内在意义。

在用户帐户控制下,所有用户(包括管理员),都运行在标准用户权限下。如果某个程序需要管理员权限,可以在程序清单(代码中内嵌的XML)的requestedExecutionLevel参数中赋值“requireAdministrator”。如果当前帐户是管理员,默认会弹出一个“用户帐户控制”对话框,询问是否允许该程序以管理员权限运行。如果当前用户是标准用户,则需要在“用户帐户控制”对话框上输入某个管理员帐户的凭据,以便提供管理员权限。

盆盆评注 要了解更多有关用户帐户控制的信息,包括应用程序如何通过程序清单的定义来通知Windows它所需的权限等等,可以参考盆盆的文章Windows Vista用户帐户控制深入剖析》。

在用户帐户控制中,给程序提供管理员权限的过程称作“提升权限”。无论是在标准用户环境里提升权限(OTS:即时提升),还是在管理员环境里提升权限(AAM:管理员批准模式),不管是以提升权限运行的进程(高级进程),还是以标准权限运行的进程(标准进程),它们都位于同一个桌面上。在标准用户环境里,高级进程和标准进程,它们以不同的帐户身份运行,所以Windows安全机制可以在高级进程周围竖立隔离墙,以防标准进程在高级进程中写入代码。但是以前的Windows安全机制并不阻止标准进程向高级进程发送欺骗性质的鼠标和键盘输入消息,同时也不会把标准进程放入隔离沙盒(以防它们攻击高级进程)。因此Windows Vista引入了Windows完整性机制,在标准进程的隔离沙盒的外围再添加一圈篱笆。

在Windows Vista的完整性机制下,每个进程都在某个完整性级别(IL)下运行,同时每个资源对象也具有完整性级别。主要的完整性级别(IL)有四个:低级、中级(默认,标准进程)、高级(高级进程)和系统。Windows的窗口系统采用完整性机制,以防止较低完整性级别的进程向较高完整性级别进程的窗口发送大多数窗口消息,这种保护机制叫做用户界面特权隔离(UIPI)。Windows Vista的最新安全机制还有一个改变,只有进程的完整性级别等于或者高于某个资源对象的完整性级别时,该进程才能打开该资源对象进行写入操作。而且,为了防止访问存放在内存中的机密信息,进程不能打开拥有更高完整性级别的其他进程进行读取操作。

盆盆评注 Mark的原文举例介绍进程和资源对象的隔离(低级别进程不能写入高级别的资源对象),参见下方的正文部分。这里补充一个实例,介绍进程之间的隔离(均以管理员帐户登录系统)。

1. Windows XP下的实验

首先介绍Windows XP下的情况,启动一个记事本程序(以管理员权限运行)。运行以下命令,以标准用户权限打开命令提示符窗口:
PsExec -l -d CMD
然后我们运行以下TaskKill命令,看看低级进程Taskkill能否关闭高级进程记事本程序:
Taskkill /FI "ImageName EQ Notepad.exe"
结果发现可以顺利运行,如附图所示(图中的Whoami命令显示,当前的命令提示符窗口以标准用户权限运行),这说明在Windows XP下,隔离沙盒存在漏洞,低级进程可以对高级进程进行操作。

2.  Windows Vista下的实验

同样对Windows Vista进行实验。直接打开命令提示符窗口,由于UAC的作用,命令提示符窗口运行在标准用户权限下。然后再以管理员身份运行记事本软件。
接下来运行Taskkill命令,看看低级进程Taskkill能否关闭高级进程记事本程序。
结果发现可以拒绝访问,如附图所示。这说明在Windows Vista下,隔离沙盒可以有效防止低级进程对高级进程的操作。

如果在Process Explorer的视图中添加“Integrity Level”列,如下图所示。我们可以看到系统进程,例如Windows服务进程,运行在“系统”完整性级别。登录会话中的绝大多数进程运行在“中级”完整性级别,以提升权限运行的进程在“高级”完整性级别,而IE浏览器则运行在“低级”完整性级别(如果启用IE保护模式)。我们可以启用系统内置的icacls.exe命令行工具查看和修改文件和目录的完整性级别,可以用Sysinternals的AccessChk工具查看文件、目录、注册表键值和进程的完整性级别。资源对象默认具有“中级”完整性级别,我们可以使用“AccessChk -e”命令搜索具有显式完整性级别的对象。
 

盆盆评注 该图并非原图,图中的“Integrity Level”一列套绿显示。有关AccessChk命令的用法,可以参考盆盆的文章《Windows Vista IE保护模式深度剖析》,有关Icacls命令的用法,可以参考盆盆的文章Windows Vista IE下紫光拼音的终极解决办法》

新版本的PsExec命令利用了Windows Vista这个增强的隔离沙盒,当使用“-l”参数时,可以让指定的进程运行在“低级”完整性级别。PsExec所建立的隔离沙盒等效于IE保护模式,想要体验这种安全隔离效果,可以尝试让命令提示符窗口或者Regedit运行在“低级”完整性级别,然后看看可以修改什么。举个例子,用以下命令,让命令提示符窗口运行在“低级”完整性级别:

PsExec -l -d

首先我用“set”命令确定当前用户的临时目录所在路径。如果尝试在该临时目录创建文件,就会收到拒绝访问的错误消息,这是因为该临时目录的完整性级别为默认的“中级”,如果用icacls命令查看该目录的权限设置,并不会看到完整性级别(译者注:表明是默认的“中级”)。如果把当前目录修改为IE浏览器的临时目录(完整性级别为“低级”),就可以成功创建文件。
 

盆盆评注 从图中我们可以很容易看到,Mark先用“set temp”命令查看“temp”环境变量的值。然后用cd命令进入“temp”目录。再用“icacls .”命令查看当前目录的权限设置(.表示当前目录)。结果发现无法在“temp”目录下写入文件,但是可以在“LocalLow”目录下写入文件,因为用icacls命令查看,发现“LocalLow”目录的完整性级别为“低级”(Low Mandatory Level)。

通过实验可以了解到我们的操作受到了限制,但是这里有一些设计上的考虑需要我们注意。首先,除了进程和线程之外,隔离沙盒并不阻止读取操作。这意味着完整性级别为“低级”的命令提示符、或者IE浏览器(启用IE保护模式)可以读取当前帐户所能访问的对象。这些对象包括当前用户的文档和注册表键值。

有时候完整性级别为“低级”的进程,甚至还可以对更高级别的对象进行操作。因为不同完整性级别的进程共享同一个桌面,所以它们共享同一个“会话”。每个用户登录系统时,会创建一个新的会话,该用户的进程就在这个会话中运行。会话也提供本地的命名空间,这样用户进程就可以通过诸如同步对象或者共享内存这样的共享对象进行通信。这意味着完整性级别为“低级”的进程,可以创建一个共享内存对象(叫做区域或者内存映射文件)以供高级别的进程访问,并在该共享内存里存储数据,这样高级别的进程就会执行其中的恶意代码(如果该进程没有正确地验证数据)。这种攻击手段叫做蹲守攻击(squatting attack),比较复杂,需要用户按照特定顺序执行进程,并且需要了解应用程序是如何通过共享对象进行操作的内部原理。

盆盆评注 会话是天然的安全屏障,跨越会话进行攻击是非常困难,Windows Vista下的服务就实现了会话隔离,让服务存在于会话0中,以避免用户进程跨越会话进行攻击。

然而我们必须清楚,无论这种攻击方法有多么困难,但是既然这种隔离沙盒存在突破口,这就说明完整性级别并没有定义安全边界。什么是安全边界?安全边界就是一道隔离墙,如果没有通过安全策略的验证,代码和数据就不能打破这道隔离墙。举个例子,在不同的会话中运行的用户帐户,会通过Windows安全边界进行分隔。如果没有其他用户的允许,一个用户不能读取或者修改其他用户的数据,也不能让其他用户执行代码。如果由于某些原因而可以绕过安全策略,这就意味着Windows系统存在bug(或者是第三方代码的原因)。

我们还必须清楚,不管是用户帐户控制、还是IE保护模式,都没有定义新的Windows安全边界。虽然微软已经表明了这个观点,但是我希望大家对此能够有一个明确的认识。此外,正如Jim Allchin在他的博客文章《Security Features vs Convenience》里所写的,Windows Vista在安全性和易用性上作了权衡,用户帐户控制和IE保护模式在设计时已经考虑到应用程序兼容性和易用性,可以有方法绕过完整性级别的隔离墙限制。

在安全性和易用性之间取得平衡,其中的一个例子是:在标准用户环境下即时提升权限(OTS)时,我们不需要按“Ctrl+Alt+Del”组合键才能调出“用户帐户控制”对话框。还有其他的一些例子,例如我在TechEd/ITForum上所讲的课程《User Account Control Internals and Impact on Malware》,Jim Allchin的博客文章里也提到一些安全增强的方法(可能会减弱易用性),例如我们可以配置Windows必须按“Ctrl+Alt+Del”组合键才能调出“用户帐户控制”对话框。举一个例子,在管理员环境下,以提升权限运行的高级进程,和其他进程一样都是以当前登录用户的身份运行,方便这些进程访问当前用户的代码和数据,但是同时也允许其他进程修改同样的代码和数据,这样就可能导致高级进程运行恶意代码。

盆盆评注 大家知道,在Windows Server上,默认需要按“Ctrl+Alt+Del”组合键(SAS序列),而只有Winlogon进程才能接受该SAS序列,以确保安全性。所以也可以设置,只有按“Ctrl+Alt+Del”组合键(SAS序列),才能弹出“用户帐户控制”对话框,以便确保安全性。否则的话,恶意代码完全可以伪造一个“用户帐户控制”对话框,让用户输入管理员凭据。

按照Jim Allchin的说法,我们可以打开组策略编辑器,然后进入计算机配置→管理模板→Windows组件→凭据用户界面,然后确保启用“要求输入凭据的受信任路径”策略项,如下图所示。

这样,当我们以标准用户身份登录系统时,如果需要执行管理任务,系统就会提示按下“Ctrl+Alt+Del”组合键(SAS序列),然后系统就会切换到Winlogon桌面(看上去是“真正”的安全桌面,而不是灰色的当前桌面背景),并显示“用户帐户控制”对话框,以提示输入管理员凭据。

因为提升权限和完整性级别并没有定义新的安全边界,所以虽然存在可能的安全攻击方法,不管是否容易或者使用范围,都不能算是安全上的bug。所以,既然不能保证防止更低级别的进程攻击高级别的进程,为什么Windows Vista还要那么麻烦引入提升权限和完整性级别的功能?原来这是为了能够让所有用户都运行在标准用户权限下,同时让所有应用程序都按照这个标准进行开发,以达到一个新的境界。

如果提升权限缺乏易用性,那么绝大多数用户就会回到以前Windows版本的状态:始终使用管理员特权。IE保护模式和“PsExec -l”命令,就可以利用完整性级别,在恶意程序的周围建立隔离沙盒,哪怕恶意程序已经突破了其他安全防护手段。提升权限和IE保护模式所构建的隔离沙盒虽然可能存在可攻击的方法,但是总比没有好。如果把安全性看的比易用性更加重要,那么就利用安全边界的作用,平时用独立的帐户以标准用户身份运行,当执行管理任务时,再切换到专门的帐户中。

盆盆评注 安全性和易用性是一对矛盾,不可能找到一种一劳永逸的方法,以杜绝所有的攻击手段。用户帐户控制和IE保护模式照样存在可能的攻击手段,但是尽管如此,还是希望大家启用这些安全功能,正如Mark所说,有总比没有好。同时安全不仅仅是操作系统的责任,用户习惯、应用程序等都非常重要,而且很可能成为木桶上最短的一块木板。

已发表 2007年2月25日 23:58 作者 ahpeng

评论通知

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

订阅帖子评论使用 RSS

评论

2007年2月26日 8:07 by ahpeng

# re: 用户帐户控制、PsExec和安全边界

本文涉及的一些术语:

Sandbox:隔离沙盒

Security Boundary:安全边界

Mark Russinovich的原文链接:

http://blogs.technet.com/markrussinovich/archive/2007/02/12/638372.aspx

2007年2月26日 9:09 by Asuka

# re: 用户帐户控制、PsExec和安全边界

谢谢盆盆!

2007年2月27日 11:42 by yinjie

# re: Windows Vista用户帐户控制、PsExec和安全边界

very good!

2007年2月27日 14:01 by ahpeng

# re: Windows Vista用户帐户控制、PsExec和安全边界

殷杰兄弟,多谢大驾光临!

Asuka朋友,欢迎光临ITECN博客,如果您觉得ITECN好,麻烦推荐给您的朋友,呵呵。

2007年2月27日 21:05 by 盆盆的博客

# Windows Vista有趣的标签SID

本文介绍Windows Vista的一个非常有趣的现象,可以绕过UAC的提示框,大家一定要去看看哈~~此外,本文还着重介绍了标签SID的两大作用,定义完整性级别、判断UAC权限提升,最后还分析了由此引发的安全意义探讨。

2007年3月2日 19:49 by 深入研究Windows内部原理

# Windows Vista安全原理深入探索

在探索和学习Windows Vista的过程中,盆盆从《Windows Internals》一书中深受启发,本文虽然改写自盆盆以前的文章,但是绝非简单的改写,盆盆还特地加入了自己最新探索和学习到的一些知识,放在本专栏的开篇,就算是抛砖引玉吧。本文即将在《程序员》杂志上发表,谢绝转载。

2007年3月14日 12:15 by Windows Vista博客

# Windows Vista的UAC也可以很方便

盆盆 在国内一家知名的Windows Vista在线讨论平台上做过 调查 (共有约1200多人参与投票),到目前为止,大概有约43%的用户认可“最小帐户特权”的功能。其中包括约38%的用户选择使用UAC,还有超过4%的用户平时用标准用户登录。

2007年3月16日 11:38 by Windows Vista博客

# Windows Vista的UAC也可以很方便

有那么多人禁用UAC,其实只需做简单的设置,就可以既方便、又安全。[已经修改过,新增了不少内容]

2007年3月18日 23:13 by 盆盆的博客

# Windows Vista的UAC也可以很方便:脚本原理的解释

在《Windows Vista的UAC也可以很方便:一个脚本轻松搞定》这篇文章里,盆盆描述了如何用一个脚本文件轻松完成所有设置。这里就来解释一下这个脚本的具体含义。

2007年5月22日 11:15 by mlu

# re: Windows Vista用户帐户控制、PsExec和安全边界

盆盆,您好,我初学vista,按照这篇文章的例子作了一下,发现,在temp下是可以创建文件并且写入的。请问这是怎么回事,我开启了UAC。

2007年7月4日 14:17 by 无我

# re: Windows Vista用户帐户控制、PsExec和安全边界

我使用的是2003 SP1,日常使用中必须以管理员登陆,所以常用低权限启动IE。看了以下知识后做了试验,发现在2003 SP1下,低权限无法访问需要高权限才能访问的进程或文件。在这方面,2003 SP1的安全性似乎和Vista平分秋色。

(在受限令牌所形成的隔离沙盒中,唯一的缺陷是:在隔离沙盒中的进程是以当前用户的身份运行的,所以只要当前用户有权读写的文件、注册表键值、甚至别的进程,该进程都能访问。这样就能打穿隔离沙盒的墙壁,如果恶意代码是专门为这种受限环境而编写的,那么它就可以利用这种手段,绕过隔离沙盒的限制,从而窃取完全的管理员权限。对于恶意程序来说,很有一个很简单的方法,只需使用OpenProcess函数,就可以读写隔离沙盒外的某个进程,并用自己的代码感染该进程,再插入一个线程,就可以执行代码。因为其他进程是以当前用户身份运行的,而Windows安全机制默认允许当前用户可以完全访问所有用户进程,因此沙盒里的进程也可以打开沙盒外的用户进程。)

2008年8月2日 8:22 by Asuka's Blog

# Mark's Webcasts: Windows Security Boundries(Windows安全边界)

好久没有看到Mark的大作了,难道是去备战奥运了?呵呵。 刚刚在Sysinternals的blog看到了有个Mark在今年Teched US上面的Session,是和安全边界有关的。 地址: http://blogs.technet.com/sysinternals/archive/2008/07/30/mark-s-webcasts-windows-security-boundries.aspx

说说您的看法?

(必填) 
必填 
(必填)