訪問令牌是安全引用監視器用來識別進程或者線程安全上下文的內核對象。安全上下文由描述特權、賬號和進程或者線程所屬的組等這些信息組成。在登錄的過程中,winlogon創建一個初始的令牌,該令牌代表了登錄用戶,winlogon將這個令牌附加到userinit.exe進程中。由於進程在默認情況下會繼承創建者的令牌,因此用戶的所有進程都擁有相同的令牌。
token的數據結構如下(winxp)
kd> dt _TOKEN
nt!_TOKEN
+0x000 TokenSource : _TOKEN_SOURCE
+0x010 TokenId : _LUID
+0x018 AuthenticationId : _LUID
+0x020 ParentTokenId : _LUID
+0x028 ExpirationTime : _LARGE_INTEGER
+0x030 TokenLock : Ptr32 _ERESOURCE
+0x038 AuditPolicy : _SEP_AUDIT_POLICY
+0x040 ModifiedId : _LUID
+0x048 SessionId : Uint4B
+0x04c UserAndGroupCount : Uint4B
+0x050 RestrictedSidCount : Uint4B
+0x054 PrivilegeCount : Uint4B
+0x058 VariableLength : Uint4B
+0x05c DynamicCharged : Uint4B
+0x060 DynamicAvailable : Uint4B
+0x064 DefaultOwnerIndex : Uint4B
+0x068 UserAndGroups : Ptr32 _SID_AND_ATTRIBUTES
+0x06c RestrictedSids : Ptr32 _SID_AND_ATTRIBUTES
+0x070 PrimaryGroup : Ptr32 Void
+0x074 Privileges : Ptr32 _LUID_AND_ATTRIBUTES
+0x078 DynamicPart : Ptr32 Uint4B
+0x07c DefaultDacl : Ptr32 _ACL
+0x080 TokenType : _TOKEN_TYPE
+0x084 ImpersonationLevel : _SECURITY_IMPERSONATION_LEVEL
+0x088 TokenFlags : Uint4B
+0x08c TokenInUse : UChar
+0x090 ProxyData : Ptr32 _SECURITY_TOKEN_PROXY_DATA
+0x094 AuditData : Ptr32 _SECURITY_TOKEN_AUDIT_DATA
+0x098 OriginatingLogonSession : _LUID
+0x0a0 VariablePart : Uint4B
token是長度可變的內核對象。其中有兩個非常重要的成員,一個Group SID,指明了用戶所屬的組;另一個是特權列表,它決定了擁有該令牌的進程或者線程可以執行的操作。訪問令牌的默認首要組和默認DACL將被應用到進程或者線程創建的對象中。
token可分為首要令牌和模仿令牌,在0x80的偏移中可以得到令牌類型。
該結構體的剩余部分提供了令牌的一些屬性信息。如用windbg解析notepad進程的訪問令牌
kd> !token e2122a20
_TOKEN e2122a20
TS Session ID: 0x1
User: S-1-5-21-2000478354-261478967-682003330-1005(account2)
Groups:
00 S-1-5-21-2000478354-261478967-682003330-513(XP4DEBUG\None)
Attributes - Mandatory Default Enabled
01 S-1-1-0(\Everyone)
Attributes - Mandatory Default Enabled
02 S-1-5-32-545(\BUILTIN\Users)
Attributes - Mandatory Default Enabled
03 S-1-5-4(NT AUTHORITY\INTERACTIVE)
Attributes - Mandatory Default Enabled
04 S-1-5-11(NT AUTHORITY\Authenticated Users)
Attributes - Mandatory Default Enabled
05 S-1-5-5-0-511418(不懂是什么)
Attributes - Mandatory Default Enabled LogonId
06 S-1-2-0(\LOCAL)
Attributes - Mandatory Default Enabled
Primary Group: S-1-5-21-2000478354-261478967-682003330-513(XP4DEBUG\None)
Privs:
00 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default
Authentication ID: (0,808bf)
Impersonation Level: Anonymous
TokenType: Primary
Source: User32 TokenFlags: 0x11 ( Token in use )
Token ID: 148ce3 ParentToken ID: 82838
Modified ID: (0, 148c79)
RestrictedSidCount: 8 RestrictedSids: e2122b30
在上面的分析中,Source就是TOKEN結構體+0x000偏移的值,指明了創建進程的實體。令牌的本地唯一標識符LUID由SRM創建並分配給令牌。Authentication ID是另一種類型的LUID,當令牌的創建者調用LsaLogonUser時分配給令牌。我們可以使用Authentication ID來判斷不同進程是否同屬於一個登陸會話。
受限制的訪問令牌則是把進程或者線程的首要訪問令牌或者模仿訪問令牌傳遞給CreateRestrictedToken函數得到的返回的訪問令牌。該函數將通過以下三種方式限制訪問令牌的權限,保護對象:
- 移除令牌的特權
- 將deny-only屬性應用於令牌的sid中,這樣進程或者線程將無法訪問保護對象
- 指定一個受限制的SID列表,限制對保護對象的訪問
下圖是以當前用戶身份運行notepad程序后,進程訪問令牌的屬性,里面列舉了受限制的訪問令牌: