# 1. Windows访问控制模型

访问控制模型提供了可以控制进程访问安全对象或执行各种系统管理任务的能力。

## 开始之前

平日中我们使用的Windows操作系统时，最常见的操作就是登陆系统（如图1-1），那么在这个登陆过程中到底发生了什么？

![图1-1 Windows登陆界面](https://749112129-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MGYVbXbh1HusRkolWNk%2F-MGYhIE9JnnQTPNuuFw-%2F-MGYj066d4SeiO7Tvg4M%2Fimage.png?alt=media\&token=be1b9807-524c-47dd-affa-236ad905f3c3)

当我们登陆系统时填写一个密码，当密码正确时我们便会进入操作系统，如图1-2

![图1-2 Windows登陆成功](https://749112129-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MGYVbXbh1HusRkolWNk%2F-MGYhIE9JnnQTPNuuFw-%2F-MGYjDFSORr33o31A0Gy%2Fimage.png?alt=media\&token=41f9183d-b43d-4816-ad11-1fc2b9c2d6d9)

其实这个时候操作系统将登陆凭证缓存到系统中，方便系统重复调用，避免用户重复输入密码。但是如何保障这一套机制准确无误的执行下去，就是我们本书想要表达的内容。

通常来说当我们登陆是windows的LSA会为用户创建两个登陆会话，每个会话具备一个不同的访问令牌。其中一个令牌代表用户的完整权限，以及所有的组关系和特权；另一个是经过筛选的令牌，基本上等价于标准用户的（也就是我们常说的未通过UAC的用户）权利，其中会禁用所有的高特权组并删除高级特权。系统会使用这个筛选后的令牌创建该用户的初始进程，例如Userinit.exe和Explorer.exe进程，同时该令牌会被所有的子进程继承。使用用户的完整令牌启动进程需要首先进行UAC权限提升，这一过程可以由程序来定义。

在一开始我们先看到这样一张Window权限控制如何运行的流程图，当然大部分内容你可能看不懂，但是没关系，我们先带着这样的问题来进行学习和研究，先以弄明白图中的所有元素为起点：）

![访问控制如何工作的流程图](https://749112129-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MGYVbXbh1HusRkolWNk%2F-MIci68oEZF5UMbEokFr%2F-MId7hnj8x7K7zecxsYy%2Fimage.png?alt=media\&token=8ce26534-6865-4fa5-afef-f1b36dbd56b5)

## 访问控制模型的组成

Windows中的访问控制模型（Access Control Model），它是Windows安全性的基础构件。访问控制模型有两个主要的组成部分，访问令牌（Access Token）和安全描述符（Security Descriptor），它们分别是访问者和被访问者拥有的东西。通过访问令牌和安全描述符的内容，Windows可以确定持有令牌的访问者能否访问持有安全描述符的对象。

访问控制模型有两个基本部分：

1. 访问令牌（Access tokens）：包含了有关已登录用户的信息（与特定的windows账户关联）
2. 安全描述符（Security descriptors）：包含了保护安全对象的安全信息（与被访问对象关联）

用户登录时，系统会验证用户的帐户名和密码。如果登录成功，系统将创建一个访问令牌，用户通过使用令牌的副本去创建和访问进程。访问令牌包含安全标识符，这些标识符标识用户帐户以及用户所属组。令牌还包含用户或用户组所拥有的权限列表。当进程尝试访问安全对象或执行需要特权的系统管理任务时，系统将使用此令牌来标识关联的用户是否拥有相应的权限。

创建安全对象后，系统会为其分配安全描述符，该描述符包含由其创建者指定的安全信息，如果未指定，则为默认安全信息。应用程序可以使用函数来检索和设置现有对象的安全性信息。

安全描述符标识指出对象的所有者，并且还可以包含以下访问控制列表：

1. discretionary access control list（DACL）: 用于标识哪些用户和组对目标对象有访问权限
2. system access control list（SACL）: 用于记录对安全对象访问的日志

ACL包含访问控制项（access control entries）（ACEs）的列表。每个ACE指定一组访问权限，并包含一个SID，用于标识其权限被允许、拒绝或审核的受托者。受托者可以是用户帐户、组帐户或登录会话。

**Windows访问控制流程图**

&#x20;当一个线程尝试去访问一个对象时，系统会检查线程持有的令牌以及被访问对象的安全描述符中的DACL。 如果安全描述符中不存在DACL，则系统会允许线程进行访问。如果存在DACL，系统会顺序遍历DACL中的每个ACE（ACE是ACL中一个一个的条目），检查ACE中的SID在线程的令牌中是否存在。以访问者中的User SID或Group SID作为关键字查询被访问对象中的DACL。顺序是：先查询类型为DENY的ACE，若命中且权限符合则访问拒绝；未命中再在ALLOWED类型的ACE中查询，若命中且类型符合则可以访问；以上两步后还没命中那么访问拒绝。

![Windows访问控制流程图](https://raw.githubusercontent.com/myoss114/oss/master/uPic/Uu4bcV.jpg)

![权限检查图](https://749112129-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MGYVbXbh1HusRkolWNk%2F-MGd0Z7jjGDqav7Yml_y%2F-MGd1tQ4c-mPEdb4Lk22%2Fimage.png?alt=media\&token=d7412092-5660-45e0-a850-6dd599ef81da)

接下来我们会针对模型中提到的名次与概念进行逐一的介绍与解释。

## 相关工具

#### Incognito.exe工具

```
incognito.exe list_tokens -u   查看本地可用的token       
incognito.exe -h IP -u administrator -p Password  -g list_tokens -u  通过IPC远程列举tokens
incognito.exe execute -c "NT AUTHORITY\SYSTEM" cmd.exe   以指定token执行命令
```

![Incognito.exe工具使用截图](https://749112129-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MGYVbXbh1HusRkolWNk%2F-MGcSBQC-frA7EEGnH2h%2F-MGcU-eBteixsn1Dtg7O%2Fimage.png?alt=media\&token=0c18519f-a978-4bfe-82fc-452a7271995b)
