Windows访问控制

Windows的访问控制模型由两个基本部分组成:

  • 访问令牌(Access Token),包含已登录用户的信息

  • 安全描述符(Security Descriptors),包含用于保护安全对象的安全信息

其余相关的概念还有安全标识符、特权等。

访问令牌

访问令牌是描述进程或线程安全上下文的对象,存储了与进程或线程相关联用户的标识和特权。用户在登录时,系统会先验证密码,验证通过后生成访问令牌,之后用户的所有进程都拥有此访问令牌的副本,如双击打开一个程序,就会拷贝explorer.exe的访问令牌。

访问令牌包含以下信息:

  • 用户帐户 (SID) 安全标识符

  • 用户组ID

  • 当前登录会话的登录SID

  • 用户或用户组的权限列表

  • 所有者SID

  • ……

令牌分为主令牌和模拟令牌。每个进程都拥有一个主令牌,默认情况下进程的线程与安全对象交互时,使用主令牌。线程可以通过模拟客户端账户的方式,使用客户端账户的身份去与安全对象交互,这种线程具有主令牌和模拟令牌。

主令牌也叫授权令牌(Delegation Token),用于交互式登录(如RDP登录访问);而模拟令牌(Impersonation Token)用于非交互式的会话(如WMI远程访问)。访问令牌存储于内存中,重启或关机后才会清除。默认情况用户只能查看用户自己和比自己权限低的所有访问令牌。

可以通过WinDbg等调试工具来查看访问令牌的结构。

举例,现在想查看进程Lenovo.Modern.ImController.exe的访问令牌结构,使用命令!process 0 0 Lenovo.Modern.ImController.exe得到进程的EPROCESS结构的地址:

EPROCESS是内核的一个结构,代表进程的进程对象。

之后使用!process ffff84898fc9c080查看此进程的信息,可以得到Token地址:

接着使用!token 地址的命令即可看到。

在用户模式下,如果不指定句柄,则显示与目标线程关联的标记,-n参数可以显示包含用户名的信息。

安全描述符

安全描述符中包含与安全对象关联的安全信息,如:

  • 安全标识符,包括所有者的SID和组SID

  • DACL(自由访问控制列表),允许或拒绝特定用户及组的访问权限

  • SACL(系统访问控制列表),记录特定用户及组的特定操作日志

  • 控制位,限定安全描述符或单个成员的含义

使用WinDbg进行双机调试,!process 0 0 cmd.exe获得cmd.exeEPROCESS结构的地址:

再使用!object fffffa8002e5bb30查看ObjectHeader的地址:

接着使用dt nt!_OBJECT_HEADER fffffa8002e5bb00获得此对象的SecurityDescriptor地址,它指向安全描述符的位置。这里的地址要计算偏移,即[address] & ~0x7,原因参考: Determining the ACL of an Object

对于DACL或SACL,都包含了零个或多个ACE(访问控制项),主要内容为:

  • 受信任的用户的SID

  • 控制权限的访问掩码(Mask)

  • ACE类型的标志

  • 一组位标志,确定子对象是否可以继承主对象相关的ACE

ACE主要有三种类型是所有安全对象都支持的:

  • 允许访问,在 DACL 中用于允许访问者访问权限

  • 拒绝访问,在 DACL 中用于拒绝访问者访问权限

  • 审核访问,在SACL中生成审核记录

以上面的图为例,DACL中第一个ACE的类型为ACCESS_ALLOWED_ACE,即允许操作;Mask为掩码,指代对应的权限,所以这个ACE的含义就是允许SID为S-1-5-32-544的对象对此安全对象做0x001fffff的操作。

安全标识符

上面多次提到了安全标识符(SID),它是用来标识受信者的唯一值,长度可变。每个账户都有一个唯一的SID,存储在安全数据库中,用户每次登录,系统都会检索相应的SID并放入访问令牌中。

SID的组成如下图:

Windows中常见的组或身份及SID:

  • S-1-0-0:空 SID,不包含任何成员的组

  • S-1-1-0:World,包含所有用户的组

  • S-1-3-0:Creator Owner,要由创建新对象的用户的安全标识符替换的安全标识符

  • S-1-3-1:Creator Group,要由创建新对象的用户的主组 SID 替换的安全标识符

  • S-1-5-18:Local SYSTEM,操作系统使用的特殊帐户

  • S-1-5-11:Authenticated Users,经过身份验证的用户

  • S-1-5-7:Anonymous,匿名登录或空会话登录

  • S-1-5-21:not unique,这里的不唯一指的是此SID会标识多个用户或组,但后面的RID不同,保证了不会出现重复的SID

常见的域内RID及代表的用户或组:

  • 500:域中的管理用户帐户

  • 512:域管理员组, 此帐户仅存在于运行服务器操作系统的系统上

  • 501:域中的来宾用户帐户,没有帐户的用户可以自动登录到此帐户

权限检查流程

Windows的权限检查流程是通过访问令牌和安全描述符相结合实现的。当线程尝试访问安全对象时,如果该对象没有DACL,则允许访问;如果存在DACL,则会在DACL中进行查找,允许或拒绝访问。

这个查找是一个比对的过程,将线程的访问令牌中的受信者与每个ACE中的受信者按顺序进行比对,直到发生下列事件之一:

  • 某条ACE拒绝令牌中受信者之一的所有访问权限

  • 一条或多条ACE允许令牌中受信者的所有访问权限

  • 如果对比完了所有ACE,还有一个及以上的访问请求没有显式允许,那么将隐式拒绝访问

线程A被拒绝访问,因为在对比的时候,类型为拒绝访问的ACE1的受信者中含有一个线程A的受信者;线程B被允许访问,因为依次对比的时候,线程B的两个受信者分别在ACE2和ACE3都符合受信者的身份要求。

从上面的例子可以看出,DACL中ACE的顺序非常重要,不同的顺序会造成不同的结果。

权限

权限是指账户的权限,用于在本地计算机上执行各种与系统相关的操作,例如关闭系统等。

通过whoami /priv命令可以查看当前用户的权限信息:

权限和上面的访问控制有两点不同:

  1. 权限控制的是对系统资源和相关任务的访问,而访问控制则针对安全对象

  2. 系统管理员可以将权限分配给用户或组,而系统则根据安全描述符相关来授予或拒绝对安全对象的访问权限

当用户执行特权操作时,系统会检查用户是否具有此特权,如果具有,则检查是否启用了此特权,是则允许执行,否则将拒绝。

访问令牌中存在用户及所属组的特权信息:

注意,这些特权仅适用于本地计算机,而域帐户可以在不同的计算机上具有不同的权限。

用户帐户控制

用户帐户控制(UAC)可以防止恶意程序损害计算机,通过UAC,应用程序可以始终在非管理员权限下运行,除非管理员显式授予权限。

当普通用户运行需要管理员权限的应用程序时,UAC会要求该用户提供管理员级别的访问凭据。

在UAC下,管理员登录时,系统会授予一个普通用户令牌和一个管理员令牌,普通用户令牌用来执行不需要管理员权限的应用程序,Explorer.exe也是使用普通令牌启动的,所以用户启动的其他应用程序同样是普通用户权限。

Last updated