Windows原理深入學習系列-訪問控制列表
這是[信安成長計劃]的第 19 篇文章
0x00 目錄
0x01 介紹
0x02 DACL
0x03 建立DACL
0x04 檔案讀取測試
0x05 程序注入測試
0x06 原理分析 Win10_x64_20H2
0x07 參考文章
在最後分析的時候糾正一下網上大批分析文章中的一個錯誤,東西只有自己實踐了才知道
0x01 介紹
在上一篇講強制完整性控制的時候提到過,在許可權檢查的時候,會先進行強制完整性檢查,然後再進行 DACL 檢查,DACL 就是包含在這次要提到的 ACL 當中的。
訪問控制列表(Access Control List,ACL),其中的每一項叫做訪問控制條目(Access Control Entries,ACE)。
訪問控制列表是屬於安全物件的安全描述符的,根據文件可以看出來,安全描述符中包含了兩個跟 ACL 相關的資訊,DACL(discretionary access control list)和 SACL(system access control list)
DACL 可以對發起請求的使用者或者組進行許可權控制,允許或者拒絕它們的訪問
SACL 使監視對受保護物件的訪問成為可能,其資訊會在安全日誌中被記錄
那所謂的安全物件又是什麼,根據微軟提供的文件可以發現,檔案、目錄、程序、執行緒、登錄檔、服務、管道、印表機、網路共享等等都屬於安全物件,也就意味著它們都擁有 DACL 和 SACL,也就說明了所有這些內容都是可以進行許可權控制和日誌記錄的。
說了這麼多,那到底 DACL 和 SACL 都是什麼東西,這其實就是我們平時最常見的安全屬性介面
DACL、SACL、ACE 分別對應的就是下面這些
接下來我們重點來說一下 DACL
0x02 DACL
對於 DACL 的不同情況,Windows 也會有不同的處理方式
如果安全描述符中沒有 DACL,即 DACL 為 NULL,Windows 會允許任何使用者的完全訪問許可權。
如果有 DACL,但是 DACL 為空,即沒有 ACE,Windows 將不允許任何使用者的任何訪問
如果有 DACL,也有 ACE,Windows 將會依次檢查 ACE,直到找到一個或多個 ACE 允許所有請求的訪問許可權,或者直到任何請求的訪問許可權被拒絕
對於前兩種就不必多說了,主要來說一下第三種情況,這裡就借用微軟的圖來說一下
Thread A 擁有 Andrew 的訪問令牌,當 Thread A 訪問 Object 物件的時候,會從 DACL 中的第一個 ACE 開始檢查,第一個許可權是 Access denied,使用者名稱是 Andrew,剛好與 Thread A 相同,就發生了拒絕訪問。
Thread B 擁有 Jane 的訪問令牌,當 Thread B 訪問 Object 物件的時候,也會從第一個 ACE 開始檢查,第一個並不滿足;然後檢查第二個,Group A 的允許寫,而 Jane 是屬於 Group A 的,所以獲得了寫的許可權;然後檢查第三個,Everyone 有讀和執行許可權,所以 Thread B 就有了讀、寫、執行許可權。
根據上面這個例子也能夠看出來,ACE 順序的重要性,如果第一個不是對 Andrew 的禁止的話,Thread A 就已經獲取到許可權了。
同時 ACE 也是可以被繼承的,在每個 ACE 中都有一個專門標記與繼承相關資訊的標誌位,一般最常見的就是全繼承,父物件與子物件具有相同的許可權控制和審計設定。
需要注意的是,繼承而來的 ACE,在子物件中是不能進行修改的,找兩個例子就可以看出來了
這一項是沒有被繼承的,許可權位是可以進行修改的
如果是繼承的話,所有的許可權位直接為灰色,不可修改
0x03 建立DACL
先說一個小插曲,剛開始的時候,我還想著 ProcessHacker 會有相關的程式碼,是不是可以直接拿來用了,然後在原始碼裡翻了半天,並沒有發現有相關的程式碼,最後在 ProcessHacker 官方論壇上發現瞭如下的對話
EditSecurity 函式上面寫的很清楚,這個展示頁是專門讓使用者編輯 ACE 的,它屬於一個專門的 DLL,名字是 Aclui.dll
除了使用上面那樣在圖形化介面中修改之外,還可以通過 API 來進行處理
整個的流程微軟也已經列出來了 https://docs.microsoft.com/en-us/windows/win32/secbp/creating-a-dacl
唯一感覺不甚友好的就是設定其許可權時候所使用的 SDDL,這個可讀性確實是有點差了
這裡就不實踐了,相關的文件,還有一份大佬的部落格,我一起放到最後的參考連結當中
還可以通過我們上一篇文章中所提到的命令列工具 icacls 來完成,它在示例當中也描述的很清楚了
除此之外,PowerShell 真是個好東西,有一個 Get-Acl 命令也可以查詢
它也能獲取登錄檔的訪問許可權
就檢視的資訊而言,也更加的清晰了
當然,也能使用 Set-Acl 命令對其進行修改,大佬的文章連結我直接貼到最後的參考文獻裡
0x04 檔案讀取測試
首先我們先看一下檔案當前的 ACL
由於當前使用者屬於 Administrator 組,所以讀取是沒有問題的
然後手動刪除掉許可權,由於當前的許可權都是繼承過來的,所以無法直接刪除
但是在編輯框中可以很方便的禁用繼承關係,我們可以直接禁用掉,最好還是選擇第一個,因為當前所有的 ACE 都是繼承過來的,如果刪除掉所有的繼承許可權的話,當前的 DACL 就會變成一個空的 DACL,那將無法進行訪問了!
然後對許可權進行刪除,這裡我只保留了 SYSTEM 許可權
訪問直接就被拒絕了
0x05 程序注入測試
與上次一樣,我們還是使用 RDI 來進行測試
先起一個 notepad 程序,可以發現我們的當前賬戶 admin 是擁有完全控制權限的
然後使用 RDI 來進行注入,一切正常
接下來再找一個當前沒有許可權的來嘗試一下注入,為了排除完整性帶來的干擾,我們直接修改這個 notepad 的 ACE,直接刪除當前使用者
然後再來進行測試,可以發現,直接無法開啟目標程序了,返回的錯誤碼是拒絕訪問
0x06 原理分析 Win10_x64_20H2
我們以這個 winlogon 為例
先取到 EPROCESS 結構
看一下物件頭的結構,SecurityDescriptor 存在裡面,這一點我們在剛開始的時候也說過了
要取到當前程序的結構頭,這裡需要注意的是,SecurityDescriptor 與 Token 一樣,最後四位都是一個快速引用的東西(雖然現在還不太明白是幹什麼用的)
接著就來看一下 _SECURITY_DESCRIPTOR 結構當中到底儲存了哪些內容
雖然能夠看到 SACL、DACL 等資訊,但是有點問題,這些地址很明顯是不正確的,它們明顯不是地址,也是讀不出來的
經過查詢,發現網上在碰到這裡的時候,都沒有看這個結構的資料,直接從首地址加上 0x30 的偏移找到 DACL,為了能更好的明白 Windows 在這個時候在做什麼,可以一個與獲取 DACL 有關的函式
通過微軟文件可以看到這個函式所用到的引數
這裡的 r8 暫存器就是用來儲存返回的 Dacl 的指標,如果按照 _SECURITY_DESCRIPTOR 結構來驗證的話,這裡先取到了 Group 中的值,然後加上 _SECURITY_DESCRIPTOR 的地址,最後直接返回給了 r8,這在邏輯上是完全講不通的
但是就在分析的時候,無意中發現了另外的一個結構 _SECURITY_DESCRIPTOR_RELATIVE,看名字當前的位置應該都是相對偏移了,感覺有可能是正確的
再拿剛剛的邏輯來分析一下,很明顯是對的上了
那就回到前面,繼續用這個結構進行分析,可以看到 Dacl 處的 0x30 偏移,這也就是網上都在說結構錯了,需要 +0x30 才能找到 Dacl 的真正原因
按照剛剛分析函式的邏輯,可以直接取到 DACL 的地址
因為它們還是 ACL 結構的,所以繼續檢視結構體,可以看到當前 ACL 的大小是 0x3c,當前 ACL 當中有 2 個 ACE
接下來應該查詢 ACE 了,但是並沒有發現與 ACE 有關的結構,經過搜尋,發現在 Win32 的 API 裡有一個與 ACE 有關的結構 _ACE_HEADER,可以看到裡面有 ACE 的型別、大小等資訊
根據型別可以找到更多的與 ACE 相關的結構,比如 ACCESS_ALLOWED_ACE
這樣就都串起來了,每一項 ACE 都有一個 ACE_HEADER,然後根據型別的不同,後面跟著的是不同的資料結構
但是還有個問題,ACE 到底該怎麼取,從哪裡開始取,接下來就來分析一下 RtlGetAce 函式,根據引數可以很明顯的發現,他會先傳入 ACL,然後根據要獲取的 ACE 的索引進行查詢,最後再進行返回
上面這些判斷並不是關鍵,下面的迴圈取值才是關鍵要看到的內容
先取到 ACL 的大小,然後偏移到 ACL 的後面
r9 是 rcx+8 的地址,目前也就是 ACL 的頭的結尾位置,加二並將值賦給 eax,因為緊接著是 _ACE_HEADER 結構,所以 eax 就是當前 ACE 的大小
r8 用來迴圈計數,判斷 AceIndex 的,我們暫且不用關心,只看它是怎麼獲取的
將 r9 加上大小,然後賦值回去,就返回 ace 了
這裡看著是跳過了第一個 ACE,實際上是因為當 AceIndex 為 0 時,在上面 rcx+8 的時候就已經是其地址了,所以就不會進入當前的這個迴圈
在分析完結構以後,繼續在 WinDBG 當中看一下
第一位是 Type,第二位是 Flags,第三位是 Size,緊接著四位是 Mask,接著後面是 Sid
Type 為 0,就是 ACCESS_ALLOWED_ACE,雖然最後的 Sid 只是一個 DWORD 型別,但是根據名字就可以看出來了,這只是記錄一下地址的,總大小在前面已經有記錄了
對於 ACCESS_MASK,就是用來描述當前許可權的
它主要分為了幾個部分,對於一般和標準的都有詳細標記,至於特殊許可權位,沒有查到詳細的內容,感興趣可以挨個試一試,連結我全部放到最後的參考文章當中
接下來就是 SID 了,它是有結構的,可以直接進行檢視
這樣 ACE 也就解析出來了
第一個是 S-1-5-18 即 SYSTEM 賬戶允許 STANDARD_RIGHTS_ALL 和 SPECIFIC_RIGHTS_ALL 許可權
第二個 SID 就是 S-1-5-32-544,可以查到他對應的是賬戶是 Administrators
這也就剛開始看到的 ACE 項所對應了
這樣也就完成了整個 DACL 的查詢
0x07 參考文章
1.https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists
2.https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor
3.https://docs.microsoft.com/en-us/windows/win32/secauthz/securable-objects
4.https://docs.microsoft.com/en-us/windows/win32/secauthz/securable-objects
5.https://docs.microsoft.com/en-us/windows/win32/secauthz/dacls-and-aces
6.https://docs.microsoft.com/en-us/windows/win32/secauthz/how-dacls-control-access-to-an-object
7.https://www.cnblogs.com/cdaniu/p/15630284.html
8.https://helgeklein.com/blog/permissions-a-primer-or-dacl-sacl-owner-sid-and-ace-explained/
9.https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/acls-dacls-sacls-aces
10.https://secureidentity.se/acl-dacl-sacl-and-the-ace/
11.https://wj32.org/processhacker/forums/viewtopic.php?t=2568
12.https://docs.microsoft.com/en-us/windows/win32/api/aclui/nf-aclui-editsecurity
13.https://docs.microsoft.com/en-us/windows/win32/secbp/creating-a-dacl
14.https://www.cnblogs.com/iBinary/p/11399114.html#tid-HABck4
15.https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings
16.https://myzxcg.com/2021/08/Windows-訪問控制模型二/
17.https://www.redteaming.top/2020/02/03/Windows——Access-Control-List/
18.https://3gstudent.github.io/滲透技巧-Windows下的Access-Control-List
19.https://blog.csdn.net/sunyikuyu/article/details/9041067
21.https://improsec.com/tech-blog/windows-kernel-shellcode-on-windows-10-part-2
22.https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
23.https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
24.https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask
25.https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/access-mask