騰訊反病毒實驗室:深度解析AppContainer工作機制

wyzsk發表於2020-08-19
作者: 騰訊電腦管家 · 2015/03/05 15:54

0x00 前言


Win8開始,Windows引入了新的程式隔離機制AppContainer,MetroAPP以及開啟EPM的IE Tab程式都執行在AppContainer隔離環境,在最新的Win10Pre(9926)上,仍然如此。騰訊反病毒實驗室對AppContainer的工作機制做一深入解讀。

0x01 AppContainer帶來的變化


Vista以前的系統,如XP,用安全描述符(簡稱SD,下同)裡的DACL(discretionary access control list)來控制使用者和使用者組的訪問許可權。

Vista以後,增加了Integrity Mechanism,在SD的SACL(system access control list)裡增加一個mandatory label的ACE,擴充套件了Windows安全體系。預設的控制策略是No-Write-Up,允許較低完整性級別的程式讀訪問較高完整性級別的物件;禁止較低完整性級別的程式寫訪問較高完整性級別的物件。

Win8引入了AppContainer隔離機制,提供了更細粒度的許可權控制,能夠阻止對未授權物件的讀寫訪問。

以Win10PreX64(9926)開啟EPM的IE Tab程式為例,看看有哪些變化。

從Process Explorer裡可以看到,IE Tab程式的完整性級別不再是Low,而是變成了AppContainer:

enter image description here 圖1

在程式屬性的Security標籤可以看到,增加了標誌為AppContainer以及Capability的SID:

enter image description here 圖2

一個AppContainer程式可以訪問的物件,在SD的DACL裡增加了額外的ACE。以IE Tab程式的程式物件為例:

enter image description here 圖3

0x02 如何使用AppContainer隔離機制


這裡我們不討論MetroAPP,主要看看DesktopAPP如何使用AppContainer隔離機制。

仍然以Win10PreX64(9926)開啟EPM的IE Tab程式為例:在IE選項裡開啟EPM,下斷點nt!NtCreateLowBoxToken,然後新建IE Tab,命中斷點,擷取最上面的幾層呼叫棧:

enter image description here 圖4

可見,透過CreateProcess這個API就可以建立出AppContainer程式。

看看CreateAppContainerProcessStrW的邏輯片段,把PackageSID String(圖2裡標記為AppContainer的SID)和CapabilitySID(圖2裡標記為Capability的SID) string轉為SID後,傳給了CreateAppContainerProcessW:

enter image description here 圖5

看看CreateAppContainerProcessW的邏輯片段,把傳入的CapabilitySIDs和PackageSID加入到ProcThreadAttributes,然後透過STARTUPINFOEX結構把ProcThreadAttributes傳給了CreateProcessW。

enter image description here 圖6

enter image description here 圖7

enter image description here 圖8

搞清楚IE Tab程式的建立邏輯,我們就可以建立自己的AppContainer程式了。

直接複用IE的PackageSID和CapabilitySIDs來建立AppContainer程式。如果需要定義自己的PackageSID,可以參考MSDN上的CreateAppContainerProfile等API,這裡就不討論了。

成功的建立出了具有AppContainer隔離機制的記事本程式。32位和64位程式都可以。可以自由組合Capability,這裡我選擇了IE Tab 6個Capability裡的3個。

enter image description here

enter image description here

如果程式在設計時沒有考慮使用AppContainer隔離機制,依賴沒有授權給AppContainer的系統資源,比如系統根目錄,使用者根目錄等,使用AppContainer隔離機制啟動程式會失敗。

0x03 AppContainer的訪問許可權控制


為描述方便,AppContainer程式的AccessToken我們簡稱為LowBoxToken(下同)。

下面是一個LowBoxToken的部分資訊,可以看到TokenFlags的掩碼位0x4000是置位的,這表示該Token是一個LowBoxToken。我們還可以看到PackageSid、Capabilities等資訊(圖2裡標誌為AppContainer和Capability的SID)。

enter image description here 圖11

0x04 DACL


DACL的遍歷是在SepNormalAccessCheck/SepMaximumAccessCheck裡進行的。這裡我們以SepNormalAccessCheck為例,來看一看如何處理AppContianer相關的ACE。

一般來說,在遍歷DACL時,如果滿足以下3個條件中的任意一個,檢查停止。

