由於最近需要使用windows的Local Group Policy的API,重新梳理一些有關windows權限的只是,這樣需要理解一些關鍵概念,這些概念之間的關聯聯系形成了一張網絡圖。必須理解才能真正理解新東西的知識體系。
以前對這些東西都是一知半解的,什么安全描述符,安全對象等等都不太明白。
1.關鍵名詞概念解釋
- 安全對象------帶有安全描述符的對象,比如文件對象,目錄對象,命名管道對象,匿名管道對象,進程對象,線程對象,訪問令牌,注冊表鍵,windows服務等。
- 訪問控制列表(ACL)-----與一個對象關聯的安全屬性列表,該列表描述了這個對象的安全訪問控制的屬性。這個對象一般就是win32 的安全對象,可以是一個文件,一個進程,
- 一個事件(Event),或其他帶有安全描述符的對象。一個ACL是由多個訪問控制項(ACE)組成的,windows有兩種類型的ACL,分別是任意訪問控制列表(discretionary ACL)和系統控制訪問列表(system ACL)
- 訪問控制項(ACE)-------多個ACE組成了一個ACL,可以把它想象成一個數組里面的元素。一個ACE包含了一組訪問權限(execute, write,read等)和一個安全ID(SID), 這個ID標識了這組訪問權限是允許,是拒絕,還是需要受到檢查才能訪問。比如,一個文件對象一個ACL列表中的其中一項就標記了這個文件不可寫或者不可讀。至於有哪些權限,可以看這里: https://msdn.microsoft.com/en-us/library/windows/desktop/aa374902(v=vs.85).aspx
- 訪問令牌(Access Token)------是一個與一個進程或線程關聯的對象,它描述了進程或線程的安全上下文。令牌中包含了與用戶賬戶關聯的進程或線程的標識和權限,當一個用戶登錄系統時,系統首先校驗用戶賬戶的密碼(正確的密碼存儲在windows系統的安全數據庫中),如果通過登陸成功,系統會生成與這個用戶賬戶關聯的訪問令牌,之后這個用戶執行啟動的每個進程或線程都會復制這個訪問令牌作為自己的令牌。令牌標識了用戶,用戶所屬的組,以及用戶的權限。系統用這個令牌來控制訪問安全對象,還有控制限制用戶的系統相關的操作。訪問令牌本身也是安全對象,因為需要控制它是否可讀寫等等。關於令牌更詳細的請看:https://msdn.microsoft.com/en-us/library/windows/desktop/aa374909(v=vs.85).aspx
- 任意訪問控制列表(DACL)-----對對象持有者控制訪問對象,並標明特定的用戶,特定的組是否能持有對象。簡單一句話就是說,定義哪個用戶,或哪個用戶所屬的組訪問該對象的權限。舉個例子,當一個進程試圖訪問一個安全對象的時候,系統就檢查檢查該安全對象的DACL的每個ACE項,逐個與該進程的訪問令牌作對比,來決定是否授權訪問給進程。如果一個安全對象沒有DACL,系統就會授予該對象的所有訪問權限給任何用戶,如果一個安全對象有DACL,但是DACL里面沒有ACE,那么系統會拒絕對該對象的任何訪問。
- 系統訪問控制列表(SACL)-----使系統管理員對一個安全對象的所有訪問都以日志記錄訪問的備份,可以簡單理解為,訪問記錄的一個表。暫時不用深入理解。
- 登陸會話(logon session)----登陸會話開始於用戶登錄電腦的那一刻,所有進程在登陸會話中都有一個同樣的primary訪問令牌,該令牌中的信息主要包括,用戶的SID,登陸的ID,還有登陸SID
- 登陸SID(logon SID)------登陸會話的安全描述ID,該ID直到用戶注銷前都有效。在登陸后,SID都是唯一的,不同的登陸會話就有不同的登陸SID,計算機啟動時,可能會重置一組登陸SID,可以從訪問令牌中檢索登陸SID,調用GetTokenInformation函數
2.知識體系圖
以上的圖應該很直接的說明這些概念是怎樣協同工作的了。下面以文本方式講解工作機制:
系統將每個 ACE 的trustee與線程的訪問令牌中標識的trustee進行比較。訪問令牌包含標識用戶所屬的用戶和組帳戶的安全標識符 (sid)。訪問令牌還包含標識當前登錄會話的登錄 sid。在訪問檢查過程中, 系統忽略未啟用的組 sid。通常, 系統使用請求訪問的線程的主訪問令牌來訪問安全對象。但是, 如果線程模擬另一個用戶, 則系統使用線程的模擬令牌。
系統將依次檢查DACL中的ACE,直到下列事件發生:
- 訪問被拒絕的 ACE 顯式拒絕對線程訪問令牌中列出的某個trustee所請求的訪問權限。
- 一個或多個允許訪問的 ACE顯式授予在線程訪問令牌中它所負責的trustee所有請求的訪問權限。
- 所有的 ACE 都已被檢查, 並且至少還有一個請求的訪問權限未被明確允許, 在這種情況下, 訪問被隱式拒絕。
下面看圖說話:
對於線程 A, 系統讀取ACE, 並立即拒絕訪問, 因為拒絕訪問的 ACE 適用於線程的訪問令牌中的用戶。在這種情況下, 系統不檢查 ACE 2和ACE 3。對於線程 B, ACE 1不適用, 因此系統將進入 ACE 2, 允許寫入訪問, 然后進入下一個ACE3, 並且 ACE 3 允許讀取和執行訪問。
由於系統在明確授予或拒絕請求的訪問時會停止檢查下一個ACE, 因此 DACL中的 ACL排列 順序非常重要。請注意, 如果該圖片示例中的 ACE 順序不同, 則系統可能已授予對線程 A的訪問權限。
更多的請參考:https://msdn.microsoft.com/en-us/library/windows/desktop/aa379298(v=vs.85).aspx
3.注意事項
不要直接修改ACL的內容,需要通過微軟專門提供的API來做,下面有參考資料:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms717798(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446659(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446596(v=vs.85).aspx
references:
http://blog.csdn.net/xbgprogrammer/article/details/16818973
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446683(v=vs.85).aspx