本文翻译于MSDN文章,名称为:Understanding and Working in Protected Mode Internet Explorer。
Url:http://msdn.microsoft.com/zh-cn/library/bb250462(en-us,VS.85).aspx
译序:看英文的文章老是觉得隔一层纱,此次下定决定翻译一篇英文文档,以提升自己英文阅读能力,也方便网友的阅读,如下便是文章,有翻译不当之处,敬请指正。
理解在保护模式下Internet Explorer的工作方式
Marc Silbey,
Peter Brundrett
Microsoft Corporation
2006 年 1 月
最后更新:2009年 2 月
适用于: Windows Internet Explorer 7 在 Windows Vista 和以后的系统中
摘要
在Windows Vista中,Internet Explorer 7 运行在保护模式下,保护模式能够帮助用户保护来自大大限制特权的运行中Internet Explorer 进程的攻击。保护模式显著减少写、更换、在用户机器上毁坏数据或植入恶意代码攻击的可能性。
这篇文章介绍保护模式,描述用来实现保护模式的Windows Vista的特性,展示如何开发在保护模式中工作的扩展组件,提出开发更具安全性程序的指导方针。
目录
l 理解保护模式
n 保护模式简介
n 理解Windows Vista的完整性机制
n 理解保护模式
n 配置保护模式
l 在保护模式下运行
n 寻找低完整性可写路径
n 保存文件到用户属性中
n 在保护模式下创建进程
n 在程序中允许拖拽功能
n 允许程序接收Windows消息
n 运行和导向保护模式进程
n 使用应用程序兼容性工具包调试程序
l 开发安全扩展组件
n 从扩展组件中安装软件
n 运行低完整性级别的进程
n 降低资源的完整性
n 确定进程的完整性级别
l 常见问题
理解保护模式
保护模式是Internet Explorer(IE)的一个重要的进步;它使用限制权限帮助用户在Windows Vista中保护IE 进程。而保护模式并不保护所有的攻击,它显著减少写、更换、在用户机器上毁坏数据或植入恶意代码攻击的可能性。
保护模式简介
对于Windows Xp Service Pack 2 大多数Internet Explorer 7 的安全特性都是可用的,而保护模式仅仅在Vista中奏效,因为它基于Windows Vista 新的安全特性。
n 用户账户控制(UAC)在没有管理员权限下可以很容易使得程序运行。当用户在限制权限下运行,他们比运行在管理员权限下更安全,因为Windows 能够限制恶意代码执行破坏性操作。
n 完整性机制通过较低完整性进程,限制安全对象的写访问,同样的,同一个组的用户账户限制用户访问系统敏感组件的权限。
n 用户界面特权隔离(UIPI)阻止进程向更高完整性的进程发送Windows消息和USER APIs。
当需要代扣特权来静默安装程序或更改敏感系统数据时。Windows Vista安全特性允许保护模式提供访问网页的权限。
这个段落帮助你理解保护模式,描述了Windows Vista完整性访问级别,总结了Internet Explorer扩展的兼容性影响。
理解Windows Vista的完整性机制
Windows Vista包含一个额外的访问控制安全机制,通过将进程和其他安全对象标签一个完整性级别。面向Internet的程序比其他程序更高风险,因为他们通过未知的源下载不值得信任的内容。相比于其他程序,使用更少的权限或更低的完整性级别来运行这些程序,将会减小更改系统或毁坏用户数据文件的可能性。
保护模式使用Windows Vista的完整性机制在低完整性下运行Internet Explorer进程。完整性机制在Windows Vista中主要的特点如下:
l 安全对象,如文件和注册表键值,或者需要权限级别来写访问的对象,拥有定义了完整性级别的安全描述符。完整性级别在系统访问控制列表(SACL)中定义了新的强制访问控制条目(ACE)。新的强制访问控制条目(ACE)叫做强制描述符。没有强制描述符的对象被指定为默认中完整性级别。
l 拥有完整性级别的进程定义在安全访问令牌中。在保护模式下,Internet Explorer拥有低完整性级别。从开始菜单运行的程序拥有中完整性级别。需要管理员权限运行的进程拥有高完整性级别。
l 低完整性级别的进程不能获得高完整性级别进程的写访问权限,即使用户的SID在自主访问控制列表(DACL)中被赋予了写访问权限。完整性级别检测先于用户访问权限检测。
在Windows Vista中所有文件和注册表键值拥有默认中等完整度级别。低完整性进程,像保护模式中的Internet Explorer,当它们尝试去更改已经存在的文件时,将收到访问拒绝错误。
一些目录拥有低强制完整度级别。一个低完整度级别的进程,例如运行在保护模式的Internet Explorer,只能创建和修改处于低完整度级别目录中的文件。例如,Internet 临时文件目录中有一个叫做Low的目录,这就是低完整性级别目录。在低完整性级别进程中,Windows Vista 完整性机制自动为安全对象分配低强制完整度级别表示符。因此,由保护模式中的Internet Explorer或其他低完整性级别进程所创建的文件和其他对象被自动赋予低完整性级别标示。默认情况下,由低完整性级别进程所创建的子进程也将用低完整性级别来运行。保护模式允许被创建的进程拥有高完整性。更详细的信息,参见在保护模式下创建进程章节。
如下表格展示了被支持的完整性访问级别和被授予的权限
完整性访问级别(IL) | 系统权限 |
高 | 管理员(进程能够安装文件到Program 文件夹和写像HKEY_LOCAL_MACHINE一样的注册表敏感键值) |
中 | 用户(进程能够创建和更改在用户Documents目录下的文件和写用户特定的注册表键值,如HKEY_CURRENT_USER) |
低 | 不信任的(进程仅仅能够写低完整性地方,如Temporary Internet Files/Low文件夹或HKEY_CURRENT_USER/Software/LowRegistry键值) |
理解保护模式
保护模式基于新的完整性机制,限制安全对象的写访问,像拥有高完整性级别进程、文件、和注册表键值。当运行在保护模式中,Internet Explorer是一个低完整性级别的进程;它不能获得文件和用户配置或系统路径注册表的写访问权限。
低完整性进程仅仅能够被写入赋予了强制低完整性标示的目录、文件和注册表键值。因此,运行在保护模式中的Internet Explorer和扩展组件仅仅能够写低完整性级别目录,例如新的低完整性Internet临时目录、历史文件夹、Cookie文件夹、收藏夹和Windows 临时文件夹。更详细的列表,参见常见问题(FAQ)章节。
因此,保护模式仅仅能够发送指定的Windows消息到更高完整性级别的进程。更多信息,请参见开发者在权限受限环境中的最佳方法和指导方针(Developer Best Practices and Guidelines for Applications in a Least Privileged Environment)中的用户界面特权隔离(UIPI)章节。
当然,这些防御措施也限制在更高完整性路径合法的更改。因此,为了减少对现存扩展组件的影响,保护模式提供一个兼容层,显示在如下图表中。
l 兼容层处理许多现存扩展组件的需要。它拦截中等完整度级别资源的写操作,例如在用户属性下的Document文件夹和HKEY_CURRENT_USER注册表。然而,它却不拦截诸如Program Files和 HKEY_LOCAL_MACHINE的写操作。这个兼容层使用Windows兼容片来自动将这些操作转发到如下的低完整性级别路径。
n Documents and Settings/%userprofile%/LocalSettings/TemporaryInternet Files/Virtualized
n HKEY_CURRENT_USER/Software/Microsoft/InternetExplorer/InternetRegistry
l 两个更高权限的调用者进程允许Internet Explorer和扩展组件在用户的允许下以高权限操作。例如,用户权限调用者(IEUser.exe)进程提供一系列的函数让用户保存文件到低完整性路径的外部。 另外,一个管理员权限调用者(IEInstal.exe)进程允许Internet Explorer安装ActiveX组件。更多信息,请参见在保护模式下运行。
配置保护模式
保护模式能够在Internet Explorer的Internet属性对话框中配置。为了配置保护模式,点击安全Tab选项,选中该区域的安全级别,并且改变“开启安全模式”复选框状态。默认,对于Internet、Interanet、和被限制的站点安全模式是开启的。为了确认Internet Explorer是否运行在保护模式下,查看“保护模式:开启”提示是否在Internet Explorer的状态栏中。
保护模式将被配置当Windows Vista转移URLACTION_LOWRIGHTS (0x00002500) URL操作。更多信息,请参见URL 安全区域概述。
在保护模式下运行
这个章节展示在保护模式中扩展组件能够怎样进行常用操作;它解释了怎样找到低完整性对象路径,在低完整性目录外保存文件,提升进程实质脱离保护模式,和调试保护模式访问失败。
寻找低完整性可写路径
在Windows Vista,在创建他们和他们的容器之间,安全对象自动继承较低的完整性级别。这意味着,一个低完整性进程能够获得他们创建的对象的写访问权限。然而,一个低完整性进程不能获得用户属性中中等或高完整性目录或文件的写访问权限。
在写入低完整性位置前,通过调用函数 IEIsProtectedModeProcess 扩展组件能够检测Internet Explorer是否运行在保护模式。当运行在保护模式,扩展组件能够写文件到低于用户属性的文件夹,典型的 %userprofile%/AppData/LocalLow。使用标识 FOLDERID_LocalAppDataLow 调用函数 SHGetKnownFolderPath 来获得展开文件夹名称。
注意 保护模式更改IE的环境变量。结果,当保护模式开启时函数GetTempPath()返回%Temp/Low%。
低完整性进程能够在注册表中创建和写入低完整性子键,例如,HKEY_CURRENT_USER/Software/AppDataLow。然而,运行在保护模式中的扩展组件进程仅仅能够写入指定的低完整性位置,并且需要使用IEGetWriteableHKCU来获得低完整性注册表位置。
安全警告 小心避免混合完整性级别。低完整性对象的存储要与中等或高完整性对象分开。另外,中等和搞完整性程序在没有合适的理由的前提下,要避免打开低完整性对象。
保存文件到用户属性中
为了用户或程序较迟发现这个文件,一些扩展组件需要保存文件到特定的位置。如下步骤展示怎样将文件保存到地完整性之外的位置。
1) 在 %userprofile%/AppData/LocalLow 创建一个临时文件。当文件成功删除后,别忘记删除这个临时文件。
2) 使用用户属性路径调用IEShowSaveFileDialog函数提示用户保存文件到不同的路径。如果用户接受保存文件对话框,IEShowSaveFileDialog返回用户选择的目的文件夹。
3) 使用在第一步中的临时路径调用IESaveFile。
当你这样做之后,保护模式的用户调用者从临时路径拷贝文件到被用户选中的路径。
为了获得中完整性对象的写访问,使用特定的调用者进程,并且提升你的中间进程到中等权限进程。当运行与中等权限进程中,调用者对象能够访问中等完整新对象。更多信息,请参见在保护模式下创建进程。
保护模式下创建进程
通常的,扩展组件应该尽可能的在低完整性进程中运行。这提供了对恶意攻击最好的保护。然而,有时候扩展组件也需要访问中或高完整性对象。
为了完成这个任务,创建一个调用者进程来访问更高完整性对象,并且使用较高的完整性级别运行这个调用者进程。默认的,如下的屏幕截图所示,Internet Explorer将提示用户确定中等完整度进程权限提升。
你能够通过创建提升策略来静默的提升你的调用者进程到中等完整度,这是一系列告诉保护模式怎样为特定调用者提升的操作的注册表键值。提升策略必须有一个全局唯一标示符(UUID)与他们关联。使用 CreateGuid 来为你的策略创建新的 GUID 。接下来,添加键值到指定的位置。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/ElevationPolicy
设置新键值的名称为你的策略所创建的GUID,并且加入如下设置。
1. Policy(DWORD)暗示保护模式怎样运行调用者。如下表格描述了支持的值。
值 | 结果 |
3 | 保护模式使用中等完整性静默运行调用者。 |
2 | 保护模式提示用户允许运行进程。如果用户同意,进程将用中等完整性运行。 |
1 | 保护模式使用低完整性静默运行调用者。 |
0 | 保护模式阻止运行进程。 |
2. 如果你的调用者是一个可执行文件,加入如下设置到你的策略中。
n AppName(REG_SZ)是你的调用可执行调用者文件的文件名。
n AppPath(REG_SZ)是用户选中的可执行调用者文件的安装路径。
3. 如果你的扩展组件运行一个没有在 HKEY_CLASSES_ROOT 注册的 COM 服务,并且动态通过 COM 注册并通过 CoCreateInstance 调用,添加一个叫做 CLSID 的 REG_SZ 值包含 COM 服务的 CLSID,并且加入如下设置到策略中。
n CLSID(REG_SZ)包含你的扩展组件的 CLSID。
为了模拟,如下的策略将静默提升一个虚拟的叫做contoso.exe的调用者到中等完整性级别中。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/ElevationPolicy/{0002df01-0000-0000-c000-000000000046}
AppName="Contoso.exe"
AppPath="C:/%USERPROFILE%/Application Data/Contoso"
Policy=(DWORD) 00000003
注意 出于安全考虑,处于保护模式中的Internet Explorer忽略改变工作路径的函数CreateProcess、CreateProcessAsUser和其他相关函数的参数。如果进程必须接受参数,使用逻辑XOR操作来添加0x80000到为你的程序设置策略的键值中。请意识到这能够创建一个安全风险,结果是灾难性的。
如果微软确定一个程序有弱点,并且为用户带来危险,微软保留任何时候移除这个程序提升策略的权利。
你也能创建能够访问高完整性对象的调用者。更多的描述关于怎样运行搞完整性级别的调用者进程,请参见开发者在权限受限环境中的最佳方法和指导方针(Developer Best Practices and Guidelines for Applications in a Least Privileged Environment)中的管理员用户程序指导方针(Guidelines for Administrative User Applications)。注意,你不需要创建一个提升策略,因为 UAC 将管理这个提升。
如果你存在使用rundll32.exe作为宿主.DLL 库的扩展组件,你能够通过添加库的文件名到指定的键值来使用低完整性静默调用rundll32.exe进程。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/RunDll32Policy
如下例子展示使用rundll32.exe低完整性静默调用虚拟的contoso.dll库的设置。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/RunDll32Policy/contoso.dll
注意 最好的方式是创建一个特定的exe作为宿主DLL,而不是使用rundll32.exe.
在程序中允许拖拽功能
默认情况下,在允许网页内容拷贝到更高完整性的进程中时,保护模式提示用户允许操作。
你能够创建拖拽策略来注册你的程序来避免这个提示,并且静默接受网页拖拽功能。拖拽策略必须有全局唯一标示符(GUID)与之关联。使用 CreateGuid 来为你的策略创建一个新的 GUID。接下来,将键值加入如下位置。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/DragDrop
设置新键值的名称为你的策略所创建的GUID,并且加入如下设置。
1. Policy(DWORD)应该被设置为 3,这表明保护模式允许网页内容静默的拷贝到你的程序进程中。
2. 如果你的程序是一个可执行文件,添加如下的设置到你的策略中。
n AppName(REG_SZ)是你的调用可执行调用者文件的文件名。
n AppPath(REG_SZ)是用户选中的可执行调用者文件的安装路径。
3. 如果你的扩展组件运行一个没有在 HKEY_CLASSES_ROOT 注册的 COM 服务,并且动态通过 COM 注册并通过 CoCreateInstance 调用,添加一个叫做 CLSID 的 REG_SZ 值包含 COM 服务的 CLSID,并且加入如下设置到策略中。
n CLSID(REG_SZ)包含你的扩展组件的 CLSID。
如下例子展示了所有的网页内容将被静默拷贝到虚拟的contoso.exe程序中的设置。
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Explorer/Low Rights/DragDrop
AppName="contose.exe"
AppPath="C:/%USERPROFILE%/Application Data/Contoso"
Policy=(DWORD) 00000003
允许程序接收Windows消息
如上所述,UIPI 层将 Window 消息从低发到更高完整性进程。如果你的扩展组件运行在保护模式,并且需要使用Window 消息与一个提升权限的程序交互,你可以调用 ChangeWindowMessageFilter() 来使程序到允许特定消息。
注意 如果你需要与保护模式交互,最好的方式是在低完整性级别中运行你的程序。否则仅仅使用进程间通信(IPC)安全的方式,例如远过程调用(RPC),来在保护模式和更高完整性级别进程中交互。
运行和导向保护模式进程
如果你的程序使用 CreateProcess 来运行IE,而在 Vista 中需要调用 IELaunchURL。这将确认你的程序获得正确的返回值,和 IE 运行在保护模式中对于保护模式奏效的站点来说。如果你在运行一个 URL 之前需要确定一个指定的 URL 是否运行在低(保护模式)或中完整性 IE 进程中,调用 IEIsProtectedModeURL。注意,使用管理员权限运行的高完整性 IE 进程中的保护模式将被关闭。如果你想运行在你的高完整性进程中运行保护模式,你可以首先创建一个中等完整性级别的进程,这个进程将调用你的高完整性进程和 IE。
如果你的程序使用 CoCreateInstance 来运行 Internet Explorer,并且当 IE 运行后需要继续控制转向,你可以使用 IWebBrowser2 来编程的转向 Internet Explorer。如果你的程序与 IE 进程有同样的完整性级别,当 IE 运行时你仅仅能够继续控制转向。当你的程序转向不同完整性 IE 进程,你将不能使用其他的转向操作。你应该让 IE 浏览框架可见。
如下例子展示怎样使用 C++ 来完成这一功能。
hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,(LPVOID*)&pIWebBrowser2);
hr = pIWebBrowser2->Navigate(bstrUrl, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
hr = pIWebBrowser2->put_Visible(VARIANT_TRUE);
如下例子展示 JScript 版本。
var ie = new ActiveXObject("InternetExplorer.Application");
ie.Navigate("http://www.msn.com");
ie.visible = true;
使用应用程序兼容性工具包调试程序
保护模式使用在 Windows Xp Service Pack 2 中引入的微软程序兼容工具箱来运行。
当保护模式中的 Internet Explorer 或者它的扩展组件尝试写安全对象,应用程序兼容日志包含描述操作和结果。如下的列表解释在日志表单中的各个值。
l ModuleName 是运行这个进程并且访问安全对象的文件名。
l VirtualizationAction 指示写操作和如下的结果。
n InterceptedWrite 指示这个操作被兼容层拦截了。
n WriteIgnored 指示这个操作被保护模式忽略,由于调用进程是较高的调用者。
n CreateVirtualCopy 指示兼容层做了一个虚拟位置对象的拷贝。
n CreateNew 指示兼容层在虚拟位置创建了一个新的对象。
l ObjectType 是文件或注册表。
l APIName 说明尝试做这个操作的函数,例如,CreateFile 或 RegOpenKey。
l RegObjectPath 是操作尝试改变的对象的位置。如果对象没有路径,则这是空的。
l 当写操作成功,NewObjectPath 指示被这个操作更改的对象。
l APIResult 指示这个 API 函数尝试写操作的结果。
l LastError 是 API 函数收到的最终错误。
当尝试着确定为什么没有按照期望工作时,这个消息是无法被估计的。
开发安全扩展组件
为保护模式开发 Internet Explorer 安全扩展组件跟为开发 Windows Vista 安全程序没有太大不同。另外这个知道方针在开发者在权限受限环境中的最佳方法和指导方针(Developer Best Practices and Guidelines for Applications in a Least Privileged Environment) 和 ActiveX 安全:改善和最好的实践(ActiveX Security: Improvements and Best Practices),扩展组件开发人员需要理解怎样在扩展组件中安装软件、运行低完整性级别的进程、降低资源完整性级别、和确定进程完整性级别。这个章节暂时怎样执行这些操作。
从扩展组件中安装软件
当运行在保护模式中,ActiveX 控件和其他扩展组件不能安装软件。如果你的扩展组件需要更改高完整性对象,如Program Files文件夹或在HKEY_LOCAL_MACHINE下的注册表键值,你应该创建独立的运行在管理员权限下的安装程序。
为了在管理员权限下运行你的程序,你能够包含一个程序manifest,详细描述描述在开发者在权限受限环境中的最佳方法和指导方针(Developer Best Practices and Guidelines for Applications in a Least Privileged Environment)。安装完成之后,你的扩展组件运行在保护模式中可以创建中完整级别的程序,而不是高完整性级别的。这将可以保护用户,因为运行用户权限下而不是管理员权限。
如果你添加了提升策略,你必须关闭和重启所有Internet Explorer 进程。IEUser.exe 不会自动检测对提升策略的更改。
运行低完整性级别的进程
默认情况下,子进程继承父进程的完整性级别。调用 CreateProcessAsUser 来在保护模式下运行低完整性级别的进程。为了在一个中完整性继承中开启一个低完整性级别的进程,你必须使用低完整性明显的开启一个新的进程。这需要三个步骤。
1、复制这个中等完整性级别进程的句柄。
2、使用 SetTokenInformation 将进程句柄来降低至低完整性。
3、使用 CreateProcessAsUser 和这个低完整性句柄来创建新的进程。
如下示例模拟了这个过程。
#include <sddl.h>
void CreateLowProcess()
{
BOOL bRet;
HANDLE hToken;
HANDLE hNewToken;
// Notepad is used as an example
WCHAR wszProcessName[MAX_PATH] = L"C://Windows//System32//Notepad.exe";
// Low integrity SID
WCHAR wszIntegritySid[20] = L"S-1-16-4096";
PSID pIntegritySid = NULL;
TOKEN_MANDATORY_LABEL TIL = {0};
PROCESS_INFORMATION ProcInfo = {0};
STARTUPINFO StartupInfo = {0};
ULONG ExitCode = 0;
if (OpenProcessToken(GetCurrentProcess(),MAXIMUM_ALLOWED, &hToken))
{
if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hNewToken))
{
if (ConvertStringSidToSid(wszIntegritySid, &pIntegritySid))
{
TIL.Label.Attributes = SE_GROUP_INTEGRITY;
TIL.Label.Sid = pIntegritySid;
// Set the process integrity level
if (SetTokenInformation(hNewToken, TokenIntegrityLevel, &TIL,
sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
{
// Create the new process at Low integrity
bRet = CreateProcessAsUser(hNewToken, NULL,
wszProcessName, NULL, NULL, FALSE,
0, NULL, NULL, &StartupInfo, &ProcInfo);
}
LocalFree(pIntegritySid);
}
CloseHandle(hNewToken);
}
CloseHandle(hToken);
}
}
注意 你也可以通过设置注册表键值在保护模式下运行低完整性级别的进程。更多信息,请参见创建进程(Starting Processes from Protected Mode)
降低资源的完整性
通常情况下,更高级别的进程将输入或者资源与更低完整性进程共享,不是一个好且安全的方式。这儿的风险是低完整性进程可以尝试恶意的行为。然而,如果要这样设计,有几个步骤。
注意 将输入或者资源与更低完整性进程共享的程序需要假设由更低完整性进程提供的数据时不可信的,并且需要采取认证措施。例如,保护模式显示从Internet Explorer 用户调用者进程中的另存为对话框;这允许用户确认使用一个比保护模式更高权限的进程来保存文件。
由于低完整性程序仅仅能够写入低完整性资源,你需要降低共享资源的完整性级别。
1、创建一个定义了低强制性标识符的 SDDL 安全描述符。
2、将 SDDL 字符串转换为安全描述符。
3、将低完整性属性赋给安全描述符。
4、将安全描述符赋给共享资源。
如下实例演示这个过程。
#include <sddl.h>
#include <AccCtrl.h>
#include <Aclapi.h>
void SetLowLabelToFile()
{
// The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
#define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
DWORD dwErr = ERROR_SUCCESS;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pSacl = NULL; // not allocated
BOOL fSaclPresent = FALSE;
BOOL fSaclDefaulted = FALSE;
LPCWSTR pwszFileName = L"Sample.txt";
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL))
{
if (GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted))
{
// Note that psidOwner, psidGroup, and pDacl are
// all NULL and set the new LABEL_SECURITY_INFORMATION
dwErr = SetNamedSecurityInfoW((LPWSTR) pwszFileName,
SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION,
NULL, NULL, NULL, pSacl);
}
LocalFree(pSD);
}
}
程序进程仅仅能够设置那些相等或更低的进程的安全对象的完整性级别。
Windows Vista 允许拥有者更改安全对象的完整性访问级别。这些更改将不会更新审计日志。
拥有 READ_CONTROL 权限的进程可以使用 GetNamedSecurity 来确认安装对象的完整性级别。
注意 低完整性文件将被保护模式层重定向,除了常见问题中的已知位置
确定进程的完整性级别
在不同进程中运行的扩展组件或许想判断一个进程是运行在低或中等完整级别,并且根据状况更改表现形式。如下步骤展示怎样确定一个进程的完整性级别。
1、打开当前进程的句柄。
2、获得令牌(Token)的完整性级别。
3、将这个完整性级别与系统预定义的完整性级别进行比较。
如下的例子展示如何做到这一点
void ShowProcessIntegrityLevel()
{
HANDLE hToken;
HANDLE hProcess;
DWORD dwLengthNeeded;
DWORD dwError = ERROR_SUCCESS;
PTOKEN_MANDATORY_LABEL pTIL = NULL;
LPWSTR pStringSid;
DWORD dwIntegrityLevel;
hProcess = GetCurrentProcess();
if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken))
{
// Get the Integrity level.
if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwLengthNeeded))
{
dwError = GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER)
{
pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded);
if (pTIL != NULL)
{
if (GetTokenInformation(hToken, TokenIntegrityLevel, TIL, dwLengthNeeded, &dwLengthNeeded))
{
dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
(DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1));
if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID)
{
// Low Integrity
wprintf(L"Low Process");
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
{
// Medium Integrity
wprintf(L"Medium Process");
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
{
// High Integrity
wprintf(L"High Integrity Process");
}
}
LocalFree(pTIL);
}
}
}
CloseHandle(hToken);
}
}
常见问题
Q:UAC 文件和注册表的虚拟化适用于保护模式吗?
A:不,UAC 虚拟化不适用于保护模式,因此,向系统敏感区域写数据将不会被重定向。对于系统区域,保护模式也不会写重定向或者虚拟化。当他们向系统敏感区域写入数据时,运行在保护模式下的扩展组件将获得拒绝访问错误。
Q:运行在Internet Explorer保护模式中的扩展组件可以写 USER PROFILE 或者 HKEY_CURRENT_USER 注册表这些特别的位置吗?
A:可以,Internet Explorer 被限制在如下的 USER PROFILE 目录。
Documents and Settings/%USER PROFILE%...
.../Local Settings/Temporary Internet Files
.../Local Settings/Temp
.../Local Settings/History .../%USER PROFILE%/Favorites .../%USER PROFILE%/Cookies
扩展组件可以写如下位置。
Documents and Settings/%USER PROFILE%...
.../Local Settings/Temporary Internet Files/Low
.../Local Settings/Temp/Low
.../Local Settings/History/Low .../%USER PROFILE%/Favorites/Low .../%USER PROFILE%/Cookies/Low %USER PROFILE%/AppData/LocalLow
注意,扩展组件不能写入如 Program Files 目录或者 HKEY_CLASSES_ROOT、HKEY_LOCAL_MACHINE 子树。
而且,扩展组件使用API函数去尝试获得写访问安全对象将获得拒绝访问错误。
actxprxy.dll | ieui.dll | mswsock.dll | sensapi.dll |
Advapi32.dll | iexplore.exe | NAPINSP.dll | Shdocvw.dll |
bcrypt.dll | IMM32.dll | ncrypt.dll | SHLWAPI.dll |
BrowseUI.dll | Inetcpl.cpl | NETAPI32.dll | SWEEPRX.dll |
clbcatq.dll | IPHLPAPI.dll | NLAapi.dll | TAPI32.dll |
Comctl32.dll | jscript.dll | NSI.dll | URLMon.dll |
Corpol.dll | jsproxy.dll | Ntdll.dll | USERENV.dll |
CREDSSP.dll | Kernel32.dll | ntmarta.dll | USP10.dll |
Crypt32.dll | LPK.dll | offprof.dll | uxtheme.dll |
Cryptnet.dll | mf.dll | OLEACC.dll | vbscript.dll |
dciman32.dll | mlang.dll | pnrpnsp.dll | Wininet.dll |
ddraw.dll | MPR.dll | PSAPI.dll | WINNSI.dll |
dhcpcsvc.dll | MSASN1.dll | rasadhlp.dll | winrnr.dll |
dhcpcsvc6.dll | mscms.dll | rasapi32.dll | WINSPOOL.DRV |
DNSAPI.dll | MSCTF.dll | rasdlg.dll | winsta.dll |
dssenh.dll | msfeeds.dll | rasman.dll | Wintrust.dll |
dwmapi.dll | msfeedsbs.dll | rpcrt4.dll | ws2_32.dll |
Dxtmsft.dll | Mshtml.dll | rsaenh.dll | wship6.dll |
Dxtrans.dll | MSHTMLED.dll | rtutils.dll | wshtcpip.dll |
gpapi.dll | msimg32.dll | samlib.dll | wsock32.dll |
Ieframe.dll | msimtf.dll | Schannel.dll | wtsapi32.dll |
IEPeers.dll | msls31.dll | secur32.dll |
|
iertutil.dll | Mstime.dll | Secure32.dll |
|
Q:我怎样才能从一个权限提升的 Internet Explorer 进程中停止工具栏?
A:许多工具栏安装程序关闭所有正在运行的 Internet Explorer 实例,然后在运行一个新的,因此新的工具栏就是可见的了。这个问题是,新的Internet Explorer 从一个被提升的进程中调用的。工具栏可以通过关闭Internet Explorer然后重新运行来避免这个问题。更多信息,请参见运行低完整性级别的进程(Starting Low Integrity Processes)。