转载

深度解析Windows最新进程隔离机制AppContainer

Win8开始,Windows引入了新的进程隔离机制AppContainer,MetroAPP以及开启EPM的IE Tab进程都运行在AppContainer隔离环境,在最新的Win10Pre(9926)上,仍然如此。腾讯反病毒实验室对AppContainer的工作机制做一深入解读。

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

深度解析Windows最新进程隔离机制AppContainer

1

在进程属性的 Security 标签可以看到,增加了标志为 AppContainer 以及 Capability SID

深度解析Windows最新进程隔离机制AppContainer

2

一个 AppContainer 进程可以访问的对象,在 SD DACL 里增加了额外的 ACE 。以 IE Tab 进程的进程对象为例:

深度解析Windows最新进程隔离机制AppContainer

3

如何使用 AppContainer 隔离机制

这里我们不讨论 MetroAPP ,主要看看 DesktopAPP 如何使用 AppContainer 隔离机制。

仍然以 Win10PreX64(9926) 开启 EPM IE Tab 进程为例:在 IE 选项里开启 EPM, 下断点 nt!NtCreateLowBoxToken ,然后新建 IE Tab ,命中断点,截取最上面的几层调用栈:

深度解析Windows最新进程隔离机制AppContainer

4

可见,通过 CreateProcess 这个 API 就可以创建出 AppContainer 进程。

看看 CreateAppContainerProcessStrW 的逻辑片段,把 PackageSIDString( 2 里标记为 AppContainer SID) CapabilitySID( 2 里标记为 Capability SID) string 转为 SID 后,传给了 CreateAppContainerProcessW

深度解析Windows最新进程隔离机制AppContainer

5

看看 CreateAppContainerProcessW 的逻辑片段,把传入的 CapabilitySIDs PackageSID 加入到 ProcThreadAttributes ,然后通过 STARTUPINFOEX 结构把 ProcThreadAttributes 传给了 CreateProcessW

深度解析Windows最新进程隔离机制AppContainer

6

深度解析Windows最新进程隔离机制AppContainer

7

深度解析Windows最新进程隔离机制AppContainer

8

搞清楚 IE Tab 进程的创建逻辑,我们就可以创建自己的 AppContainer 进程了。

直接复用 IE PackageSID CapabilitySIDs 来创建 AppContainer 进程。如果需要定义自己的 PackageSID ,可以参考 MSDN 上的 CreateAppContainerProfile API ,这里就不讨论了。

成功的创建出了具有 AppContainer 隔离机制的记事本进程。 32 位和 64 位进程都可以。可以自由组合 Capability ,这里我选择了 IE Tab6 Capability 里的 3 个。

深度解析Windows最新进程隔离机制AppContainer

9

深度解析Windows最新进程隔离机制AppContainer

10

如果程序在设计时没有考虑使用 AppContainer 隔离机制,依赖没有授权给 AppContainer 的系统资源,比如系统根目录,用户根目录等,使用 AppContainer 隔离机制启动程序会失败。

AppContainer 的访问权限控制

为描述方便, AppContainer 进程的 AccessToken 我们简称为 LowBoxToken (下同)。

下面是一个 LowBoxToken 的部分信息,可以看到 TokenFlags 的掩码位 0×4000 是置位的,这表示该 Token 是一个 LowBoxToken 。我们还可以看到 PackageSid Capabilities 等信息(图 2 里标志为 AppContainer Capability SID )。

深度解析Windows最新进程隔离机制AppContainer

11

DACL

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

在遍历类型为ACCESS_ALLOWED_ACE_TYPE的ACE时,如果ACE的SID前缀为SePackagePrefixSid(S-1-15-2)或者SeCapabilityPrefixSid(S-1-15-3),则跳转到处理AppContainer访问权限控制的逻辑:

深度解析Windows最新进程隔离机制AppContainer

12

如果ACE的SID前缀为SePackagePrefixSid(S-1-15-2),会先看这个SID是否为ALLAPPLICATION PACKAGES,这是一个Well known SID

深度解析Windows最新进程隔离机制AppContainer

13

如果是这个SID,认为匹配成功,不需要再精确比较SID了;否则和Token的PackageSID做精确匹配:

深度解析Windows最新进程隔离机制AppContainer

14

如果ACE的SID前缀为SeCapabilityPrefixSid(S-1-15-3),会尝试匹配Token的Capabilities:

深度解析Windows最新进程隔离机制AppContainer

15

PackageSID或者Capabilities匹配成功后,会通过a13记录获取到的权限以及还剩下未获取到的权限。a13是上层调用传进来的结构指针,上一层函数会根据这个结构的值,判断AppContainer进程是否获取到了请求的访问权限

看看上一层函数 SepAccessCheck 的逻辑片段, var_AccessLowbox 就是图 14/15 里的 a13 。如果 PackageSID 或者 CapabilitieSID 给予的权限不能完全覆盖用户请求的权限( var_Remaining != 0 ),则访问失败:

深度解析Windows最新进程隔离机制AppContainer

16

另外,对于 No DACL 的情况,也有额外的处理逻辑。 AppContainer 进程访问 No DACL 的对象时,是无法获得访问权限的:

深度解析Windows最新进程隔离机制AppContainer

17

所以在 Win8 及以上系统中,我们如果想要创建一个所有进程(包括开启 EPM IE Tab )都能访问的对象,对于该对象的 SD ,除了在 SACL 里指定为低完整性级别外,还要考虑在 DACL 中显示的给予 everyone 以及 ALL APPLICATIONS PACKAGE 对应的访问权限控制。

ACCESS_DENIED_ACE_TYPE

在遍历类型为ACCESS_DENIED_ACE_TYPE的ACE时,处理逻辑里并没有区分ACE的SID是否为PackageSID或者CapabilitiesSID。而是简单使用SepSidInTokenSidHash函数在Token的SidHash/RestrictedSidHash里匹配。如果是PackageSID或者CapabilitiesSID,匹配会失败,因此该ACE描述的拒绝访问权限控制不会生效:

深度解析Windows最新进程隔离机制AppContainer

18

做一个实验验证上面的结论,首先我们用 AppContainer 隔离机制启动一个记事本,复用 IE EPM PackageSID 以及部分 Capabilities

深度解析Windows最新进程隔离机制AppContainer

19

把C:/Users/{当前用户}/AppData/Local/Packages/windows_ie_ac_001/AC/Temp/test/1.txt设置为下面的权限控制:

深度解析Windows最新进程隔离机制AppContainer

20

深度解析Windows最新进程隔离机制AppContainer

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)]

正文到此结束
Loading...