访问令牌是安全引用监视器用来识别进程或者线程安全上下文的内核对象。安全上下文由描述特权、账号和进程或者线程所属的组等这些信息组成。在登录的过程中,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程序后,进程访问令牌的属性,里面列举了受限制的访问令牌: