歡迎關注微信公眾號:[信安成長計划]
0x00 目錄
0x01 介紹
0x02 完整性等級
0x03 文件讀取測試
0x04 進程注入測試
0x05 原理分析 Win10_x64_20H2
0x06 參考文章
0x01 介紹
強制完整性控制(Mandatory Integrity Control,MIC),它是對 discretionary access control list 的補充,並且是在 DACL 之前檢查的
這是從 Windows Vista 新增的安全機制,在 Windows XP 中幾乎所有的進程都是運行在管理員權限下的。
在官方文檔中描述為 Windows 為其划分了四個完整性級別:低、中、高、系統;但從實際上看到的對應表中,有五個等級,多了一個不受信任等級
在查資料的時候發現,還會有一個等級,高於 System 完整性,被叫做 Protected integrity level,但是它默認情況下是沒有使用的,它只能由內核層來設置
具有低完整性級別的主體無法寫入具有中等完整性級別的對象,這就相當於提供了一種在同一用戶下,根據可信程度來限制不同進程之間的交互,低完整性等級的進程都無法對高完整性進程進行注入
雖然是限制了進程間的交互,但是高低完整性的進程還是可以通過其他的進程間通信的方式來進行交互:共享內存、Sockets、RPC、Windows 消息機制、命名管道,這些是不受限制的。
0x02 完整性等級
Windows 直接使用了 SID 來定義完整性等級,這樣就非常容易的將此機制集成到現有的結構當中,還不用修改代碼
完整性等級所使用的 SID 格式是:S-1-16-xxxx
16 就是強制完整性的標識,后面的 xxxx,就是所對應的 RID,用來表示完整性等級的,這個值就是上面所提到的那幾個十六進制值,它們以 0x1000 為間隔,也是為了將來能夠再定義其他的等級
所以組合到一起以后完整性等級所對應的 SID 就變成了
System
這是最高的完整性級別,由在本地服務、網絡服務和系統賬戶下運行的進程和服務使用。此級別的目的是在管理員和系統之間提供一個安全層,即使以完全管理員身份運行的進程也無法與系統完整性級別進程交互
唯一的例外情況是,如果管理員賬戶被授予 SE_DEBUG_NAME 權限,那么他就可以在 token 中啟用這個權限,來進行交互
High
分配給在管理員賬戶下運行的進程的默認完整性級別,如果啟用了 UAC,則此級別將僅提供給提升過 UAC 權限的用戶
Medium
授予在非管理員用戶賬戶下運行的進程或啟用 UAC 的管理員賬戶上的進程。
此完整性級別的進程只能修改 HKEY_CURRENT_USER、非受保護文件夾中的文件以及具有相同或更低完整性的進程。
Low
最低完整性級別默認不分配給進程,它要么通過繼承,要么由父進程設置。
以低完整性級別運行的進程只能在 HKEY_CURRENT_USER\Software\AppDataLow 下操作,或者將文件寫入 %USERPROFILE%\AppData\LocalLow 目錄下
低完整性進程實際上不可能對系統進行任何更改,但仍然可以讀取大部分的數據。
在 Process Explorer 中可以查看到進程的完整性等級
可以看到 Chrome 默認啟動的是 Medium 等級的,其中還有 Low 等級的,這個可能就是沙盒用到的,給它們足夠低的等級,能夠最大限度的減少在出現問題時所帶來的影響;而大量的不被信任的進程,有可能就是各個標簽頁所在的處理進程
還有幾點需要注意:
1.進程是無法更改自己的完整性等級的
2.進程一旦運行,完整性等級是無法再修改了,即使是更高完整性等級的進程
3.進程只能夠創建具有相同或者更低完整性等級的進程
4.進程不能修改或者寫入具有更高完整性等級的進程或者文件
完整性等級的限制還有幾個例外的情況
1.被授予 SE_DEBUG_NAME 權限的高完整性等級的進程可以修改更高完整性等級的進程
2.中等完整性的進程可以通過一些操作提升到高完整性等級,這就是平時的 Bypass UAC 的操作
3.進程可以請求從中等完整性提升到高完整性等級,這個只能在執行的時候發生,會彈出 UAC 的提示讓用戶來選擇
0x03 文件讀取測試
微軟提供了一個可以來修改默認完整性等級的命令行工具——icacls
具體的命令參數可以查看幫助信息
除此之外,還有一個更強大的替代方案——Chml,可以在 http://www.minasi.com/apps/ 中獲得
從中可以很清楚的看到完整性等級以及詳細的權限等等
因為當前是中等完整性等級,我們運行的 cmd 也是中等完整性等級,所以是可以直接看到的
為了驗證,我們拷貝一個 cmd 應用出來,並將它處理為低完整性等級
但是,發現它還是可以讀取的
這是因為這個權限並沒有被禁止,我們在上面查詢的時候,發現只有不可寫是開啟的
可以用寫操作來驗證一下,可以發現確實是不可寫的
如果想要讓其也不可讀,就需要將不可讀的權限開起來
然后再來驗證一下,確實跟我們所設想的是一樣的
這樣我們就有了一個保護文件的方案,將敏感文件的完整性等級修改為高完整性,這樣完整性等級低一些的將無法對文件進行讀取等操作
正常啟動的 cmd 與低完整性的 cmd 都是無法查看的
只有管理員權限的才能夠對其進行查看
0x04 進程注入測試
至於注入,就直接偷懶了,用 RDI 來進行測試
首先我們起一個 notepad,現在兩個都是中等完整性級別
然后進行注入的測試,是沒有問題的
然后再使用我們之前所用到的低完整性等級的 cmd,再來測試注入
發現訪問被拒絕,無法打開句柄
0x05 原理分析 Win10_x64_20H2
在內核里,強制完整性等級是存儲在 Token 當中的,我們可以在 _TOKEN 結構體當中找到,以這個 msedge 為例
6200 換成十六進制也就是 0x1838,先找到這個進程
查看當前的 EPROCESS 結構,需要從中找到 Token,可以發現 Token 在 0x4b8 的位置
然后看一下這個結構體的內容,Token 的地址就應該是 0xffffb681`c89d20a0
從中可以發現 0xd0 的位置與完整性等級有關,但是根據這個名字可以看出來,這只是一個索引
那么如何根據索引來找其對應的內容呢,我們可以來找一找相關的函數,看 Windows 是怎么處理的,可以發現有一個跟查詢相關的函數
跟過以后發現,它直接調用了 SepCopyTokenIntegrity,同時傳了兩個參數
跟進去以后發現,沒有做任何處理直接調用了 SepLocateTokenIntegrity
因為之前傳來了兩個參數,所以 rcx 就是 TOKEN,根據這里可以看出來,先從 TOKEN 中獲取到 IntegrityLevelIndex,如果索引是 -1 的話,就直接返回 0,否則就將索引乘以 16,然后在 UserAndGroups 當中尋找,並將值返回
如果返回值不為 0,就從返回值中取值,將其返回到第二個參數中,然后再將返回值中的地址 +8 的位置存儲到第二個參數偏移 8 的位置,最后返回
如果返回值為 0,也就意味着 IntegrityLevelIndex 為 -1,就從 SeUntrustedMandatorySid 中取值,並將其返回到第二個參數當中,然后將 0x60 存入,返回
而第二個參數是 SID_AND_ATTRIBUTES 類型的,可以看到,第一個位置存儲的就是 Sid,而偏移 8 的位置就是 Attributes
所以,我們也要按照這樣的方式來進行查找
通過官方文檔可以看到第一個參數是一個指向 SID 結構的指針
所以我們繼續來查結構
到這里已經發現跟剛開始所提到的知識對上了,16 代表是強制完整性,0x2000 代表了是中等完整性等級
我們讓 WinDBG 自己來解析一下,也是得到了一樣的結果
0x06 參考文章
1.https://docs.microsoft.com/en-us/windows/win32/secauthz/mandatory-integrity-control
2.https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb625957(v=msdn.10)
3.https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb625963(v=msdn.10)
4.https://www.malwaretech.com/2014/10/usermode-sandboxing.html
5.https://zeltser.com/windows-integrity-levels-for-spyware-protection-processe/
6.https://zeltser.com/windows-integrity-levels-malware-protection-files/
9.https://blog.didierstevens.com/2010/09/07/integrity-levels-and-dll-injection/
10.https://en.wikipedia.org/wiki/Mandatory_Integrity_Control
12.https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-token_groups
13.https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid_and_attributes