Windows原理深入學習系列-訪問控制列表-關於安全描述符的補充

這是[信安成長計劃]的第 20 篇文章

0x00 目錄

0x01 安全描述符的結構

0x02 兩個結構的不同點

0x03 真正的查詢方案

0x04 參考文章

0x01 安全描述符的結構

在上一篇文章中,我們在取 DACL 的時候,對安全描述符的結構產生了疑問,在查到的資料中都在說使用 _SECURITY_DESCRIPTOR 結構,但是因為符號不是最新的等等原因,造成了錯位,最後發現應該 +0x30

圖片

而在我們去分析內核實際操作的時候發現,應該使用的是 _SECURITY_DESCRIPTOR_RELATIVE 結構,採用相對偏移的方法來進行

圖片

事實證明這是正確的,也能夠更加合理的解釋為什麼 +0x30 的位置才是真正 DACL 的位置

0x02 兩個結構的不同點

通過對比可以很明顯的發現,兩個結構的差異主要出現在後面的四個成員中,前三個成員的偏移和大小都是一致的,只有在取後面內容的時候所需要的方式是不同的。

在 _SECURITY_DESCRIPTOR 中,取 DACL,可以直接使用 +0x20 偏移的方式來進行

在 _SECURITY_DESCRIPTOR_RELATIVE 中,取 DACL,需要先 +0x10 偏移,從中取出一個相對的偏移,在我們的測試環境中,這個值是 0x30,然後在將這個偏移值加過去,也就是 +0x30 的偏移得到 DACL

0x03 真正的查詢方案

本來以為這樣就結束了,但是在最後整理的時候,發現了一個我們一開始就漏掉的信息

我們選取的方案是使用 _SECURITY_DESCRIPTOR_RELATIVE 結構,從中取出偏移值以後,再將其加上

圖片

而在最後面,有一個漏掉的信息,一個非常眼熟的 +0x20 的操作

圖片

所以,我重新看了一下整個的邏輯,發現了獲取 DACL 時真正的邏輯

注意下面的這個跳轉,這個跳轉指令的上面是對 Control 等的操作,這些值的偏移和大小在兩個結構中都是一樣的,所以不存在任何的衝突

而這個判斷條件用來判斷了 Control 中所存儲的值,如果是正數就跳轉,跳轉以後就會直接取 +0x20 的位置,然後將其返回給 DACL

圖片

接着,我去查找了相關的資料,得到了下面這樣的信息,如果未設置的話,就說明是存儲的是絕對的偏移

圖片

而這個值正好是 0x8000,在判斷 cx 的時候,最高位為 1,代表是一個負數,所以,如果判斷 Control 為正數的話,就直接拿偏移進行了獲取

所以最終的邏輯應該是這樣的,根據 Control 的情況來判斷使用什麼樣的方式

圖片

一定一定一定要把邏輯看清楚

0x04 參考文章

1.//docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-control

2.//docs.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors