Win8开始,Windows引入了新的进程隔离机制AppContainer,MetroAPP以及开启EPM的IE Tab进程都运行在AppContainer隔离环境,在最新的Win10Pre(9926)上,仍然如此。腾讯反病毒实验室对AppContainer的工作机制做一深入解读。
Vista 以前的系统,如 XP ,用安全描述符(简称 SD ,下同)里的 DACL ( discretionaryaccess control list )来控制用户和用户组的访问权限。
Vista 以后,增加了 IntegrityMechanism ,在 SD 的 SACL(system access control list) 里增加一个 mandatory label 的 ACE ,扩展了 Windows 安全体系。默认的控制策略是 No-Write-Up ,允许较低完整性级别的进程读访问较高完整性级别的对象;禁止较低完整性级别的进程写访问较高完整性级别的对象。
Win8 引入了 AppContainer 隔离机制,提供了更细粒度的权限控制,能够阻止对未授权对象的读写访问。
以 Win10PreX64(9926) 开启 EPM 的 IE Tab 进程为例,看看有哪些变化。
从 ProcessExplorer 里可以看到, IE Tab 进程的完整性级别不再是 Low ,而是变成了 AppContainer :
图 1
在进程属性的 Security 标签可以看到,增加了标志为 AppContainer 以及 Capability 的 SID :
图 2
一个 AppContainer 进程可以访问的对象,在 SD 的 DACL 里增加了额外的 ACE 。以 IE Tab 进程的进程对象为例:
图 3
这里我们不讨论 MetroAPP ,主要看看 DesktopAPP 如何使用 AppContainer 隔离机制。
仍然以 Win10PreX64(9926) 开启 EPM 的 IE Tab 进程为例:在 IE 选项里开启 EPM, 下断点 nt!NtCreateLowBoxToken ,然后新建 IE Tab ,命中断点,截取最上面的几层调用栈:
图 4
可见,通过 CreateProcess 这个 API 就可以创建出 AppContainer 进程。
看看 CreateAppContainerProcessStrW 的逻辑片段,把 PackageSIDString( 图 2 里标记为 AppContainer 的 SID) 和 CapabilitySID( 图 2 里标记为 Capability 的 SID) string 转为 SID 后,传给了 CreateAppContainerProcessW :
图 5
看看 CreateAppContainerProcessW 的逻辑片段,把传入的 CapabilitySIDs 和 PackageSID 加入到 ProcThreadAttributes ,然后通过 STARTUPINFOEX 结构把 ProcThreadAttributes 传给了 CreateProcessW 。
图 6
图 7
图 8
搞清楚 IE Tab 进程的创建逻辑,我们就可以创建自己的 AppContainer 进程了。
直接复用 IE 的 PackageSID 和 CapabilitySIDs 来创建 AppContainer 进程。如果需要定义自己的 PackageSID ,可以参考 MSDN 上的 CreateAppContainerProfile 等 API ,这里就不讨论了。
成功的创建出了具有 AppContainer 隔离机制的记事本进程。 32 位和 64 位进程都可以。可以自由组合 Capability ,这里我选择了 IE Tab6 个 Capability 里的 3 个。
图 9
图 10
如果程序在设计时没有考虑使用 AppContainer 隔离机制,依赖没有授权给 AppContainer 的系统资源,比如系统根目录,用户根目录等,使用 AppContainer 隔离机制启动程序会失败。
为描述方便, AppContainer 进程的 AccessToken 我们简称为 LowBoxToken (下同)。
下面是一个 LowBoxToken 的部分信息,可以看到 TokenFlags 的掩码位 0×4000 是置位的,这表示该 Token 是一个 LowBoxToken 。我们还可以看到 PackageSid 、 Capabilities 等信息(图 2 里标志为 AppContainer 和 Capability 的 SID )。
图 11
DACL的遍历是在SepNormalAccessCheck/SepMaximumAccessCheck里进行的。这里我们以SepNormalAccessCheck为例,来看一看如何处理AppContianer相关的ACE。
一般来说,在遍历DACL时,如果满足以下3个条件中的任意一个,检查停止。
1.有一个 access-denied ACE 明确拒绝了请求访问权限中的任意一个;
2.有一个或者多个 access-allowed ACEs 明确给予了所有的请求访问权限;
3.已经检查完了所有的 ACE ,但是仍然至少有一个请求访问权限没有被明确给予,这种情况下,访问被拒绝。
从Windows Server 2003开始,DACL里ACE的顺序为:
Explicit ACE:AccessDenied Explicit ACE:AccessAllowed Inherited ACE:Access Denied Inherited ACE:Access Allowed
这个遍历规则和顺序保证了明确拒绝优先于明确允许;明确指定的访问控制优先于继承的访问控制。
以下的内容基于Win10PreX86(9926)。
在遍历类型为ACCESS_ALLOWED_ACE_TYPE的ACE时,如果ACE的SID前缀为SePackagePrefixSid(S-1-15-2)或者SeCapabilityPrefixSid(S-1-15-3),则跳转到处理AppContainer访问权限控制的逻辑:
图 12
如果ACE的SID前缀为SePackagePrefixSid(S-1-15-2),会先看这个SID是否为ALLAPPLICATION PACKAGES,这是一个Well known SID
图 13
如果是这个SID,认为匹配成功,不需要再精确比较SID了;否则和Token的PackageSID做精确匹配:
图 14
如果ACE的SID前缀为SeCapabilityPrefixSid(S-1-15-3),会尝试匹配Token的Capabilities:
图 15
PackageSID或者Capabilities匹配成功后,会通过a13记录获取到的权限以及还剩下未获取到的权限。a13是上层调用传进来的结构指针,上一层函数会根据这个结构的值,判断AppContainer进程是否获取到了请求的访问权限 。
看看上一层函数 SepAccessCheck 的逻辑片段, var_AccessLowbox 就是图 14/15 里的 a13 。如果 PackageSID 或者 CapabilitieSID 给予的权限不能完全覆盖用户请求的权限( var_Remaining != 0 ),则访问失败:
图 16
另外,对于 No DACL 的情况,也有额外的处理逻辑。 AppContainer 进程访问 No DACL 的对象时,是无法获得访问权限的:
图 17
所以在 Win8 及以上系统中,我们如果想要创建一个所有进程(包括开启 EPM 的 IE Tab )都能访问的对象,对于该对象的 SD ,除了在 SACL 里指定为低完整性级别外,还要考虑在 DACL 中显示的给予 everyone 以及 ALL APPLICATIONS PACKAGE 对应的访问权限控制。
在遍历类型为ACCESS_DENIED_ACE_TYPE的ACE时,处理逻辑里并没有区分ACE的SID是否为PackageSID或者CapabilitiesSID。而是简单使用SepSidInTokenSidHash函数在Token的SidHash/RestrictedSidHash里匹配。如果是PackageSID或者CapabilitiesSID,匹配会失败,因此该ACE描述的拒绝访问权限控制不会生效:
图 18
做一个实验验证上面的结论,首先我们用 AppContainer 隔离机制启动一个记事本,复用 IE EPM 的 PackageSID 以及部分 Capabilities :
图 19
把C:/Users/{当前用户}/AppData/Local/Packages/windows_ie_ac_001/AC/Temp/test/1.txt设置为下面的权限控制:
图 20
图 21
ACE[0]Mask为0x001F01FF,包含要请求的权限0×00100080
虽然ACE[0]明确的拒绝了
S-1-15-2-1430448594-2639229838-973813799-439329657-1197984847-4069167804-1277922394( 图 19 里标志为 AppContainer 的 SID) ,记事本仍然能成功打开 1.txt(ACE[1] 明确给予了 ALL APPLICATION PACKAGES 0x001F01FF 的访问权限 ) 。
AppContainer 提供了更细粒度的隔离机制,不仅能用于 MetroAPP 和 IE EPM ,当应用程序需要访问未知第三方内容时,也可以考虑使用 AppContainer 隔离机制,把对系统的潜在影响降到最低。
[作者/腾讯电脑管家(企业账号),转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)]