目录
访问控制模型ACM(Access Control Model)
令牌
访问令牌
访问令牌一般包括两个部分:
一部分是令牌所表示的用户(包括会话ID、用户及其所属的组),这些信息告诉Token属于哪个用户的;
另一部分是“特权列表”(Privilege),这用来告诉进程能够进行特定的系统操作,如关闭系统、修改系统时间、加载设备驱动等。
管理员令牌
管理员令牌有二种:
当使用高特权的管理员帐号登录时,系统会同时创建两个访问令牌,其中一个是完全的管理员访问令牌
另一个是经过“过滤”的标准用户访问令牌(filtered token)-虽然以管理员登录,但应用程序默认是以标准用户权限的运行
主令牌
每个进程都有一个Token(被称为主令牌)。可以从父进程处继承(也可以修改,但其最高权限不会超过登录账户的最高权限。即只能在进程的边界上提升权限!
模仿令牌
线程默认下会使用进程的令牌来访问对象。但它也可以拥有自己的访问令牌(被称为模仿令牌(ImperonaitonToken)。但该令牌不是必须的,线程可以不拥有模仿令牌。模仿令牌的用处,如当一个线程要找开一个文件,但该文件只有User2才能打开,而主令牌属于User1,这时线程就可以模仿一个User2令牌来打开这个文件。
操作Token的UserMode API
①OpenProcessToken、OpenThreadToken
②AdjustTokenPrivileges、AdjustTokenGroups
③GetTokenInformation、SetTokenInformation
④LookupPrivilegeValue、PrivilegeCheck
⑤LookupPrivilegeDisplayName、LookupPrivilegeName
数据结构
在Windows-Research-Kernel-WRK中没有定义TOKEN的数据结构,属于undocumented的结构,主要原因是不同的操作系统版本这个数据结构的定义都有区别,以下通过kd导出的数据结构可以作为参考:
实际数据
参考下面的组图可以对照查看数据结构中的值。
主属性:
UserAndGroups:
Privileges:
DefaultDacl:
Misc:
字段分析
①Privileges定义了一个Token中的特权列表,指明该Token可以拥有哪些特权。
②ImpersonationLevel定义了Token的模拟级别,这个enum的定义如下:
③AuditPolicy 对应的数据结构TOKEN_AUDIT_POLICY如下:
④TokenType 对应的enum值如下:
⑤ProxyData 对应的数据结构SECURITY_TOKEN_PROXY_DATA如下:
⑥AuditData 对应的数据结构SECURITY_TOKEN_AUDIT_DATA如下:
TokenFlags 对应的常量定义如下:
#define TOKEN_HAS_TRAVERSE_PRIVILEGE 0x01
#define TOKEN_HAS_BACKUP_PRIVILEGE 0x02
#define TOKEN_HAS_RESTORE_PRIVILEGE 0x04
#define TOKEN_HAS_ADMIN_GROUP 0x08
#define TOKEN_IS_RESTRICTED 0x10
#define TOKEN_SESSION_NOT_REFERENCED 0x20
#define TOKEN_SANDBOX_INERT 0x40
#define TOKEN_HAS_IMPERSONATE_PRIVILEGE 0x80
内核函数
①创建Token:SeMakeSystemToken、SeMakeAnonymousLogonToken、SeMakeAnonymousLogonTokenNoEveryone
②分配Token:SeAssignPrimaryToken、SeDeassignPrimaryToken、SeExchangePrimaryToken
③裁剪Token:SeFilterToken、SeFastFilterToken、SeSubProcessToken、SeCopyClientToken
④查询Token信息:SeQueryInformationToken、SeQueryAuthenticationIdToken、SeQuerySessionIdToken、SeGetTokenControlInformation、SeTokenType、SeTokenImpersonationLevel、SeTokenIsAdmin、SeTokenIsRestricted
⑤机制查询:SeTokenCanImpersonate、SeDetailedAuditingWithToken、SeIsChildToken、SeIsChildTokenByPointer、SeIsSiblingToken、SeIsSiblingTokenByPointer
安全描述符
安全描述符(SecurityDescriptor)——是访问控制模型的灵魂,每个内核对象中都一个SecurityDescriptor结构体的指针,指向一个SD,该SD的结构体如下:
数据结构分析
①SD中描述了该对象的拥有者Owner(用户Sid)、SACL和DACL等信息。
②SACL:系统访问控制列表,用来记录某个安全对象被访问的情况,一般不用关心。
③DACL:自主访问控制列表,记录了哪些用户可以(/不可以)以何种方式访问该对象(重要)。
字段分析
内核函数
①SeCaptureSecurityDescriptor、SeReleaseSecurityDescriptor
②SeAssignSecurity、SeAssignSecurityEx、SeDeassignSecurity
③SeAccessCheck、SeFastTraverseCheck、SeValidSecurityDescriptor
④SeQuerySecurityDescriptorInfo、SeSetSecurityDescriptorInfo、SeSetSecurityDescriptorInfoEx
⑤SeAuditingFileEvents、SeAuditingFileEventsWithContext、SeAuditingHardLinkEvents、SeAuditingHardLinkEventsWithContext、SeAuditingFileOrGlobalEvents
⑥SeGetWorldRights、SeAssignWorldSecurityDescriptor、SeComputeQuotaInformationSize