有一個access-denied ACE明確拒絕了請求訪問許可權中的任意一個;

有一個或者多個access-allowed ACEs明確給予了所有的請求訪問許可權;

已經檢查完了所有的ACE,但是仍然至少有一個請求訪問許可權沒有被明確給予,這種情況下,訪問被拒絕。

從Windows Server 2003開始,DACL裡ACE的順序為:

Explicit    ACE:Access Denied
Explicit    ACE:Access Allowed
Inherited ACE:Access Denied
Inherited ACE:Access Allowed

這個遍歷規則和順序保證了明確拒絕優先於明確允許;明確指定的訪問控制優先於繼承的訪問控制。

以下的內容基於Win10PreX86( 9926)。

0x05 ACCESS_ALLOWED_ACE_TYPE


在遍歷型別為ACCESS_ALLOWED_ACE_TYPE的ACE時,如果ACE的SID字首為SePackagePrefixSid(S-1-15-2)或者SeCapabilityPrefixSid(S-1-15-3),則跳轉到處理AppContainer訪問許可權控制的邏輯:

enter image description here 圖12

如果ACE的SID字首為SePackagePrefixSid(S-1-15-2),會先看這個SID是否為ALL APPLICATION PACKAGES,這是一個Well known SID

enter image description here 圖13

如果是這個SID,認為匹配成功,不需要再精確比較SID了;否則和Token的PackageSID做精確匹配:

enter image description here 圖14

如果ACE的SID字首為SeCapabilityPrefixSid(S-1-15-3),會嘗試匹配Token的Capabilities:

enter image description here 圖15

PackageSID或者Capabilities匹配成功後,會透過a13記錄獲取到的許可權以及還剩下未獲取到的許可權。a13是上層呼叫傳進來的結構指標,上一層函式會根據這個結構的值,判斷AppContainer程式是否獲取到了請求的訪問許可權。

看看上一層函式SepAccessCheck的邏輯片段,var_AccessLowbox就是圖14/15裡的a13。如果PackageSID或者CapabilitieSID給予的許可權不能完全覆蓋使用者請求的許可權(var_Remaining != 0),則訪問失敗:

enter image description here 圖16

另外,對於No DACL的情況,也有額外的處理邏輯。AppContainer程式訪問No DACL的物件時,是無法獲得訪問許可權的:

enter image description here 圖17

所以在Win8及以上系統中,我們如果想要建立一個所有程式(包括開啟EPM的IE Tab )都能訪問的物件,對於該物件的SD,除了在SACL裡指定為低完整性級別外,還要考慮在DACL中顯示的給予everyone以及ALL APPLICATIONS PACKAGE對應的訪問許可權控制。

0x06 ACCESS_DENIED_ACE_TYPE


在遍歷型別為ACCESS_DENIED_ACE_TYPE的ACE時,處理邏輯裡並沒有區分ACE的SID是否為PackageSID或者CapabilitiesSID。而是簡單使用SepSidInTokenSidHash函式在Token的SidHash/RestrictedSidHash裡匹配。如果是PackageSID或者CapabilitiesSID,匹配會失敗,因此該ACE描述的拒絕訪問許可權控制不會生效:

enter image description here 圖18

做一個實驗驗證上面的結論,首先我們用AppContainer隔離機制啟動一個記事本,複用IE EPM的PackageSID以及部分Capabilities:

enter image description here 圖19

把C:\Users{當前使用者}\AppData\Local\Packages\windows_ie_ac_001\AC\Temp\test\1.txt設定為下面的許可權控制:

enter image description here 圖20

enter image description here 圖21

ACE[0]Mask為0x001F01FF,包含要請求的許可權0x00100080 雖然ACE[0]明確的拒絕了 S-1-15-2-1430448594-2639229838-973813799-439329657-1197984847-4069167804-1277922394 (圖19裡標誌為AppContainer的SID),記事本仍然能成功開啟1.txt(ACE1明確給予了ALL APPLICATION PACKAGES 0x001F01FF的訪問許可權)。

0x07 結束語


AppContainer提供了更細粒度的隔離機制,不僅能用於MetroAPP和 IE EPM,當應用程式需要訪問未知第三方內容時,也可以考慮使用AppContainer隔離機制,把對系統的潛在影響降到最低。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章