├── .gitbook └── assets │ ├── image (1).png │ ├── image (10).png │ ├── image (11).png │ ├── image (12).png │ ├── image (13).png │ ├── image (14).png │ ├── image (15).png │ ├── image (16).png │ ├── image (17).png │ ├── image (2).png │ ├── image (3).png │ ├── image (4).png │ ├── image (5).png │ ├── image (6).png │ ├── image (7).png │ ├── image (8).png │ ├── image (9).png │ └── image.png ├── 1.-windows-fang-wen-kong-zhi-mo-xing.md ├── 4.-ad-zhong-de-acl.md ├── LICENSE ├── README.md ├── SUMMARY.md ├── access-token.md ├── ace-strings.md ├── ba-qi-ta.md ├── er-an-quan-miao-shu-fu.md ├── liu-ji-quan-ce-lve.md ├── qi-an-quan-biao-shi-fu.md ├── quan-xian-kong-zhi-qi-ta-nei-rong.md ├── san-acl.md ├── security-descriptor-definition-language-for-conditional-aces.md ├── security-descriptor-definition-language.md ├── si-ace.md ├── sid-strings.md └── wu-fang-wen-quan-xian-yu-quan-xian-ma.md /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (10).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (10).png -------------------------------------------------------------------------------- /.gitbook/assets/image (11).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (11).png -------------------------------------------------------------------------------- /.gitbook/assets/image (12).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (12).png -------------------------------------------------------------------------------- /.gitbook/assets/image (13).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (13).png -------------------------------------------------------------------------------- /.gitbook/assets/image (14).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (14).png -------------------------------------------------------------------------------- /.gitbook/assets/image (15).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (15).png -------------------------------------------------------------------------------- /.gitbook/assets/image (16).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (16).png -------------------------------------------------------------------------------- /.gitbook/assets/image (17).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (17).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (5).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (6).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (7).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (8).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image (9).png -------------------------------------------------------------------------------- /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootclay/Windows-Access-Control/51af80a5dcf4d9ab712c2bb6a70298aa44d2c122/.gitbook/assets/image.png -------------------------------------------------------------------------------- /1.-windows-fang-wen-kong-zhi-mo-xing.md: -------------------------------------------------------------------------------- 1 | # 1. Windows访问控制模型 2 | 3 | 访问控制模型提供了可以控制进程访问安全对象或执行各种系统管理任务的能力。 4 | 5 | ## 开始之前 6 | 7 | 平日中我们使用的Windows操作系统时,最常见的操作就是登陆系统(如图1-1),那么在这个登陆过程中到底发生了什么? 8 | 9 | ![图1-1 Windows登陆界面](.gitbook/assets/image%20%284%29.png) 10 | 11 | 当我们登陆系统时填写一个密码,当密码正确时我们便会进入操作系统,如图1-2 12 | 13 | ![图1-2 Windows登陆成功](.gitbook/assets/image%20%288%29.png) 14 | 15 | 其实这个时候操作系统将登陆凭证缓存到系统中,方便系统重复调用,避免用户重复输入密码。但是如何保障这一套机制准确无误的执行下去,就是我们本书想要表达的内容。 16 | 17 | 通常来说当我们登陆是windows的LSA会为用户创建两个登陆会话,每个会话具备一个不同的访问令牌。其中一个令牌代表用户的完整权限,以及所有的组关系和特权;另一个是经过筛选的令牌,基本上等价于标准用户的(也就是我们常说的未通过UAC的用户)权利,其中会禁用所有的高特权组并删除高级特权。系统会使用这个筛选后的令牌创建该用户的初始进程,例如Userinit.exe和Explorer.exe进程,同时该令牌会被所有的子进程继承。使用用户的完整令牌启动进程需要首先进行UAC权限提升,这一过程可以由程序来定义。 18 | 19 | 在一开始我们先看到这样一张Window权限控制如何运行的流程图,当然大部分内容你可能看不懂,但是没关系,我们先带着这样的问题来进行学习和研究,先以弄明白图中的所有元素为起点:) 20 | 21 | ![访问控制如何工作的流程图](.gitbook/assets/image%20%2815%29.png) 22 | 23 | ## 访问控制模型的组成 24 | 25 | Windows中的访问控制模型(Access Control Model),它是Windows安全性的基础构件。访问控制模型有两个主要的组成部分,访问令牌(Access Token)和安全描述符(Security Descriptor),它们分别是访问者和被访问者拥有的东西。通过访问令牌和安全描述符的内容,Windows可以确定持有令牌的访问者能否访问持有安全描述符的对象。 26 | 27 | 访问控制模型有两个基本部分: 28 | 29 | 1. 访问令牌(Access tokens):包含了有关已登录用户的信息(与特定的windows账户关联) 30 | 2. 安全描述符(Security descriptors):包含了保护安全对象的安全信息(与被访问对象关联) 31 | 32 | 用户登录时,系统会验证用户的帐户名和密码。如果登录成功,系统将创建一个访问令牌,用户通过使用令牌的副本去创建和访问进程。访问令牌包含安全标识符,这些标识符标识用户帐户以及用户所属组。令牌还包含用户或用户组所拥有的权限列表。当进程尝试访问安全对象或执行需要特权的系统管理任务时,系统将使用此令牌来标识关联的用户是否拥有相应的权限。 33 | 34 | 创建安全对象后,系统会为其分配安全描述符,该描述符包含由其创建者指定的安全信息,如果未指定,则为默认安全信息。应用程序可以使用函数来检索和设置现有对象的安全性信息。 35 | 36 | 安全描述符标识指出对象的所有者,并且还可以包含以下访问控制列表: 37 | 38 | 1. discretionary access control list(DACL): 用于标识哪些用户和组对目标对象有访问权限 39 | 2. system access control list(SACL): 用于记录对安全对象访问的日志 40 | 41 | ACL包含访问控制项(access control entries)(ACEs)的列表。每个ACE指定一组访问权限,并包含一个SID,用于标识其权限被允许、拒绝或审核的受托者。受托者可以是用户帐户、组帐户或登录会话。 42 | 43 | **Windows访问控制流程图** 44 | 45 | 当一个线程尝试去访问一个对象时,系统会检查线程持有的令牌以及被访问对象的安全描述符中的DACL。 如果安全描述符中不存在DACL,则系统会允许线程进行访问。如果存在DACL,系统会顺序遍历DACL中的每个ACE(ACE是ACL中一个一个的条目),检查ACE中的SID在线程的令牌中是否存在。以访问者中的User SID或Group SID作为关键字查询被访问对象中的DACL。顺序是:先查询类型为DENY的ACE,若命中且权限符合则访问拒绝;未命中再在ALLOWED类型的ACE中查询,若命中且类型符合则可以访问;以上两步后还没命中那么访问拒绝。 46 | 47 | ![Windows访问控制流程图](https://raw.githubusercontent.com/myoss114/oss/master/uPic/Uu4bcV.jpg) 48 | 49 | ![权限检查图](.gitbook/assets/image.png) 50 | 51 | 接下来我们会针对模型中提到的名次与概念进行逐一的介绍与解释。 52 | 53 | ## 相关工具 54 | 55 | #### Incognito.exe工具 56 | 57 | ```text 58 | incognito.exe list_tokens -u 查看本地可用的token 59 | incognito.exe -h IP -u administrator -p Password -g list_tokens -u 通过IPC远程列举tokens 60 | incognito.exe execute -c "NT AUTHORITY\SYSTEM" cmd.exe 以指定token执行命令 61 | ``` 62 | 63 | ![Incognito.exe工具使用截图](.gitbook/assets/image%20%285%29.png) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /4.-ad-zhong-de-acl.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Active 4 | Directory(AD)对象安全描述符是一个尚未开发的攻击环境,攻击者和防御者都经常忽略它们。尽管AD安全描述符错误配置可以提供许多有助于提升域权限的路径,但它们也为隐蔽部署Active 5 | Directory持久性提供了独特的机会。通常很难确定特定的AD安全描述符错误配置是故意设置的还是偶然实现的。 6 | --- 7 | 8 | # 4. AD中的ACL 9 | 10 | Active Directory(AD)对象安全描述符是一个尚未开发的攻击环境,攻击者和防御者都经常忽略它们。尽管AD安全描述符错误配置可以提供许多有助于提升域权限的路径,但它们也为隐蔽部署Active Directory持久性提供了独特的机会。通常很难确定特定的AD安全描述符错误配置是故意设置的还是偶然实现的。 11 | 12 | 随着人们对Golden1和Silver2 Kerberos票证的认识不断提高,行业开始意识到“无恶意软件”的持久性技术。也就是说,不涉及在系统上执行代码的持久性策略是为了保留将来对环境的访问。尽管Golden和Silver Kerberos票证攻击可以在环境中进行任何修改或提供代码执行的持久性,但存在另一种促进Active Directory持久性的途径。安全描述符持久性方法确实涉及对环境的某种类型的修改。但是,不需要执行代码,并且所做的更改通常会在操作系统和域功能级别升级后继续存在。这意味着Active Directory安全描述符的修改提供了一个极好的机会,可以以最小的痕迹在域中进行持久化。 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | 本项目主要把理解的Windows访问控制内容进行输出整理,并结合上安全问题来讲解。在学习并整理的过程中发现WIndows的认证内容繁多,访问控制只是其冰山一角,后续也会考虑以访问控制为基础继续完善本项目,将整个认证梳理为文,为后来之人提供研究基础。 4 | --- 5 | 6 | # Windows访问控制 7 | 8 | ## 介绍 9 | 10 | Author:香山(微信:\_xiangshan) 11 | 12 | 本文刚开始写,慢慢写完再发布,不妥之处及时沟通 13 | 14 | Gitbook链接地址:[https://rootclay.gitbook.io/windows-access-control/](https://rootclay.gitbook.io/windows-access-control/) 15 | 16 | **访问控制**是指控制谁可以访问操作系统中资源的安全功能。 应用程序调用访问控制功能来设置谁可以访问特定资源,或者控制对应用程序提供的资源的访问。 17 | 18 | 此概述描述了用于控制对Windows对象(例如文件)的访问,以及用于控制对管理功能(例如设置系统时间或审核用户的操作)的访问的安全模型。 访问控制模型主题提供了访问控制各部分以及它们之间如何交互的高级描述。 19 | 20 | 访问控制是一个经久不衰的话题,实际上访问控制的目标就是依据授权,对提出的资源访问请求进行控制,防止未授权的访问。未授权的访问主要包括:未经授权的使用,泄露,销毁信息以及颁发指令等等。现实生活中我们经常接触到访问控制,比如:保险箱,防止外人打开,取走宝贵的资料。再比如,学校的图书馆,寝室等等需要用校园卡刷卡进入,只有拥有校园卡的人才可以进入图书馆。 21 | 22 | 所以策略(ACL)就体现在其中了,比如我们猜测图书馆对于策略的规定是只有学生,严格意义上是只有持有校园卡的学生才能进入图书馆,这就是一种策略。 23 | 24 | 25 | 26 | ## 27 | 28 | ### 29 | 30 | ### 31 | 32 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Windows访问控制](README.md) 4 | * [1. Windows访问控制模型](1.-windows-fang-wen-kong-zhi-mo-xing.md) 5 | * [(一)Access Token](access-token.md) 6 | * [(二)安全描述符(SD)](er-an-quan-miao-shu-fu.md) 7 | * [(三)ACL](san-acl.md) 8 | * [(四)ACE](si-ace.md) 9 | * [(五)访问权限与权限码](wu-fang-wen-quan-xian-yu-quan-xian-ma.md) 10 | * [(六)集权策略](liu-ji-quan-ce-lve.md) 11 | * [(七)安全标识符(SID)](qi-an-quan-biao-shi-fu.md) 12 | * [(八)其他](ba-qi-ta.md) 13 | * [2. SDDL](security-descriptor-definition-language.md) 14 | * [(一)基于条件表达式ACE的SDDL](security-descriptor-definition-language-for-conditional-aces.md) 15 | * [(二)ACE字符串](ace-strings.md) 16 | * [(三)SID字符串](sid-strings.md) 17 | * [3. 权限控制其他内容](quan-xian-kong-zhi-qi-ta-nei-rong.md) 18 | * [4. AD中的ACL](4.-ad-zhong-de-acl.md) 19 | 20 | -------------------------------------------------------------------------------- /access-token.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 'Access Token:与特定的windows账户关联,账户环境下启动的所有进程都会获得该令牌的副本,进程中的线程默认获得这个令牌。' 3 | --- 4 | 5 | # (一)Access Token 6 | 7 | ## 访问令牌(Access tokens) 8 | 9 | 访问令牌是描述进程或线程的安全上下文的对象。令牌中的信息包括与进程或线程关联的用户帐户的标识和特权信息。当用户登录时,系统通过将用户密码与安全数据库(如域认证中的NTDS或本地认证中的SAM文件)中存储的信息进行比较来验证用户密码。如果密码经过验证,则系统将生成访问令牌。代表该用户执行的每个进程都有此访问令牌的副本。(通常我们在输入密码登陆进入Windows界面时就是一个生成访问令牌的过程) 10 | 11 | 当线程与安全对象进行交互或尝试执行需要特权的系统任务时,系统使用访问令牌来标识用户。访问令牌包含以下信息: 12 | 13 | * 用户帐户的安全标识符(SID)(关SID是什么后续章节会详细介绍) 14 | * 用户所在组的SID 15 | * 标识当前登录会话(logon session)的登录SID 16 | * 用户或用户组拥有的特权列表 17 | * 所有者SID 18 | * 主要组的SID 19 | * 用户创建安全对象而不指定安全描述符时系统使用的默认DACL 20 | * 访问令牌的来源 21 | * 令牌是主要令牌(内核分配的令牌)还是模拟令牌(模拟而来的令牌) 22 | * 受限制SID的可选列表(如UAC存在时会针对某些账户删除某些特权) 23 | * 当前的模拟级别 24 | * 其他数据 25 | 26 | Access tokens产生的大致过程为: 27 | 28 | 1. 使用凭据\(用户密码\)进行认证 29 | 2. 当前登录会话的Session创建 30 | 3. Windows此时会返回用户sid和用户组sid 31 | 4. LSA\(Local Security Authority\)创建一个Token 32 | 5. 依据该token创建进程、线程\(如果CreaetProcess时自己指定了 Token, LSA会用该Token, 否则就继承父进程Token进行运行\) 33 | 34 | Windows Access Token分两种: 35 | 36 | 1. 主令牌(Primary token) 37 | 2. 模拟令牌(Impersonation token) 38 | 39 | 每个进程都有一个主要令牌,用于描述与该进程关联的用户帐户的安全上下文。默认情况下,当进程的线程与安全对象进行交互时,系统使用主令牌。 40 | 41 | 此外,线程可以模拟客户端帐户。模拟允许线程使用客户端的安全上下文与安全对象进行交互。模拟客户端的线程同时具有主令牌和模拟令牌。_(出现这种情况是因为服务操作是在寄宿进程中执行,在默认的情况下,服务操作是否具有足够的权限访问某个资源(比如文件)取决于执行寄宿进程Windows帐号的权限设置,而与作为客户端的Windows帐号无关。在有多情况下,我们希望服务操作执行在基于客户端的安全上下文中执行,以解决执行服务进行的帐号权限不足的问题。简单来说就是我们希望不同客户端来访问服务时,服务可以模拟客户端的身份去访问服务,而不是用自己的主进程Token身份去访问。)_ 42 | 43 | 使用`OpenProcessToken`函数可检索进程的主令牌的句柄。使用`OpenThreadToken`函数检索线程的模拟令牌的句柄。 44 | 45 | 给出一个C++代码示例来看看如何使用API,这段代码主要用于查看当前运行的账户是否在Administrators组内。 46 | 47 | ```text 48 | C++ 49 | // ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 50 | // 51 | 52 | #include 53 | #include 54 | #include 55 | 56 | bool is_administrator() { 57 | HANDLE access_token; 58 | DWORD buffer_size = 0; 59 | PSID admin_SID; 60 | TOKEN_GROUPS* group_token = NULL; 61 | SID_IDENTIFIER_AUTHORITY NT_authority = SECURITY_NT_AUTHORITY; 62 | 63 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &access_token)) 64 | return false; 65 | 66 | GetTokenInformation( 67 | access_token, 68 | TokenGroups, 69 | group_token, 70 | 0, 71 | &buffer_size 72 | ); 73 | 74 | std::vector buffer(buffer_size); 75 | 76 | group_token = 77 | reinterpret_cast(&buffer[0]); 78 | 79 | bool succeeded = GetTokenInformation( 80 | access_token, 81 | TokenGroups, 82 | group_token, 83 | buffer_size, 84 | &buffer_size 85 | ); 86 | 87 | CloseHandle(access_token); 88 | if (!succeeded) 89 | return false; 90 | 91 | if (!AllocateAndInitializeSid( 92 | &NT_authority, 93 | 2, 94 | SECURITY_BUILTIN_DOMAIN_RID, 95 | DOMAIN_ALIAS_RID_ADMINS, 96 | 0, 0, 0, 0, 0, 0, 97 | &admin_SID 98 | )) 99 | { 100 | return false; 101 | } 102 | 103 | bool found = false; 104 | for (int i = 0; !found && i < group_token->GroupCount; i++) 105 | found = EqualSid(admin_SID, group_token->Groups[i].Sid); 106 | FreeSid(admin_SID); 107 | return found; 108 | } 109 | 110 | int main() 111 | { 112 | bool ret; 113 | ret = is_administrator(); 114 | if (ret) { 115 | printf("Yes, you are administrator!"); 116 | } 117 | } 118 | ``` 119 | 120 | 其他的API还有很多,可以使用以下功能来操作访问令牌。 121 | 122 | | 函数 | 描述 | 123 | | :---: | :---: | 124 | | [**AdjustTokenGroups**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokengroups) | 更改访问令牌中的组信息。 | 125 | | [**AdjustTokenPrivileges**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-adjusttokenprivileges) | 启用或禁用访问令牌中的特权。它不会授予新特权或撤销现有特权。 | 126 | | [**CheckTokenMembership**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-checktokenmembership) | 确定是否在指定的访问令牌中启用了指定的SID。 | 127 | | [**CreateRestrictedToken**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-createrestrictedtoken) | 创建一个新令牌,它是现有令牌的受限版本。受限令牌可以具有禁用的SID、已删除的特权以及受限的SID列表。 | 128 | | [**DuplicateToken**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-duplicatetoken) | 创建一个新的模拟令牌,该令牌复制现有令牌。 | 129 | | [**DuplicateTokenEx**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-duplicatetokenex) | 创建一个新的主要令牌或模拟令牌,该令牌可复制现有令牌。 | 130 | | [**GetTokenInformation**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-gettokeninformation) | 检索有关令牌的信息。 | 131 | | [**IsTokenRestricted**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-istokenrestricted) | 确定令牌是否具有限制SID列表。 | 132 | | [**OpenProcessToken**](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocesstoken) | 检索进程的主要访问令牌的句柄。 | 133 | | [**OpenThreadToken**](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openthreadtoken) | 检索线程的模拟访问令牌的句柄。 | 134 | | [**SetThreadToken**](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadtoken) | 分配或删除线程的模拟令牌。 | 135 | | [**SetTokenInformation**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-settokeninformation) | 更改令牌的所有者、主要组或默认DACL。 | 136 | 137 | 访问令牌功能使用以下结构来描述访问令牌的各个部分: 138 | 139 | | 结构体 | 描述 | 140 | | :---: | :---: | 141 | | [**TOKEN\_CONTROL**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_control) | 标识访问令牌的信息。 | 142 | | [**TOKEN\_DEFAULT\_DACL**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_default_dacl) | 系统在线程创建的新对象的安全描述符中使用的默认DACL。 | 143 | | [**TOKEN\_GROUPS**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_groups) | 指定访问令牌中的SID和组SID的属性。 | 144 | | [**TOKEN\_OWNER**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_owner) | 新对象的安全描述符的默认所有者SID。 | 145 | | [**TOKEN\_PRIMARY\_GROUP**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_primary_group) | 新对象的安全描述符的默认主要组SID。 | 146 | | [**TOKEN\_PRIVILEGES**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_privileges) | 与访问令牌关联的特权。还确定是否启用了特权。 | 147 | | [**TOKEN\_SOURCE**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_source) | 访问令牌的来源。 | 148 | | [**TOKEN\_STATISTICS**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_statistics) | 与访问令牌关联的统计信息。 | 149 | | [**TOKEN\_USER**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ns-winnt-token_user) | 与访问令牌关联的用户的SID。 | 150 | 151 | 访问令牌功能使用以下枚举类型: 152 | 153 | | 枚举类型 | 指定 | 154 | | :---: | :---: | 155 | | [**TOKEN\_INFORMATION\_CLASS**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ne-winnt-token_information_class) | 标识正在设置或从访问令牌检索的信息的类型。 | 156 | | [**TOKEN\_TYPE**](https://docs.microsoft.com/en-us/windows/desktop/api/Winnt/ne-winnt-token_type) | 将访问令牌标识为主要令牌或模拟令牌。 | 157 | 158 | ### **受限令牌** 159 | 160 | 一个常见的受限令牌如下图所示,这是一个未过UAC的用户,通常来说Windows在启动时LSA将尝试识别用户是否是特权组的成员,或者是否已使用与IsTokenRestricted函数类似的功能授予敏感特权。存在限制的SID将生成低特权的新访问令牌。 161 | 162 | ![低特权用户](.gitbook/assets/image%20%287%29.png) 163 | 164 | 成为管理员之后便会增加大量权限: 165 | 166 | ![管理员特权](.gitbook/assets/image%20%283%29.png) 167 | 168 | 也可以使用Process Explorer查看进安全信息: 169 | 170 | ![Process Explorer查看进程内容](.gitbook/assets/image%20%286%29.png) 171 | 172 | 受限令牌是已由`CreateRestrictedToken`函数修改的主令牌或模拟访问令牌。在受限令牌的安全上下文中运行的进程或模拟线程在访问安全对象或执行特权操作方面的能力受到限制。 `CreateRestrictedToken`函数可以通过以下方式限制令牌: 173 | 174 | * 从令牌中删除某些特权。 175 | * 将“仅拒绝”属性应用于令牌中的SID,以便它们不能用于访问受保护的对象。(相关内容可以产看下一节的SID属性) 176 | * 限制SID列表,这可以限制受限令牌拥有者对安全对象的访问。 177 | 178 | 当系统检查令牌对安全对象的访问时,系统将使用限制SID列表。当受限制的进程或线程尝试访问安全对象时,系统执行两项访问检查:一项使用令牌启用的SID,另一项使用限制SID列表。仅当两个访问检查都允许所请求的访问权限时,才授予访问权限。 179 | 180 | 可以在对`CreateProcessAsUser`函数的调用中使用受限制的主令牌。通常调用`CreateProcessAsUser`的进程必须具有`SE_ASSIGNPRIMARYTOKEN_NAME`特权,该特权通常仅由系统代码或`LocalSystem`帐户中运行的服务保留。但是,如果`CreateProcessAsUser`调用指定了调用者主令牌的受限令牌,则不需要此特权。这使普通应用程序可以创建受限进程。 181 | 182 | ![SE\_ASSIGNPRIMARYTOKEN\_NAME特权](.gitbook/assets/image%20%289%29.png) 183 | 184 | 还可以在`ImpersonateLoggedOnUser`函数中使用受限制的主要或模拟令牌。 185 | 186 | 若要确定令牌是否具有限制SID列表,可以调用`IsTokenRestricted`函数。 187 | 188 | 注意:使用受限令牌的应用程序应在默认桌面以外的其他桌面上运行受限应用程序, 防止受限制的应用程序使用`SendMessage`或`PostMessage`攻击默认桌面上不受限制的应用程序。 189 | 190 | ### **Access Token中的SID属性** 191 | 192 | 访问令牌中的每个用户和组安全标识符(SID)具有一组属性,这些属性控制系统在访问检查中如何使用SID。下表列出了控制访问检查的属性。 193 | 194 | | 属性 | 描述 | 195 | | :---: | :---: | 196 | | SE\_GROUP\_ENABLED | 启用具有此属性的SID进行访问检查。当系统执行访问检查时,它将检查适用于访问令牌中已启用的SID之一的允许访问和拒绝访问的访问控制项(ACE)。除非设置了`SE_GROUP_USE_FOR_DENY_ONLY`属性,否则在访问检查期间将忽略不具有此属性的SID。 | 197 | | SE\_GROUP\_USE\_FOR\_DENY\_ONLY | 具有此属性的SID是仅拒绝的SID。当系统执行访问检查时,它会检查适用于SID的拒绝访问的ACE,但是会忽略SID允许访问的ACE。如果设置了此属性,则不会设置SE\_GROUP\_ENABLED属性,并且无法重新启用SID | 198 | 199 | 要设置或清除组SID的`SE_GROUP_ENABLED`属性,可使用`AdjustTokenGroups`函数。不能禁用具有`SE_GROUP_MANDATORY`属性的组SID。不能使用`AdjustTokenGroups`禁用访问令牌的用户SID。 200 | 201 | 若要确定令牌中是否启用了SID,即它是否具有`SE_GROUP_ENABLED`属性,可以调用`CheckTokenMembership`函数。 202 | 203 | 若要设置SID的`SE_GROUP_USE_FOR_DENY_ONLY`属性,可以在调用`CreateRestrictedToken`函数时指定的拒绝专用SID列表中包含的该SID。 `CreateRestrictedToken`可以将`SE_GROUP_USE_FOR_DENY_ONLY`属性应用于任何SID,包括用户SID和具有`SE_GROUP_MANDATORY`属性的组SID。但不能从SID中删除仅拒绝属性,也不能使用`AdjustTokenGroups`在仅拒绝SID上设置`SE_GROUP_ENABLED`属性。 204 | 205 | 要获取SID的属性,可以使用`TokenGroups`值调用`GetTokenInformation`函数。该函数返回一个`SID_AND_ATTRIBUTES`结构数组,该结构标识组SID及其属性。 206 | 207 | ### **访问令牌对象的访问权限** 208 | 209 | 除非应用程序有权更改对象的访问控制列表,否则该应用程序不能更改该对象的访问控制列表。这些权限由对象的访问令牌中的安全描述符控制。有关安全性的更多信息,请参见访问[控制模型](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-model)。 210 | 211 | 要获取或设置访问令牌的安全描述符,请调用`GetKernelObjectSecurity`和`SetKernelObjectSecurity`函数。 212 | 213 | 当调用`OpenProcessToken`或`OpenThreadToken`函数以获取访问令牌的句柄时,系统将根据令牌的安全描述符中的DACL检查请求的访问权限。 214 | 215 | 以下是访问令牌对象的有效访问权限: 216 | 217 | * `DELETE`,`READ_CONTROL`,`WRITE_DAC`和`WRITE_OWNER`标准访问权限。访问令牌不支持`SYNCHRONIZE`标准访问权限。 218 | * 获得或设置对象的安全描述符中的`SACL`的`ACCESS_SYSTEM_SECURITY`权限。 219 | * 下表列出了访问令牌的特定访问权限: 220 | * | 值 | 含义 | 221 | | :---: | :---: | 222 | | TOKEN\_ADJUST\_DEFAULT | 更改访问令牌的默认所有者,主要组或DACL是必需的。 | 223 | | TOKEN\_ADJUST\_GROUPS | 需要在访问令牌中调整组的属性 | 224 | | TOKEN\_ADJUST\_PRIVILEGES | 启用或禁用访问令牌中的特权 | 225 | | TOKEN\_ADJUST\_SESSIONID | 调整访问令牌的会话ID。必须具有`SE_TCB_NAME`特权。 | 226 | | TOKEN\_ASSIGN\_PRIMARY | 将主令牌附加到进程。要完成此任务,还需要`SE_ASSIGNPRIMARYTOKEN_NAME`特权。 | 227 | | TOKEN\_DUPLICATE | 复制访问令牌 | 228 | | TOKEN\_EXECUTE | 结合`STANDARD_RIGHTS_EXECUTE`和`TOKEN_IMPERSONATE` | 229 | | TOKEN\_IMPERSONATE | 将模拟访问令牌附加到进程 | 230 | | TOKEN\_QUERY | 查询访问令牌 | 231 | | TOKEN\_QUERY\_SOURCE | 查询访问令牌的来源 | 232 | | TOKEN\_READ | 结合`STANDARD_RIGHTS_READ`和`TOKEN_QUERY` | 233 | | TOKEN\_WRITE | 合并`STANDARD_RIGHTS_WRITE`,`TOKEN_ADJUST_PRIVILEGES`,`TOKEN_ADJUST_GROUPS`和`TOKEN_ADJUST_DEFAULT` | 234 | | TOKEN\_ALL\_ACCESS | 合并令牌的所有可能的访问权限 | 235 | 236 | ## \*\*\*\* 237 | 238 | ## \*\*\*\* 239 | 240 | -------------------------------------------------------------------------------- /ace-strings.md: -------------------------------------------------------------------------------- 1 | # (二)ACE字符串 2 | 3 | ## ACE字符串 4 | 5 | 安全描述符定义语言(SDDL)在安全描述符字符串的DACL和SACL组件中使用ACE字符串。 如“安全描述符字符串格式”示例所示,安全描述符字符串中的每个ACE都用括号括起来。 ACE的字段按以下顺序排列,并用分号(;)分隔 6 | 7 | 语法:`ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)` 8 | 9 | 范围: 10 | 11 | **ace\_type:ACE的类型** 12 | 13 | 一个字符串,指示ACE\_HEADER结构的AceType成员的值。 ACE类型字符串可以是Sddl.h中定义的以下字符串之一。 14 | 15 | | ACE 类型字符串 | Sddl.h中的常量 | Ace类型的值 | 16 | | :--- | :--- | :--- | 17 | | "A" | SDDL\_ACCESS\_ALLOWED | ACCESS\_ALLOWED\_ACE\_TYPE | 18 | | "D" | SDDL\_ACCESS\_DENIED | ACCESS\_DENIED\_ACE\_TYPE | 19 | | "OA" | SDDL\_OBJECT\_ACCESS\_ALLOWED | ACCESS\_ALLOWED\_OBJECT\_ACE\_TYPE | 20 | | "OD" | SDDL\_OBJECT\_ACCESS\_DENIED | ACCESS\_DENIED\_OBJECT\_ACE\_TYPE | 21 | | "AU" | SDDL\_AUDIT | SYSTEM\_AUDIT\_ACE\_TYPE | 22 | | "AL" | SDDL\_ALARM | SYSTEM\_ALARM\_ACE\_TYPE | 23 | | "OU" | SDDL\_OBJECT\_AUDIT | SYSTEM\_AUDIT\_OBJECT\_ACE\_TYPE | 24 | | "OL" | SDDL\_OBJECT\_ALARM | SYSTEM\_ALARM\_OBJECT\_ACE\_TYPE | 25 | | "ML" | SDDL\_MANDATORY\_LABEL | SYSTEM\_MANDATORY\_LABEL\_ACE\_TYPE | 26 | | "XA" | SDDL\_CALLBACK\_ACCESS\_ALLOWED | ACCESS\_ALLOWED\_CALLBACK\_ACE\_TYPE**Windows Vista and Windows Server 2003:** Not available. | 27 | | "XD" | SDDL\_CALLBACK\_ACCESS\_DENIED | ACCESS\_DENIED\_CALLBACK\_ACE\_TYPE**Windows Vista and Windows Server 2003:** Not available. | 28 | | "RA" | SDDL\_RESOURCE\_ATTRIBUTE | SYSTEM\_RESOURCE\_ATTRIBUTE\_ACE\_TYPE**Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003:** Not available. | 29 | | "SP" | SDDL\_SCOPED\_POLICY\_ID | SYSTEM\_SCOPED\_POLICY\_ID\_ACE\_TYPE**Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003:** Not available. | 30 | | "XU" | SDDL\_CALLBACK\_AUDIT | SYSTEM\_AUDIT\_CALLBACK\_ACE\_TYPE**Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003:** Not available. | 31 | | "ZA" | SDDL\_CALLBACK\_OBJECT\_ACCESS\_ALLOWED | ACCESS\_ALLOWED\_CALLBACK\_ACE\_TYPE**Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003:** Not available. | 32 | 33 | **ace\_flags标志位** 34 | 35 | 一个字符串,指示`ACE_HEADER`结构的`AceFlags`成员的值。 ACE标志字符串可以是Sddl.h中定义的以下字符串的串联。 36 | 37 | | ACE 标志字符串 | Sddl.h中的常量 | Ace标志值 | 38 | | :--- | :--- | :--- | 39 | | "CI" | SDDL\_CONTAINER\_INHERIT | CONTAINER\_INHERIT\_ACE | 40 | | "OI" | SDDL\_OBJECT\_INHERIT | OBJECT\_INHERIT\_ACE | 41 | | "NP" | SDDL\_NO\_PROPAGATE | NO\_PROPAGATE\_INHERIT\_ACE | 42 | | "IO" | SDDL\_INHERIT\_ONLY | INHERIT\_ONLY\_ACE | 43 | | "ID" | SDDL\_INHERITED | INHERITED\_ACE | 44 | | "SA" | SDDL\_AUDIT\_SUCCESS | SUCCESSFUL\_ACCESS\_ACE\_FLAG | 45 | | "FA" | SDDL\_AUDIT\_FAILURE | FAILED\_ACCESS\_ACE\_FLAG | 46 | 47 | 一个字符串,指示`ACE_HEADER`结构的`AceFlags`成员的值。 ACE标志字符串可以是`Sddl.h`中定义的以下字符串的串联。 48 | 49 | **rights:权限** 50 | 51 | 一个字符串,指示由ACE控制的访问权限。该字符串可以是访问权限的十六进制字符串表示形式,例如“ 0x7800003F”,也可以是以下字符串的串联形式。 52 | 53 | _通用访问权限_ 54 | 55 | | 访问权限字符串 | Sddl.h中的常量 | 访问权限值 | 56 | | :--- | :--- | :--- | 57 | | "GA" | SDDL\_GENERIC\_ALL | GENERIC\_ALL | 58 | | "GR" | SDDL\_GENERIC\_READ | GENERIC\_READ | 59 | | "GW" | SDDL\_GENERIC\_WRITE | GENERIC\_WRITE | 60 | | "GX" | SDDL\_GENERIC\_EXECUTE | GENERIC\_EXECUTE | 61 | 62 | _标准访问权限_ 63 | 64 | | 访问权限字符串 | Sddl.h中的常量 | 访问权限值 | 65 | | :--- | :--- | :--- | 66 | | "RC" | SDDL\_READ\_CONTROL | READ\_CONTROL | 67 | | "SD" | SDDL\_STANDARD\_DELETE | DELETE | 68 | | "WD" | SDDL\_WRITE\_DAC | WRITE\_DAC | 69 | | "WO" | SDDL\_WRITE\_OWNER | WRITE\_OWNER | 70 | 71 | _目录服务对象访问权限_ 72 | 73 | | 访问权限字符串 | Sddl.h中的常量 | 访问权限值 | 74 | | :--- | :--- | :--- | 75 | | "RP" | SDDL\_READ\_PROPERTY | ADS\_RIGHT\_DS\_READ\_PROP | 76 | | "WP" | SDDL\_WRITE\_PROPERTY | ADS\_RIGHT\_DS\_WRITE\_PROP | 77 | | "CC" | SDDL\_CREATE\_CHILD | ADS\_RIGHT\_DS\_CREATE\_CHILD | 78 | | "DC" | SDDL\_DELETE\_CHILD | ADS\_RIGHT\_DS\_DELETE\_CHILD | 79 | | "LC" | SDDL\_LIST\_CHILDREN | ADS\_RIGHT\_ACTRL\_DS\_LIST | 80 | | "SW" | SDDL\_SELF\_WRITE | ADS\_RIGHT\_DS\_SELF | 81 | | "LO" | SDDL\_LIST\_OBJECT | ADS\_RIGHT\_DS\_LIST\_OBJECT | 82 | | "DT" | SDDL\_DELETE\_TREE | ADS\_RIGHT\_DS\_DELETE\_TREE | 83 | | "CR" | SDDL\_CONTROL\_ACCESS | ADS\_RIGHT\_DS\_CONTROL\_ACCESS | 84 | 85 | _档案存取权_ 86 | 87 | | 访问权限字符串 | Sddl.h中的值 | 访问权限值 | 88 | | :--- | :--- | :--- | 89 | | "FA" | SDDL\_FILE\_ALL | FILE\_ALL\_ACCESS | 90 | | "FR" | SDDL\_FILE\_READ | FILE\_GENERIC\_READ | 91 | | "FW" | SDDL\_FILE\_WRITE | FILE\_GENERIC\_WRITE | 92 | | "FX" | SDDL\_FILE\_EXECUTE | FILE\_GENERIC\_EXECUTE | 93 | 94 | _注册表项访问权限_ 95 | 96 | | 访问权限字符串 | Sddl.h中的常量 | 访问权限值 | 97 | | :--- | :--- | :--- | 98 | | "KA" | SDDL\_KEY\_ALL | KEY\_ALL\_ACCESS | 99 | | "KR" | SDDL\_KEY\_READ | KEY\_READ | 100 | | "KW" | SDDL\_KEY\_WRITE | KEY\_WRITE | 101 | | "KX" | SDDL\_KEY\_EXECUTE | KEY\_EXECUTE | 102 | 103 | _强制性标签权利_ 104 | 105 | | 访问权限字符串 | Sddl.h中的值 | 访问权限值 | 106 | | :--- | :--- | :--- | 107 | | "NR" | SDDL\_NO\_READ\_UP | SYSTEM\_MANDATORY\_LABEL\_NO\_READ\_UP | 108 | | "NW" | SDDL\_NO\_WRITE\_UP | SYSTEM\_MANDATORY\_LABEL\_NO\_WRITE\_UP | 109 | | "NX" | SDDL\_NO\_EXECUTE\_UP | SYSTEM\_MANDATORY\_LABEL\_NO\_EXECUTE\_UP | 110 | 111 | **object\_guid** 112 | 113 | GUID的字符串表示形式,它表示特定于对象的ACE结构(例如`ACCESS_ALLOWED_OBJECT_ACE`)的`ObjectType`成员的值。 GUID字符串使用`UuidToString`函数返回的格式。 114 | 115 | 下表列出了一些常用的对象GUID。 116 | 117 | | Rights and GUID | Permission | 118 | | :--- | :--- | 119 | | CR;ab721a53-1e2f-11d0-9819-00aa0040529b | Change password | 120 | | CR;00299570-246d-11d0-a768-00aa006e0529 | Reset password | 121 | 122 | **inherit\_object\_guid** 123 | 124 | GUID的字符串表示形式,它指示特定于对象的ACE结构的`InheritedObjectType`成员的值。 GUID字符串使用`UuidToString`格式。 125 | 126 | **account\_sid** 127 | 128 | 标识ACE受托者的SID字符串。 129 | 130 | **resource\_attribute** 131 | 132 | 可选: resource\_attribute仅用于资源ACE,并且是可选的。指示数据类型的字符串。资源属性ace数据类型可以是Sddl.h中定义的以下数据类型之一。 133 | 134 | 资源属性中的“#”符号与“ 0”同义。例如,`D:AI(XA;OICI;FA;;;WD;(OctetStringType==#1#2#3##))` 等同于`D:AI(XA;OICI;FA;;;WD;(OctetStringType==#01020300))`. 135 | 136 | **Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista and Windows Server 2003:** 资源属性不可用 137 | 138 | | ace类型字符串资源属性 | Sddl.h中的常量 | 数据类型 | 139 | | :--- | :--- | :--- | 140 | | "TI" | SDDL\_INT | Signed integer | 141 | | "TU" | SDDL\_UINT | Unsigned integer | 142 | | "TS" | SDDL\_WSTRING | Wide string | 143 | | "TD" | SDDL\_SID | SID | 144 | | "TX" | SDDL\_BLOB | Octet string | 145 | | "TB" | SDDL\_BOOLEAN | Boolean | 146 | 147 | 以下示例显示了允许访问的ACE的ACE字符串。它不是特定于对象的ACE,因此在`object_guid`和`Inherited_object_guid`字段中没有任何信息。 `ace_flags`字段也为空,表示未设置任何ACE标志。 148 | 149 | ```cpp 150 | (A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-1-0) 151 | ``` 152 | 153 | 上面显示的ACE字符串描述了以下ACE信息。 154 | 155 | ```cpp 156 | AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE) 157 | AceFlags: 0x00 158 | Access Mask: 0x100e003f 159 | READ_CONTROL 160 | WRITE_DAC 161 | WRITE_OWNER 162 | GENERIC_ALL 163 | Other access rights(0x0000003f) 164 | Ace Sid : (S-1-1-0) 165 | ``` 166 | 167 | 下面的示例显示了一个文件,该文件使用Windows的资源声明和“结构化查询语言(SQL)”将“保密性”设置为“高业务影响”。 168 | 169 | ```cpp 170 | (RA;CI;;;;S-1-1-0; ("Project",TS,0,"Windows","SQL")) 171 | (RA;CI;;;;S-1-1-0; ("Secrecy",TU,0,3)) 172 | ``` 173 | 174 | 上面显示的ACE字符串描述了以下ACE信息。 175 | 176 | ```cpp 177 | AceType: 0x12 (SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE) 178 | AceFlags: 0x1 (SDDL_CONTAINER_INHERIT) 179 | Access Mask: 0x0 180 | Ace Sid : (S-1-1-0) 181 | Resource Attributes: Project has the strings Windows and SQL, Secrecy has the unsigned int value of 3 182 | ``` 183 | 184 | ## 185 | 186 | -------------------------------------------------------------------------------- /ba-qi-ta.md: -------------------------------------------------------------------------------- 1 | # (八)其他 2 | 3 | ## 访问控制如何工作 4 | 5 | ![](.gitbook/assets/image%20%282%29.png) 6 | 7 | 当线程尝试访问安全对象时,系统会授予或拒绝访问。如果对象没有任意访问控制列表(DACL),则系统授予访问权限;否则,系统将授予访问权限。否则,系统将在对象的DACL中查找适用于该线程的访问控制项(ACE)。对象的DACL中的每个ACE都指定受托者允许或拒绝的访问权限,可以是用户帐户、组帐户或登录会话。 8 | 9 | **DACLs** 10 | 11 | 系统将每个ACE中的受托者与线程的访问令牌中标识的受托者进行比较。访问令牌包含安全标识符(SID),用于标识用户和用户所属的组帐户。令牌还包含用于标识当前登录会话的登录SID。在访问检查期间,系统将忽略未启用的组SID。有关启用,禁用和仅拒绝SID的更多信息,请参阅访问令牌中的SID属性。 12 | 13 | 通常,系统使用请求访问的线程的主要访问令牌。但是,如果线程模拟其他用户,则系统将使用线程的模拟令牌。 14 | 15 | 系统依次检查每个ACE,直到发生以下事件之一: 16 | 17 | * 拒绝访问的ACE明确拒绝对线程访问令牌中列出的一个受托者的任何请求的访问权限。 18 | * 线程的访问令牌中列出的针对受托者的一个或多个允许访问的ACE明确授予所有请求的访问权限。 19 | * 已检查所有ACE,并且仍然存在至少一个未明确允许的请求访问权限,在这种情况下,访问被隐式拒绝。 20 | 21 | 下图显示了对象的DACL如何允许访问一个线程而拒绝访问另一个线程。 22 | 23 | ![dacl that grants different access rights to different threads](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/accctrl1.png) 24 | 25 | 对于线程A,系统将读取ACE 1并立即拒绝访问,因为拒绝访问的ACE适用于线程访问令牌中的用户。在这种情况下,系统将不检查ACE 2和ACE3。对于线程B,ACE 1不适用,因此系统进入允许写入访问的ACE 2和允许读取和执行访问的ACE 3。 26 | 27 | 因为当明确授予或拒绝所请求的访问权限时系统会停止检查ACE,所以DACL中ACE的顺序很重要。请注意,如果示例中的ACE顺序不同,则系统可能已授予访问线程A的权限。对于系统对象,操作系统在DACL中定义了ACE的首选顺序。 28 | 29 | ## 线程与安全对象之间的交互 30 | 31 | 当线程尝试使用安全对象时,系统会在允许线程继续进行之前执行访问检查。在访问检查中,系统将线程访问令牌中的安全信息与对象的安全描述符中的安全信息进行比较。 32 | 33 | * 访问令牌包含安全标识符(SID),用于标识与线程关联的用户。 34 | * 安全描述符标识对象的所有者,并包含一个自由访问控制列表(DACL)。 DACL包含访问控制项(ACE),每个访问控制项都指定对特定用户或组允许或拒绝的访问权限。 35 | 36 | 系统检查对象的DACL,从线程的访问令牌中查找适用于用户的ACE和组SID。系统将检查每个ACE,直到授予访问权限或拒绝访问为止,或者直到不再有要检查的ACE。可以想象,访问控制列表(ACL)可以具有多个应用于令牌的SID的ACE。并且,如果发生这种情况,则会累积每个ACE授予的访问权限。例如,如果一个ACE授予对组的读访问权限,而另一个ACE授予对组成员的用户的写访问权限,则该用户可以同时具有对该对象的读和写访问权限。 37 | 38 | 下图显示了这些安全信息块之间的关系: 39 | 40 | ![relationships between processes, aces, and dacls](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/cssec-02.png) 41 | 42 | ## DACLs和ACEs 43 | 44 | 如果Windows对象没有任意访问控制列表(DACL),则系统允许所有人对其进行完全访问。如果对象具有DACL,则系统仅允许DACL中的访问控制项(ACE)明确允许的访问。如果DACL中没有ACE,则系统不允许访问任何人。同样,如果DACL具有允许访问有限的一组用户或组的ACE,则系统暗中拒绝访问未包括在ACE中的所有受托者。 45 | 46 | 在大多数情况下,可以使用允许访问的ACE控制对对象的访问。您无需明确拒绝访问对象。例外是当ACE允许访问组并且您要拒绝对组成员的访问时。为此,将用户拒绝访问的ACE放置在DACL中,然后放置在该组允许访问的ACE之前。请注意,ACE的顺序很重要,因为系统会按顺序读取ACE,直到允许或拒绝访问为止。用户的拒绝访问的ACE必须首先出现;否则,当系统读取该组的访问允许的ACE时,它将向受限用户授予访问权限。 47 | 48 | 下图显示了DACL,该DACL拒绝对一个用户的访问并向两个组授予访问权限。 A组的成员通过累积允许给A组的权限和允许给所有人的权限来获得读取,写入和执行访问权限。 Andrew是一个例外,尽管他是Everyone Group的成员,但拒绝访问的ACE拒绝了他的访问。![dacl that grants differing access rights based on group membership](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/accctrl1.png) 49 | 50 | ## 空DACL和空DACL(授权) 51 | 52 | 如果属于对象的安全描述符的自由访问控制列表(DACL)设置为NULL,则会创建一个空DACL。空DACL授予对请求它的任何用户的完全访问权限;不对该对象执行正常的安全检查。空的DACL不应与空的DACL混淆。空的DACL是正确分配和初始化的DACL,其中不包含访问控制项(ACE)。空的DACL不允许访问对其分配的对象。 53 | 54 | ## 允许匿名访问 55 | 56 | 默认安全策略将匿名本地访问限制为没有权限。然后,管理员可以根据需要添加或减少权限。 57 | 58 | 对于具有与所有人相同访问权限的应用程序,存在本地访问组。然后,管理员可以适当地增加或减少该组中的用户数量,该组名为Windows 2000之前的兼容访问组。 59 | 60 | -------------------------------------------------------------------------------- /er-an-quan-miao-shu-fu.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 安全描述符,与被访问对象关联。由对象所有者的SID、所属组的SID、DACL、SACL、一组控制Bit组成。 3 | --- 4 | 5 | # (二)安全描述符(SD) 6 | 7 | ## **安全描述符\(**Security Descriptors,SD**\)** 8 | 9 | 安全描述符是与被访问对象关联的,它含有这个对象所有者的SID,以及一个访问控制列表(ACL,Access Control List),访问控制列表又包括了DACL(Discretionary Access Control List)和SACL(System Access Control List)以及一组控制位,用于限定安全描述符含义。 10 | 11 | 安全描述符包含与安全对象关联的安全信息(安全对象是可以具有安全描述符的对象。比如文件、管道、进程、注册表等)。安全描述符由`SECURITY_DESCRIPTOR`结构及其关联的安全信息组成。安全描述符的结构体如下: 12 | 13 | ```text 14 | typedef struct _SECURITY_DESCRIPTOR { 15 | BYTE Revision; 16 | BYTE Sbz1; 17 | SECURITY_DESCRIPTOR_CONTROL Control; 18 | PSID Owner; 19 | PSID Group; 20 | PACL Sacl; 21 | PACL Dacl; 22 | } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR; 23 | ``` 24 | 25 | 安全描述符可以包括以下安全信息: 26 | 27 | * 对象的所有者和所属组的安全标识符(SID) 28 | * DACL:它里面包含零个(可以为0,之后会有详细介绍)或多个访问控制项(ACE,Access Control Entry),每个访问控制项的内容描述了允许或拒绝特定账户对这个对象执行特定操作。 29 | * SACL:主要是用于系统审计的,它的内容指定了当特定账户对这个对象执行特定操作时,记录到系统日志中。 30 | * 一组控制位,用于限定安全描述符或其单个成员的含义 31 | 32 | 应用程序不能直接操纵安全描述符的内容。 Windows API提供了用于在对象的安全描述符中设置和检索安全信息的功能。此外,还有用于创建和初始化新对象的安全描述符的函数。 33 | 34 | 在`Active Directory`对象上使用安全描述符的应用程序可以使用Windows安全功能或`Active Directory`服务接口(ADSI)提供的安全接口。有关ADSI安全接口的详细信息,我会在之后的系列中详细介绍。 35 | 36 | ### **如何使用API操作安全描述符** 37 | 38 | Windows API提供了用于获取和设置与安全对象关联的安全描述符的组件的功能。使用`GetSecurityInfo`和`GetNamedSecurityInfo`函数检索指向对象的安全描述符的指针。这些函数还可以检索指向安全描述符的各个组件的指针:DACL、SACL、owner SID和主要组SID。使用`SetSecurityInfo`和`SetNamedSecurityInfo`函数来设置对象的安全描述符的组件。`SetSecurityInfo`的结构如下所示: 39 | 40 | ```text 41 | DWORD SetSecurityInfo( 42 | HANDLE handle, 43 | SE_OBJECT_TYPE ObjectType, 44 | SECURITY_INFORMATION SecurityInfo, 45 | PSID psidOwner, 46 | PSID psidGroup, 47 | PACL pDacl, 48 | PACL pSacl 49 | ); 50 | ``` 51 | 52 | 通常,应将`GetSecurityInfo`和`SetSecurityInfo`与通过句柄标识的对象一起使用,将`SetNamedSecurityInfo`和`GetNamedSecurityInfo`与通过名称标识的对象一起使用。 53 | 54 | 要在安全描述符中获取控制信息,可调用`GetSecurityDescriptorControl`函数。要设置与自动ACE继承相关的控制位,可调用`SetSecurityDescriptorControl`函数。其他控制位由设置安全描述符组件的各种功能设置。例如,如果使用`SetSecurityInfo`更改对象的DACL,则该函数将适当地设置或清除位,以指示安全描述符是否具有DACL,是否为默认DACL,等等。另一个示例是安全描述符中包含的资源管理器(RM)控制位。这些位根据资源管理器的实现使用,并通过`GetSecurityDescriptorRMControl`和`SetSecurityDescriptorRMControl`函数进行访问。 55 | 56 | ### **创建新对象时引入安全描述符** 57 | 58 | 创建安全对象时,可以将安全描述符分配给新对象。用于创建安全对象的函数(例如`CreateFile`或`RegCreateKeyEx`)具有指向`SECURITY_ATTRIBUTES`结构的参数,该结构可以包含指向新对象的安全描述符的指针。 59 | 60 | 管理对象的系统组件或服务器可以存储指定的或默认的安全描述符,以使其成为对象的持久属性。如果对象的创建者未指定安全描述符,系统将继承或使用默认的安全信息来创建安全描述符。可以使用函数来更改对象的安全描述符中的信息。(这就是一开始讲到的默认安全描述符) 61 | 62 | 域内的对象、文件、目录、注册表项和桌面是安全对象,可以具有父对象。创建这些对象时,系统会在父对象的安全描述符中检查可继承的ACE。系统通常将任何可继承的ACE合并到新对象的安全描述符的ACL中。但是可以通过在安全描述符的控制位中设置`SE_DACL_PROTECTED`或`SE_SACL_PROTECTED`位来防止`DACL`或`SACL`继承`ACE`。 63 | 64 | #### _新对象的DACL_ 65 | 66 | 系统使用以下方式为新对象构建DACL: 67 | 68 | 1. 对象当前的DACL是来自对象创建者指定的安全描述符的DACL。除非在安全描述符的控制位中设置了`SE_DACL_PROTECTED`位,否则系统会将所有可继承的ACE合并到指定的DACL中。 69 | 2. 如果创建者未指定安全描述符,则系统将从可继承的ACE构建对象的DACL。 70 | 3. 如果未指定安全描述符,并且没有可继承的ACE,则对象的DACL是来自创建者的主令牌或模拟令牌的默认DACL。 71 | 4. 如果没有指定的、继承的或默认的DACL,则系统将创建不具有DACL的对象,从而允许所有人完全访问该对象。 72 | 73 | 系统使用不同的算法为新的Active Directory对象构建DACL。有关域的安全构建后续会有新的章节单独详细介绍。 74 | 75 | #### _新对象的SACL_ 76 | 77 | 系统使用以下方式为新对象构建SACL: 78 | 79 | 1. 对象的SACL是对象创建者指定的安全描述符中的SACL。除非在安全描述符的控制位中设置了`SE_SACL_PROTECTED`位,否则系统会将所有可继承的ACE合并到指定的SACL中。即使`SE_SACL_PROTECTED`位置已经设置,来自父对象的`SYSTEM_RESOURCE_ATTRIBUTE_ACE`和`SYSTEM_SCOPED_POLICY_ID_ACE`也将合并到新对象。 80 | 2. 如果创建者未指定安全描述符,则系统将从可继承的ACE构建对象的SACL。 81 | 3. 如果没有指定的或继承的SACL,则该对象没有SACL。 82 | 83 | 要为新对象指定SACL,对象的创建者必须启用`SE_SECURITY_NAME`特权。如果为新对象指定的SACL仅包含`SYSTEM_RESOURCE_ATTRIBUTE_ACE`,则不需要`SE_SECURITY_NAME`特权。如果对象的SACL是从继承的ACE构建的,则创建者不需要此特权。 84 | 85 | 同样,域DACL一样,系统使用不同的算法为新的Active Directory对象构建SACL。有关域的安全构建后续会有新的章节单独详细介绍。 86 | 87 | #### _新对象的所有者_ 88 | 89 | 对象的所有者隐式具有对该对象的`WRITE_DAC`访问权限。这意味着所有者可以修改对象的自由访问控制列表(DACL),从而可以控制对对象的访问。 90 | 91 | 新对象的所有者是创建过程的主令牌或模拟令牌中的默认所有者安全标识符(SID)。要获取或设置访问令牌中的默认所有者,可使用`TOKEN_OWNER`结构调用`GetTokenInformation`或`SetTokenInformation`函数。系统不允许将令牌的默认所有者设置为无效的SID,例如另一个用户帐户的SID。(如果可以就会产生越权的安全问题) 92 | 93 | 启用了`SE_TAKE_OWNERSHIP`特权的进程可以将自身设置为对象的所有者。启用了`SE_RESTORE_NAME`特权或对对象具有`WRITE_OWNER`访问权限的进程可以将任何有效的用户或组SID设置为对象的所有者。 94 | 95 | #### _新对象的主要组_ 96 | 97 | 新对象的主要组是对象创建者指定的安全描述符中的主要组。如果对象的创建者未指定主要组,则该对象的主要组是创建者的主要或模拟令牌中的默认主要组。 98 | 99 | 下面的示例为新的注册表项创建安全描述符。可以使用类似的代码为其他对象类型创建安全描述符。 100 | 101 | 1. 该示例使用两个ACE的信息填充EXPLICIT\_ACCESS结构的数组。一个ACE允许所有人读取权限;另一个ACE允许管理员完全访问。 102 | 2. 该EXPLICIT\_ACCESS结构传递给SetEntriesInAcl函数来创建的安全描述符DACL。 103 | 3. 在为安全描述符分配了内存之后,将调用InitializeSecurityDescriptor和SetSecurityDescriptorDacl函数来初始化安全描述符并附加DACL。 104 | 4. 然后将安全描述符存储在SECURITY\_ATTRIBUTES结构中,并传递给RegCreateKeyEx函数,该函数将安全描述符附加到新创建的key上。 105 | 106 | ```text 107 | #pragma comment(lib, "advapi32.lib") 108 | 109 | #include 110 | #include 111 | #include 112 | #include 113 | 114 | void main() 115 | { 116 | 117 | DWORD dwRes, dwDisposition; 118 | PSID pEveryoneSID = NULL, pAdminSID = NULL; 119 | PACL pACL = NULL; 120 | PSECURITY_DESCRIPTOR pSD = NULL; 121 | EXPLICIT_ACCESS ea[2]; 122 | SID_IDENTIFIER_AUTHORITY SIDAuthWorld = 123 | SECURITY_WORLD_SID_AUTHORITY; 124 | SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; 125 | SECURITY_ATTRIBUTES sa; 126 | LONG lRes; 127 | HKEY hkSub = NULL; 128 | 129 | // Create a well-known SID for the Everyone group. 130 | if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, 131 | SECURITY_WORLD_RID, 132 | 0, 0, 0, 0, 0, 0, 0, 133 | &pEveryoneSID)) 134 | { 135 | _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError()); 136 | goto Cleanup; 137 | } 138 | 139 | // Initialize an EXPLICIT_ACCESS structure for an ACE. 140 | // The ACE will allow Everyone read access to the key. 141 | ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); 142 | ea[0].grfAccessPermissions = KEY_READ; 143 | ea[0].grfAccessMode = SET_ACCESS; 144 | ea[0].grfInheritance= NO_INHERITANCE; 145 | ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; 146 | ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 147 | ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID; 148 | 149 | // Create a SID for the BUILTIN\Administrators group. 150 | if(! AllocateAndInitializeSid(&SIDAuthNT, 2, 151 | SECURITY_BUILTIN_DOMAIN_RID, 152 | DOMAIN_ALIAS_RID_ADMINS, 153 | 0, 0, 0, 0, 0, 0, 154 | &pAdminSID)) 155 | { 156 | _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError()); 157 | goto Cleanup; 158 | } 159 | 160 | // Initialize an EXPLICIT_ACCESS structure for an ACE. 161 | // The ACE will allow the Administrators group full access to 162 | // the key. 163 | ea[1].grfAccessPermissions = KEY_ALL_ACCESS; 164 | ea[1].grfAccessMode = SET_ACCESS; 165 | ea[1].grfInheritance= NO_INHERITANCE; 166 | ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; 167 | ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; 168 | ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID; 169 | 170 | // Create a new ACL that contains the new ACEs. 171 | dwRes = SetEntriesInAcl(2, ea, NULL, &pACL); 172 | if (ERROR_SUCCESS != dwRes) 173 | { 174 | _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError()); 175 | goto Cleanup; 176 | } 177 | 178 | // Initialize a security descriptor. 179 | pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, 180 | SECURITY_DESCRIPTOR_MIN_LENGTH); 181 | if (NULL == pSD) 182 | { 183 | _tprintf(_T("LocalAlloc Error %u\n"), GetLastError()); 184 | goto Cleanup; 185 | } 186 | 187 | if (!InitializeSecurityDescriptor(pSD, 188 | SECURITY_DESCRIPTOR_REVISION)) 189 | { 190 | _tprintf(_T("InitializeSecurityDescriptor Error %u\n"), 191 | GetLastError()); 192 | goto Cleanup; 193 | } 194 | 195 | // Add the ACL to the security descriptor. 196 | if (!SetSecurityDescriptorDacl(pSD, 197 | TRUE, // bDaclPresent flag 198 | pACL, 199 | FALSE)) // not a default DACL 200 | { 201 | _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), 202 | GetLastError()); 203 | goto Cleanup; 204 | } 205 | 206 | // Initialize a security attributes structure. 207 | sa.nLength = sizeof (SECURITY_ATTRIBUTES); 208 | sa.lpSecurityDescriptor = pSD; 209 | sa.bInheritHandle = FALSE; 210 | 211 | // Use the security attributes to set the security descriptor 212 | // when you create a key. 213 | lRes = RegCreateKeyEx(HKEY_CURRENT_USER, _T("mykey"), 0, _T(""), 0, 214 | KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition); 215 | _tprintf(_T("RegCreateKeyEx result %u\n"), lRes ); 216 | 217 | Cleanup: 218 | 219 | if (pEveryoneSID) 220 | FreeSid(pEveryoneSID); 221 | if (pAdminSID) 222 | FreeSid(pAdminSID); 223 | if (pACL) 224 | LocalFree(pACL); 225 | if (pSD) 226 | LocalFree(pSD); 227 | if (hkSub) 228 | RegCloseKey(hkSub); 229 | 230 | return; 231 | 232 | } 233 | ``` 234 | 235 | ### **安全描述符字符串** 236 | 237 | 有效的功能安全描述符包含二进制格式的安全信息。 `Windows API`提供了用于将二进制安全描述符与文本字符串相互转换的功能。字符串格式的安全描述符不起作用,但是对于存储或传输安全描述符信息很有用。若要将安全描述符转换为字符串格式,需要调用 [`ConvertSecurityDescriptorToStringSecurityDescriptor`](https://docs.microsoft.com/en-us/windows/desktop/api/Sddl/nf-sddl-convertsecuritydescriptortostringsecuritydescriptora)函数。要将字符串格式的安全描述符转换回有效的功能安全描述符,需要调用[`ConvertStringSecurityDescriptorToSecurityDescriptor`](https://docs.microsoft.com/en-us/windows/desktop/api/Sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora)函数。 238 | 239 | -------------------------------------------------------------------------------- /liu-ji-quan-ce-lve.md: -------------------------------------------------------------------------------- 1 | # (六)集权策略 2 | 3 | ## **集中授权政策** 4 | 5 | 动态访问控制(DAC)方案可对企业文件服务器方案进行集中式访问控制管理。大多数组织都希望在多个区域中控制访问权限。 6 | 7 | 例如: 8 | 9 | * 控制对敏感信息的访问,其中标记为敏感的文件将具有特定权限 10 | * 控制对包含个人身份信息(PII)的文件的访问 11 | * 根据组织保留策略限制对文档的访问 12 | 13 | 提供了几种新的授权策略抽象,以允许管理员集中定义这些策略,并通过允许分别定义和维护这些访问需求中的每一个但作为一个策略应用来简化定义过程。 14 | 15 | Windows 8中引入了两个新的`Active Directory`策略对象,即中央授权策略(cap)和中央授权策略规则(capr),以基于声明和资源属性的表达式定义和应用集中式授权策略。在使用这些对象时,管理员将capr定义为特定的授权策略,可以将其应用于具有特定属性或满足特定适用性条件的资源。例如标记为“对业务有重大影响”的文件。在Windows 8 dac表达式方面,可以为可以表达的组织中的每个所需访问控制策略定义capes,并可以标识应该应用的资源。封顶是可一起应用于资源的封顶的集合。下图显示了cap和cape的关系,以及定义和将这些对象应用于文件资源所涉及的概念性步骤。 16 | 17 | ![relationship of capes and caps](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/cap.png) 18 | 19 | ### **中央授权政策** 20 | 21 | 中央授权策略(CAP)将特定的授权规则(CAPR)收集到单个策略中。为了将特定的授权规则(CAPR)合并到组织的整体授权策略中,可以将CAPR一起引用,并应用于一组资源。这是通过将多个(通过引用)收集到CAP来完成的。一旦定义了CAP,资源管理器就可以分发它,以将组织授权策略应用于资源。 22 | 23 | CAP具有以下属性: 24 | 25 | * CAPR的集合–对现有CAPR对象的引用列表 26 | * 标识符(Sid) 27 | * 描述 28 | * 名称 29 | 30 | 在访问评估期间,对管理员启用了文件和文件夹的CAP进行了评估。在`AccessCheck`呼叫期间,CAP检查在逻辑上与任意的ACL检查结合在一起。这意味着,为了获得对CAP适用的文件的访问权限,用户需要同时具有CAP(与之关联的CAPR)和文件上的任意ACL的访问权限。 31 | 32 | CAP 例子: 33 | 34 | ```text 35 | CORPORATE-FINANCE-CAP] 36 | CAPID=S-1-5-3-4-56-45-67-123 37 | Policies=HBI-CAPE;RETENTION-CAPR 38 | ``` 39 | 40 | CAP的定义 41 | 42 | 使用ADAC(或`PowerShell`)中的新UX在`Active Directory`中创建和编辑CAP,从而允许管理员创建CAP并指定组成该CAP的一组CAPR。 43 | 44 | ### **中央授权政策规则** 45 | 46 | 中央授权策略规则(CAPR)的目的是为组织的授权策略的孤立方面提供域范围的定义。管理员定义CAPR以执行特定的授权要求之一。由于CAPR仅定义了授权策略的一个特定的期望要求,因此,与将组织的所有授权策略要求汇总到单个策略定义中相比,可以更简单地定义和理解它。 47 | 48 | CAPR具有以下属性: 49 | 50 | * 名称–管理员标识CAPR 51 | * 描述-定义CAPR的目的以及CAPR使用者可能需要的任何信息 52 | * 适用性表达 - 定义将在其中应用策略的资源或情况 53 | * ID - 用于审核CAPR更改的标识符 54 | * 有效的访问控制策略 - Windows安全描述符,其中包含定义有效授权策略的DACL 55 | * 异常表达 - 一个或多个表达式,提供了一种方法来覆盖策略并根据表达式的评估来授予对主体的访问权限 56 | * 分期政策 - 可选的Windows安全描述符,其中包含定义了建议的授权策略(访问控制条目列表)的DACL,该授权策略将针对有效策略进行测试,但未执行。如果有效策略的结果与登台策略的结果之间存在差异,则该差异将记录在审核事件日志中。 57 | * 由于分段可能会对系统性能产生不可预测的影响,因此组策略管理员必须能够选择将在其中生效分段的特定计算机。这允许在OU的大多数计算机上采用现有策略,而在其中一部分计算机上进行暂存。 58 | * P2 –如果特定计算机上的暂存造成过多的性能下降,则该计算机上的本地管理员应该能够禁用暂存。 59 | * CAP的反向链接–指向可能引用此CAPR的任何CAP的反向链接的列表。 60 | 61 | 在访问检查期间,将根据适用性表达式评估CAPR的适用性。如果CAPR适用,则需要评估CAPR是否向请求用户提供对标识资源的请求访问权限。然后,AND在逻辑上将CAPE评估的结果与资源上DACL的结果以及对资源有效的任何其他适用的CAPR进行合并。 62 | 63 | CAPRs 例子: 64 | 65 | ```text 66 | [HBI-POLICY] 67 | APPLIES-TO="(@resource.confidentiality == HBI" 68 | SD ="D:(A;;FA;;;AU;(@memberOf("Smartcard Logon")))" 69 | StagingSD = "D:(A;;FA;;;AU;(@memberOf("Smartcard Logon") AND memberOfAny(Resource.ProjectGroups)))" 70 | description="Control access to sensitive information" 71 | 72 | [RETENTION-POLICY] 73 | Applies-To="@resource.retention == true" 74 | SD ="D:(A;;;FA;;BA)(A;;FR;;;WD)" 75 | description="If the document is marked for retention, then it is read-only for everyone however Local Admins have 76 | full control to them to put them out of retention when the time comes" 77 | 78 | [TEST-FINANCE-POLICY] 79 | Applies-To="@resource.label == 'finance'" 80 | SD="D:(A;;FA;;;AU;(member_of(FinanceGroup))" 81 | description="Department: Only employees of the finance department should be able to read documents labeled as finance" 82 | ``` 83 | 84 | _CAPE定义_ 85 | 86 | 通过Active Directory管理中心(ADAC)中提供的新UX创建CAPR。在ADAC中,提供了一个新的任务选项来创建CAPR。选择此任务后,ADAC将通过对话框提示用户,要求用户输入CAPR名称和说明。提供这些功能后,将启用用于定义任何其余CAPR元素的控件。对于其余的每个CAPR元素,UX将调出ACL-UI以允许定义表达式和/或ACL。 87 | 88 | -------------------------------------------------------------------------------- /qi-an-quan-biao-shi-fu.md: -------------------------------------------------------------------------------- 1 | # (七)安全标识符(SID) 2 | 3 | ## **安全标识符** 4 | 5 | 安全标识符(SID)是用于标识受托者的可变长度的唯一值。每个帐户都有一个由权威机构(例如Windows域控制器)颁发的唯一SID,并存储在安全数据库中。每次用户登录时,系统都会从数据库中检索该用户的SID,并将其放在该用户的访问令牌中。系统使用访问令牌中的SID在与Windows安全性的所有后续交互中识别用户。当SID用作用户或组的唯一标识符时,就不能再使用它来标识另一个用户或组。 6 | 7 | 查询自己的SID可以通过:**`whoami /user`** 8 | 9 | 查询其他用户的SID可以通过WMI命令查询:**`wmic useraccount where name="%username%" get sid`** 10 | 11 | 常见的SID列表: 12 | 13 | * S-1-5-18 \(LocalSystem\) 14 | * S-1-5-19 \(LocalService\) 15 | * S-1-5-20 \(NetworkService\) 16 | * S-1-5-32-544 \(Administrators\) 17 | * S-1-5-32-545 \(Users\) 18 | * S-1-5-32-550 \(PrintOperators\) 19 | 20 | Windows安全在以下安全元素中使用SID: 21 | 22 | * 在安全描述符中标识对象和主要组的所有者 23 | * 在访问控制条目(ACE)中,标识允许,拒绝或审核访问的受托者 24 | * 在访问令牌中(AC Token),用于标识用户和该用户所属的组 25 | 26 | 除了分配给特定用户和组的唯一创建的,特定于域的SID外,还有一些知名的SID用于标识通用组和通用用户。例如,众所周知的SID(每个人和世界)标识包含所有用户的组。 27 | 28 | 大多数应用程序永远不需要使用SID。因为常见的SID的名称可能会有所不同,所以您应该使用函数从预定义的常量构建SID,而不要使用常见的SID的名称。例如,英文版本的Windows操作系统有一个众所周知的SID,名为“ `BUILTIN\Administrators`”,在国际版本的系统上可能具有不同的名称。 29 | 30 | 如果确实需要使用SID,请不要直接操作它们。而是使用以下功能。 31 | 32 | | 函数 | Description | 33 | | :--- | :--- | 34 | | [**AllocateAndInitializeSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-allocateandinitializesid) | 使用指定数量的子权限分配和初始化SID | 35 | | [**ConvertSidToStringSid**](https://docs.microsoft.com/en-us/windows/desktop/api/Sddl/nf-sddl-convertsidtostringsida) | 将SID转换为适合于显示、存储或传输的字符串格式。 | 36 | | [**ConvertStringSidToSid**](https://docs.microsoft.com/en-us/windows/desktop/api/Sddl/nf-sddl-convertstringsidtosida) | 将字符串格式的SID转换为有效的功能性SID | 37 | | [**CopySid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-copysid) | 将源SID复制到缓冲区 | 38 | | [**EqualPrefixSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-equalprefixsid) | 测试两个SID前缀值是否相等。 SID前缀是除最后一个子权限值以外的整个SID | 39 | | [**EqualSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-equalsid) | 测试两个SID是否相等。它们必须完全匹配才能被视为相等 | 40 | | [**FreeSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-freesid) | 通过使用`AllocateAndInitializeSid`函数释放先前分配的SID。 | 41 | | [**GetLengthSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getlengthsid) | 检索SID的长度 | 42 | | [**GetSidIdentifierAuthority**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsididentifierauthority) | 检索指向SID标识符权限的指针 | 43 | | [**GetSidLengthRequired**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsidlengthrequired) | 检索存储具有指定数量的子权限的SID所需的缓冲区大小 | 44 | | [**GetSidSubAuthority**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsidsubauthority) | 检索指向SID中指定的子机构的指针 | 45 | | [**GetSidSubAuthorityCount**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsidsubauthoritycount) | 检索SID中的子机构数. | 46 | | [**InitializeSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-initializesid) | 初始化SID结构 | 47 | | [**IsValidSid**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-isvalidsid) | 通过验证修订号在已知范围内并且子授权机构的数量小于最大数量,来测试SID的有效性 | 48 | | [**LookupAccountName**](https://docs.microsoft.com/en-us/windows/desktop/api/Winbase/nf-winbase-lookupaccountnamea) | 检索与指定帐户名对应的SID | 49 | | [**LookupAccountSid**](https://docs.microsoft.com/en-us/windows/desktop/api/Winbase/nf-winbase-lookupaccountsida) | 检索与指定的SID对应的帐户名 | 50 | 51 | 参考代码。示例使用OpenProcessToken和GetTokenInformation函数来获取访问令牌中的组成员身份。然后,它使用AllocateAndInitializeSid函数创建一个SID,该SID标识本地计算机管理员组的常见的SID。接下来,它使用EqualSid函数将知名SID与访问令牌中的组SID进行比较。如果令牌中存在SID,则该功能将检查SID属性以确定该令牌中SID是否已启用。 52 | 53 | ```text 54 | #include 55 | #include 56 | #pragma comment(lib, "advapi32.lib") 57 | 58 | #define MAX_NAME 256 59 | 60 | BOOL SearchTokenGroupsForSID (VOID) 61 | { 62 | DWORD i, dwSize = 0, dwResult = 0; 63 | HANDLE hToken; 64 | PTOKEN_GROUPS pGroupInfo; 65 | SID_NAME_USE SidType; 66 | char lpName[MAX_NAME]; 67 | char lpDomain[MAX_NAME]; 68 | PSID pSID = NULL; 69 | SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; 70 | 71 | // Open a handle to the access token for the calling process. 72 | 73 | if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) 74 | { 75 | printf( "OpenProcessToken Error %u\n", GetLastError() ); 76 | return FALSE; 77 | } 78 | 79 | // Call GetTokenInformation to get the buffer size. 80 | 81 | if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) 82 | { 83 | dwResult = GetLastError(); 84 | if( dwResult != ERROR_INSUFFICIENT_BUFFER ) { 85 | printf( "GetTokenInformation Error %u\n", dwResult ); 86 | return FALSE; 87 | } 88 | } 89 | 90 | // Allocate the buffer. 91 | 92 | pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize ); 93 | 94 | // Call GetTokenInformation again to get the group information. 95 | 96 | if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo, 97 | dwSize, &dwSize ) ) 98 | { 99 | printf( "GetTokenInformation Error %u\n", GetLastError() ); 100 | return FALSE; 101 | } 102 | 103 | // Create a SID for the BUILTIN\Administrators group. 104 | 105 | if(! AllocateAndInitializeSid( &SIDAuth, 2, 106 | SECURITY_BUILTIN_DOMAIN_RID, 107 | DOMAIN_ALIAS_RID_ADMINS, 108 | 0, 0, 0, 0, 0, 0, 109 | &pSID) ) 110 | { 111 | printf( "AllocateAndInitializeSid Error %u\n", GetLastError() ); 112 | return FALSE; 113 | } 114 | 115 | // Loop through the group SIDs looking for the administrator SID. 116 | 117 | for(i=0; iGroupCount; i++) 118 | { 119 | if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) ) 120 | { 121 | 122 | // Lookup the account name and print it. 123 | 124 | dwSize = MAX_NAME; 125 | if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid, 126 | lpName, &dwSize, lpDomain, 127 | &dwSize, &SidType ) ) 128 | { 129 | dwResult = GetLastError(); 130 | if( dwResult == ERROR_NONE_MAPPED ) 131 | strcpy_s (lpName, dwSize, "NONE_MAPPED" ); 132 | else 133 | { 134 | printf("LookupAccountSid Error %u\n", GetLastError()); 135 | return FALSE; 136 | } 137 | } 138 | printf( "Current user is a member of the %s\\%s group\n", 139 | lpDomain, lpName ); 140 | 141 | // Find out whether the SID is enabled in the token. 142 | if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED) 143 | printf("The group SID is enabled.\n"); 144 | else if (pGroupInfo->Groups[i].Attributes & 145 | SE_GROUP_USE_FOR_DENY_ONLY) 146 | printf("The group SID is a deny-only SID.\n"); 147 | else 148 | printf("The group SID is not enabled.\n"); 149 | } 150 | } 151 | 152 | if (pSID) 153 | FreeSid(pSID); 154 | if ( pGroupInfo ) 155 | GlobalFree( pGroupInfo ); 156 | return TRUE; 157 | } 158 | ``` 159 | 160 | ### **SID组成** 161 | 162 | SID值由SID结构信息和唯一标识受托者组成。 163 | 164 | SID由以下组件组成: 165 | 166 | * SID 版本 167 | * 一个48位的标识符授权值,用于标识发布SID的授权(一般用来代指颁发机构) 168 | * 可变数量的子机构或相对标识符(RID)值,用于相对于发布SID的机构唯一地标识受托人 169 | 170 | 标识符授权值和子权限值的组合确保即使两个不同的SID颁发机构发布相同的RID值组合,也不会有两个SID相同。每个SID颁发机构仅发出一次给定的RID。 171 | 172 | SID以二进制格式存储在SID结构中。要显示SID,可以调用`ConvertSidToStringSid`函数将二进制SID转换为字符串格式。要将SID字符串转换回有效的功能性SID,调用`ConvertStringSidToSid`函数。 173 | 174 | 这些函数对SID使用以下标准化的字符串符号,这使得可视化其组件更加简单: 175 | 176 | S-_R_-_I_-_S_… 177 | 178 | 在这种表示法中,文字字符“ S”将一系列数字标识为SID,R是SID版本号,I是标识符授权值,S…是一个或多个子授权值。 179 | 180 | 下面示例使用此表示法来显示本地Administrators组的常见的相对于域的SID: 181 | 182 | S-1-5-32-544 183 | 184 | 在此示例中,SID具有以下组件。括号中的常量是Winnt.h中定义的众所周知的标识符权限和RID值: 185 | 186 | * 修订级别1 187 | * 标识符授权值为5(`SECURITY_NT_AUTHORITY`) 188 | * 第一子授权值32(`SECURITY_BUILTIN_DOMAIN_RID`) 189 | * 第二个子权限值544(`DOMAIN_ALIAS_RID_ADMINS`) 190 | 191 | ### **常见的SID** 192 | 193 | 常见的安全标识符(SID)用来标识通用组和通用用户。例如,有一些知名的SID可以标识以下组和用户: 194 | 195 | * Everyone,这是一个包括所有用户的组。 196 | * `CREATOR_OWNER`,在可继承ACE中用作占位符。继承ACE后,系统将CREATOR\_OWNER SID替换为对象创建者的SID。 197 | * 本地计算机上内置域的Administrators组。 198 | 199 | 有通用的知名SID,这些ID在使用此安全模型的所有安全系统上都有意义,包括Windows以外的其他操作系统。此外,还有一些常见的SID仅在Windows系统上有意义。 200 | 201 | Windows API为众所周知的标识符授权和相对标识符(RID)值定义了一组常量。您可以使用这些常量来创建众所周知的SID。下面的示例结合了`SECURITY_WORLD_SID_AUTHORITY和SECURITY_WORLD_RID`常数,以显示代表所有用户(所有人或世界)的特殊组的通用众所周知的SID: 202 | 203 | S-1-1-0 204 | 205 | 本示例对SID使用字符串表示法,其中S将字符串标识为SID,前1是SID的修订级别,其余两位数字是`SECURITY_WORLD_SID_AUTHORITY`和`SECURITY_WORLD_RID`常数。 206 | 207 | 您可以使用`AllocateAndInitializeSid`函数通过将标识符授权值与最多八个子授权值组合来构建SID。例如,要确定已登录的用户是否为特定知名组的成员,请调用AllocateAndInitializeSid为该知名组构建一个SID,然后使用EqualSid函数将该SID与该用户中的组SID进行比较。 208 | 209 | 以下是一些通用的众所周知的SID。 210 | 211 | | known SID | String value | Identifies | 212 | | :--- | :--- | :--- | 213 | | Null SID | S-1-0-0 | 没有成员的群组。当SID值未知时,通常使用此方法。 | 214 | | World | S-1-1-0 | 包括所有用户的组。 | 215 | | Local | S-1-2-0 | 在本地(物理上)登录到系统的终端上登录的用户。 | 216 | | Creator Owner ID | S-1-3-0 | 由创建新对象的用户的安全标识符替换的安全标识符。此SID在可继承ACE中使用。 | 217 | | Creator Group ID | S-1-3-1 | 将由创建新对象的用户的主要组SID替换的安全标识符。在可继承ACE中使用此SID。 | 218 | 219 | 下表列出了预定义的标识符授权常量。前四个值与通用的众所周知的SID一起使用。最后一个值与Windows众所周知的SID一起使用。 220 | 221 | | Identifier authority | Value | String value | 222 | | :--- | :--- | :--- | 223 | | SECURITY\_NULL\_SID\_AUTHORITY | 0 | S-1-0 | 224 | | SECURITY\_WORLD\_SID\_AUTHORITY | 1 | S-1-1 | 225 | | SECURITY\_LOCAL\_SID\_AUTHORITY | 2 | S-1-2 | 226 | | SECURITY\_CREATOR\_SID\_AUTHORITY | 3 | S-1-3 | 227 | | SECURITY\_NT\_AUTHORITY | 5 | S-1-5 | 228 | 229 | 以下RID值与通用的众所周知的SID一起使用。标识符授权列显示标识符授权的前缀,您可以将其与RID结合使用以创建通用的知名SID 230 | 231 | | Relative identifier authority | Value | String value | 232 | | :--- | :--- | :--- | 233 | | SECURITY\_NULL\_RID | 0 | S-1-0 | 234 | | SECURITY\_WORLD\_RID | 0 | S-1-1 | 235 | | SECURITY\_LOCAL\_RID | 0 | S-1-2 | 236 | | SECURITY\_LOCAL\_LOGON\_RID | 1 | S-1-2 | 237 | | SECURITY\_CREATOR\_OWNER\_RID | 0 | S-1-3 | 238 | | SECURITY\_CREATOR\_GROUP\_RID | 1 | S-1-3 | 239 | 240 | `SECURITY_NT_AUTHORITY(S-1-5)`预定义的标识符授权产生的SID不是通用的,但仅在Windows安装上才有意义。您可以将以下RID值与`SECURITY_NT_AUTHORITY`一起使用以创建众所周知的SID。 241 | 242 | | 常量 | 字符串 | 识别 | 243 | | :--- | :--- | :--- | 244 | | SECURITY\_DIALUP\_RID | S-1-5-1 | 使用拨号调制解调器登录终端的用户。这是一个组身份 | 245 | | SECURITY\_NETWORK\_RID | S-1-5-2 | 跨网络登录的用户。这是在通过网络登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_NETWORK。 | 246 | | SECURITY\_BATCH\_RID | S-1-5-3 | 使用批处理队列工具登录的用户。这是在作为批处理作业记录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_BATCH | 247 | | SECURITY\_INTERACTIVE\_RID | S-1-5-4 | 登录进行交互操作的用户。这是在以交互方式登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_INTERACTIVE。 | 248 | | SECURITY\_LOGON\_IDS\_RID | S-1-5-5-_X_-_Y_ | 登录会话。这用于确保只有给定登录会话中的进程才能访问该会话的窗口站对象。对于每个登录会话,这些SID的X和Y值都不同。值SECURITY\_LOGON\_IDS\_RID\_COUNT是此标识符(5-X-Y)中RID的数量。 | 249 | | SECURITY\_SERVICE\_RID | S-1-5-6 | 授权作为服务登录的帐户。这是在作为服务登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_SERVICE | 250 | | SECURITY\_ANONYMOUS\_LOGON\_RID | S-1-5-7 | 匿名登录,或空会话登录 | 251 | | SECURITY\_PROXY\_RID | S-1-5-8 | 代理. | 252 | | SECURITY\_ENTERPRISE\_CONTROLLERS\_RID | S-1-5-9 | 企业控制器. | 253 | | SECURITY\_PRINCIPAL\_SELF\_RID | S-1-5-10 | 可以在用户或组对象的ACL中使用PRINCIPAL\_SELF安全标识符。在访问检查期间,系统将SID替换为对象的SID。PRINCIPAL\_SELF SID对于指定适用于继承该ACE的用户或组对象的可继承ACE很有用。这是在架构的默认_安全_描述_符_中表示创建的对象的SID的唯一方法。 | 254 | | SECURITY\_AUTHENTICATED\_USER\_RID | S-1-5-11 | 经过身份验证的用户。 | 255 | | SECURITY\_RESTRICTED\_CODE\_RID | S-1-5-12 | Restricted code. | 256 | | SECURITY\_TERMINAL\_SERVER\_RID | S-1-5-13 | Terminal Services. Automatically added to the security token of a user who logs on to a terminal server. | 257 | | SECURITY\_LOCAL\_SYSTEM\_RID | S-1-5-18 | 操作系统使用的特殊帐户。 | 258 | | SECURITY\_NT\_NON\_UNIQUE | S-1-5-21 | SIDS are not unique. | 259 | | SECURITY\_BUILTIN\_DOMAIN\_RID | S-1-5-32 | The built-in system domain. | 260 | | SECURITY\_WRITE\_RESTRICTED\_CODE\_RID | S-1-5-33 | Write restricted code. | 261 | 262 | 以下RID与每个域有关。 263 | 264 | | RID | Value | Identifies | 265 | | :--- | :--- | :--- | 266 | | DOMAIN\_ALIAS\_RID\_CERTSVC\_DCOM\_ACCESS\_GROUP | 0x0000023E | 可以使用分布式组件对象模型(DCOM)连接到证书颁发机构的用户组。 | 267 | | DOMAIN\_USER\_RID\_ADMIN | 0x000001F4 | 域中的管理用户帐户。 | 268 | | DOMAIN\_USER\_RID\_GUEST | 0x000001F5 | 域中的来宾用户帐户。没有帐户的用户可以自动登录到该帐户。 | 269 | | DOMAIN\_GROUP\_RID\_ADMINS | 0x00000200 | 域管理员组。该帐户仅存在于运行服务器操作系统的系统上。 | 270 | | DOMAIN\_GROUP\_RID\_USERS | 0x00000201 | 包含域中所有用户帐户的组。所有用户都将自动添加到该组中。 | 271 | | DOMAIN\_GROUP\_RID\_GUESTS | 0x00000202 | 域中的来宾组帐户。 | 272 | | DOMAIN\_GROUP\_RID\_COMPUTERS | 0x00000203 | 域计算机的组。域中的所有计算机都是该组的成员。 | 273 | | DOMAIN\_GROUP\_RID\_CONTROLLERS | 0x00000204 | 域控制器的组。域中的所有DC都是该组的成员。 | 274 | | DOMAIN\_GROUP\_RID\_CERT\_ADMINS | 0x00000205 | 证书发布者组。运行证书服务的计算机是该组的成员 | 275 | | DOMAIN\_GROUP\_RID\_ENTERPRISE\_READONLY\_DOMAIN\_CONTROLLERS | 0x000001F2 | 企业只读域控制器组。 | 276 | | DOMAIN\_GROUP\_RID\_SCHEMA\_ADMINS | 0x00000206 | 模式管理员组。该组的成员可以修改Active Directory架构。 | 277 | | DOMAIN\_GROUP\_RID\_ENTERPRISE\_ADMINS | 0x00000207 | 企业管理员组。该组的成员具有对Active Directory林中所有域的完全访问权限。企业管理员负责林级操作,例如添加或删除新域。 | 278 | | DOMAIN\_GROUP\_RID\_POLICY\_ADMINS | 0x00000208 | 策略管理员组。 | 279 | | DOMAIN\_GROUP\_RID\_READONLY\_CONTROLLERS | 0x00000209 | 只读域控制器组。 | 280 | | DOMAIN\_GROUP\_RID\_CLONEABLE\_CONTROLLERS | 0x0000020A | 可克隆域控制器的组 | 281 | | DOMAIN\_GROUP\_RID\_CDC\_RESERVED | 0x0000020C | 保留的CDC组 | 282 | | DOMAIN\_GROUP\_RID\_PROTECTED\_USERS | 0x0000020D | 受保护的用户组。 | 283 | | DOMAIN\_GROUP\_RID\_KEY\_ADMINS | 0x0000020E | 关键管理员组 | 284 | | DOMAIN\_GROUP\_RID\_ENTERPRISE\_KEY\_ADMINS | 0x0000020F | 企业密钥管理员组 | 285 | 286 | 以下RID用于指定强制完整性级别。 287 | 288 | | RID | Value | Identifies | 289 | | :--- | :--- | :--- | 290 | | SECURITY\_MANDATORY\_UNTRUSTED\_RID | 0x00000000 | Untrusted. | 291 | | SECURITY\_MANDATORY\_LOW\_RID | 0x00001000 | Low integrity. | 292 | | SECURITY\_MANDATORY\_MEDIUM\_RID | 0x00002000 | Medium integrity. | 293 | | SECURITY\_MANDATORY\_MEDIUM\_PLUS\_RID | SECURITY\_MANDATORY\_MEDIUM\_RID + 0x100 | Medium high integrity. | 294 | | SECURITY\_MANDATORY\_HIGH\_RID | 0X00003000 | High integrity. | 295 | | SECURITY\_MANDATORY\_SYSTEM\_RID | 0x00004000 | System integrity. | 296 | | SECURITY\_MANDATORY\_PROTECTED\_PROCESS\_RID | 0x00005000 | Protected process. | 297 | 298 | 下表提供了相对域RID的示例,您可以使用它们来为本地组(别名)形成众所周知的SID。有关本地和全局组的更多信息,请参见本地组功能和组功能。 299 | 300 | | RID | Value | String Value | Identifies | 301 | | :--- | :--- | :--- | :--- | 302 | | DOMAIN\_ALIAS\_RID\_ADMINS | 0x00000220 | S-1-5-32-544 | 用于管理域的本地组。 | 303 | | DOMAIN\_ALIAS\_RID\_USERS | 0x00000221 | S-1-5-32-545 | 代表域中所有用户的本地组 | 304 | | DOMAIN\_ALIAS\_RID\_GUESTS | 0x00000222 | S-1-5-32-546 | 代表域来宾的本地组。 | 305 | | DOMAIN\_ALIAS\_RID\_POWER\_USERS | 0x00000223 | S-1-5-32-547 | 一个本地组,用于代表希望将系统视为其个人计算机而不是多个用户的工作站的用户或一组用户。 | 306 | | DOMAIN\_ALIAS\_RID\_ACCOUNT\_OPS | 0x00000224 | S-1-5-32-548 | 仅在运行服务器操作系统的系统上存在的本地组。此本地组允许控制非管理员帐户。 | 307 | | DOMAIN\_ALIAS\_RID\_SYSTEM\_OPS | 0x00000225 | S-1-5-32-549 | 仅在运行服务器操作系统的系统上存在的本地组。该本地组执行系统管理功能,不包括安全功能。它建立网络共享,控制打印机,解锁工作站并执行其他操作。 | 308 | | DOMAIN\_ALIAS\_RID\_PRINT\_OPS | 0x00000226 | S-1-5-32-550 | 仅在运行服务器操作系统的系统上存在的本地组。此本地组控制打印机和打印队列。 | 309 | | DOMAIN\_ALIAS\_RID\_BACKUP\_OPS | 0x00000227 | S-1-5-32-551 | 一个用于控制文件备份和还原特权的分配本地组。 | 310 | | DOMAIN\_ALIAS\_RID\_REPLICATOR | 0x00000228 | S-1-5-32-552 | 一个本地组,负责将安全数据库从主域控制器复制到备份域控制器。这些帐户仅由系统使用。 | 311 | | DOMAIN\_ALIAS\_RID\_RAS\_SERVERS | 0x00000229 | S-1-5-32-553 | 代表RAS和IAS服务器的本地组。该组允许访问用户对象的各种属性。 | 312 | | DOMAIN\_ALIAS\_RID\_PREW2KCOMPACCESS | 0x0000022A | S-1-5-32-554 | 仅在运行Windows 2000 Server的系统上存在的本地组。有关更多信息,请参见允许匿名访问。 | 313 | | DOMAIN\_ALIAS\_RID\_REMOTE\_DESKTOP\_USERS | 0x0000022B | S-1-5-32-555 | 代表所有远程桌面用户的本地组。 | 314 | | DOMAIN\_ALIAS\_RID\_NETWORK\_CONFIGURATION\_OPS | 0x0000022C | S-1-5-32-556 | 代表网络配置的本地组。 | 315 | | DOMAIN\_ALIAS\_RID\_INCOMING\_FOREST\_TRUST\_BUILDERS | 0x0000022D | S-1-5-32-557 | 代表任何林信任用户的本地组。 | 316 | | DOMAIN\_ALIAS\_RID\_MONITORING\_USERS | 0x0000022E | S-1-5-32-558 | 代表所有受监视用户的本地组。 | 317 | | DOMAIN\_ALIAS\_RID\_LOGGING\_USERS | 0x0000022F | S-1-5-32-559 | 负责记录用户的本地组。 | 318 | | DOMAIN\_ALIAS\_RID\_AUTHORIZATIONACCESS | 0x00000230 | S-1-5-32-560 | 代表所有授权访问的本地组。 | 319 | | DOMAIN\_ALIAS\_RID\_TS\_LICENSE\_SERVERS | 0x00000231 | S-1-5-32-561 | 仅在运行允许终端服务和远程访问的服务器操作系统的系统上存在的本地组。 | 320 | | DOMAIN\_ALIAS\_RID\_DCOM\_USERS | 0x00000232 | S-1-5-32-562 | 一个本地组,代表可以使用分布式组件对象模型(DCOM)的用户。 | 321 | | DOMAIN\_ALIAS\_RID\_IUSERS | 0X00000238 | S-1-5-32-568 | 代表Internet用户的本地组。 | 322 | | DOMAIN\_ALIAS\_RID\_CRYPTO\_OPERATORS | 0x00000239 | S-1-5-32-569 | 一个本地组,代表对密码运算符的访问。 | 323 | | DOMAIN\_ALIAS\_RID\_CACHEABLE\_PRINCIPALS\_GROUP | 0x0000023B | S-1-5-32-571 | 表示可以缓存的主体的本地组。 | 324 | | DOMAIN\_ALIAS\_RID\_NON\_CACHEABLE\_PRINCIPALS\_GROUP | 0x0000023C | S-1-5-32-572 | 表示无法缓存的主体的本地组。 | 325 | | DOMAIN\_ALIAS\_RID\_EVENT\_LOG\_READERS\_GROUP | 0x0000023D | S-1-5-32-573 | 代表事件日志读取器的本地组。 | 326 | | DOMAIN\_ALIAS\_RID\_CERTSVC\_DCOM\_ACCESS\_GROUP | 0x0000023E | S-1-5-32-574 | 可以使用分布式组件对象模型(DCOM)连接到证书颁发机构的本地用户组。 | 327 | | DOMAIN\_ALIAS\_RID\_RDS\_REMOTE\_ACCESS\_SERVERS | 0x0000023F | S-1-5-32-575 | 代表RDS远程访问服务器的本地组。 | 328 | | DOMAIN\_ALIAS\_RID\_RDS\_ENDPOINT\_SERVERS | 0x00000240 | S-1-5-32-576 | 代表端点服务器的本地组。 | 329 | | DOMAIN\_ALIAS\_RID\_RDS\_MANAGEMENT\_SERVERS | 0x00000241 | S-1-5-32-577 | 代表管理服务器的本地组 | 330 | | DOMAIN\_ALIAS\_RID\_HYPER\_V\_ADMINS | 0x00000242 | S-1-5-32-578 | 代表hyper-v管理员的本地组 | 331 | | DOMAIN\_ALIAS\_RID\_ACCESS\_CONTROL\_ASSISTANCE\_OPS | 0x00000243 | S-1-5-32-579 | 代表访问控制辅助OPS的本地组。 | 332 | | DOMAIN\_ALIAS\_RID\_REMOTE\_MANAGEMENT\_USERS | 0x00000244 | S-1-5-32-580 | 代表远程管理用户的本地组。 | 333 | | DOMAIN\_ALIAS\_RID\_DEFAULT\_ACCOUNT | 0x00000245 | S-1-5-32-581 | 代表默认帐户的本地组。 | 334 | | DOMAIN\_ALIAS\_RID\_STORAGE\_REPLICA\_ADMINS | 0x00000246 | S-1-5-32-582 | 代表存储副本管理员的本地组。 | 335 | | DOMAIN\_ALIAS\_RID\_DEVICE\_OWNERS | 0x00000247 | S-1-5-32-583 | 代表的本地组可以为设备所有者进行预期的设置。 | 336 | 337 | `WELL_KNOWN_SID_TYPE`枚举定义了常用SID的列表。此外,安全描述符定义语言(SDDL)使用SID字符串以字符串格式引用众所周知的SID。 338 | 339 | ## 340 | 341 | -------------------------------------------------------------------------------- /quan-xian-kong-zhi-qi-ta-nei-rong.md: -------------------------------------------------------------------------------- 1 | # 3. 权限控制其他内容 2 | 3 | ### 权限 4 | 5 | 特权是帐户(例如用户帐户或组帐户)在本地计算机上执行各种与系统相关的操作(例如关闭系统,加载设备驱动程序或更改系统时间)的权利。特权与访问权限在两个方面有所不同: 6 | 7 | * 特权控制对系统资源和系统相关任务的访问,而访问权限控制对安全对象的访问。 8 | * 系统管理员为用户帐户和组帐户分配特权,而系统则根据对象的DACL中ACE中授予的访问权限来授予或拒绝对安全对象的访问。 9 | 10 | 每个系统都有一个帐户数据库,用于存储用户帐户和组帐户所拥有的特权。当用户登录时,系统会生成一个访问令牌,其中包含用户特权的列表,包括授予用户或用户所属组的特权。请注意,特权仅适用于本地计算机。域帐户在不同的计算机上可以具有不同的特权。 11 | 12 | 当用户尝试执行特权操作时,系统检查用户的访问令牌以确定该用户是否拥有必要的特权,如果是,则检查是否启用了特权。如果用户未通过这些测试,则系统不会执行该操作。 13 | 14 | 要确定访问令牌中保留的特权,请调用`GetTokenInformation`函数,该函数还指示启用了哪些特权。默认情况下,大多数特权是禁用的。 15 | 16 | Windows API定义了一组字符串常量,例如`SE_ASSIGNPRIMARYTOKEN_NAME`,以标识各种特权。这些常量在所有系统上都相同,并在`Winnt.h`中定义。有关`Windows`定义的特权的表,请参阅特权常数。但是,获取和调整访问令牌中的特权的函数使用`LUID`类型来标识特权。一台计算机的特权的`LUID`值可能会不同,而同一台计算机上的一次引导到另一台计算机也会有所不同。若要获取与字符串常量之一相对应的当前LUID,请使用`LookupPrivilegeValue`函数。使用`LookupPrivilegeName`函数将LUID转换为其相应的字符串常量。 17 | 18 | 系统提供了一组描述每个权限的显示名称。当您需要向用户显示特权说明时,这些功能很有用。使用`LookupPrivilegeDisplayName`函数可检索与特权字符串常量相对应的描述字符串。例如,在使用美国英语的系统上,`SE_SYSTEMTIME_NAME`特权的显示名称为“更改系统时间”。 19 | 20 | 您可以使用`PrivilegeCheck`函数来确定访问令牌是否持有指定的特权集。这主要用于模拟客户端的服务器应用程序。 21 | 22 | 系统管理员可以使用管理工具(例如用户管理器)来添加或删除用户帐户和组帐户的特权。管理员可以以编程方式使用本地安全机构(LSA)功能来使用特权。 `LsaAddAccountRights`和`LsaRemoveAccountRights`函数可从帐户添加或删除特权。`LsaEnumerateAccountRights`函数枚举指定帐户所拥有的特权。 `LsaEnumerateAccountsWithUserRight`函数枚举具有指定特权的帐户。 23 | 24 | ### 审核生成 25 | 26 | C2级安全性要求指定系统管理员必须能够审核与安全性有关的事件,并且对此审核数据的访问必须仅限于授权管理员。 Windows API提供了使管理员能够监视与安全性有关的事件的功能。 27 | 28 | 可保护对象的安全描述符可以具有系统访问控制列表(SACL)。 SACL包含访问控制条目(ACE),它们指定生成审核报告的访问尝试的类型。每个ACE标识一个受托者,一组访问权限和一组标志,这些标志指示系统是否为失败的访问尝试和/或成功的访问尝试生成审核消息。 29 | 30 | 系统将审核消息写入安全事件日志。有关访问安全事件日志中的记录的信息,请参阅事件日志。 31 | 32 | 要读取或写入对象的`SACL`,线程必须首先启用`SE_SECURITY_NAME`特权。有关更多信息,请参见`SACL`访问权限。 33 | 34 | ### 安全对象 35 | 36 | 安全对象是可以具有安全描述符的对象。所有命名的`Windows`对象都是安全的。一些未命名的对象(例如进程和线程对象)也可以具有安全描述符。对于大多数安全对象,可以在创建对象的函数调用中指定对象的安全描述符。例如,您可以在`CreateFile`和`CreateProcess`函数中指定安全描述符。 37 | 38 | 此外,Windows安全功能使您能够获取和设置在Windows以外的操作系统上创建的可安全对象的安全信息。 Windows安全功能还支持将安全描述符与专用的,应用程序定义的对象一起使用。有关私有安全对象的更多信息,请参见客户端/服务器访问控制。 39 | 40 | 每种类型的可保护对象都定义了自己的一组特定访问权限,并定义了自己的通用访问权限映射。有关每种安全对象的特定和通用访问权限的信息,请参阅该对象的概述。 41 | 42 | 下表显示了用于处理某些常见安全对象的安全信息的功能。 43 | 44 | | 对象类型 | 安全描述符函数 | 45 | | :--- | :--- | 46 | | [Files or directories](https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-security-and-access-rights) on an NTFS file system | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 47 | | [Named pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/named-pipe-security-and-access-rights) [Anonymous pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/anonymous-pipe-security-and-access-rights) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 48 | | [Processes](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-security-and-access-rights) [Threads](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-security-and-access-rights) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 49 | | [File-mapping objects](https://docs.microsoft.com/en-us/windows/desktop/Memory/file-mapping-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 50 | | [Access tokens](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/access-rights-for-access-token-objects) | [**SetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setkernelobjectsecurity), [**GetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getkernelobjectsecurity) | 51 | | Window-management objects \([window stations](https://docs.microsoft.com/en-us/windows/desktop/winstation/window-station-security-and-access-rights) and [desktops](https://docs.microsoft.com/en-us/windows/desktop/winstation/desktop-security-and-access-rights)\) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 52 | | [Registry keys](https://docs.microsoft.com/en-us/windows/desktop/SysInfo/registry-key-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 53 | | [Windows services](https://docs.microsoft.com/en-us/windows/desktop/Services/service-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 54 | | Local or remote printers | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 55 | | Network shares | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 56 | | [Interprocess synchronization objects](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) \(events, mutexes, semaphores, and waitable timers\) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 57 | | [Job objects](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/job-object-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 58 | 59 | ### 低层访问控制 60 | 61 | 低级安全功能可帮助您使用安全描述符,访问控制列表(ACL)和访问控制项(ACE)。 62 | 63 | 有关模型的说明,请参阅访问控制模型。 64 | 65 | | 主题 | 描述 | 66 | | :--- | :--- | 67 | | [Low-level Security Descriptor Functions](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/low-level-security-descriptor-functions) | 用于设置和检索对象的安全描述符的函数。 | 68 | | [Low-level Security Descriptor Creation](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/low-level-security-descriptor-creation) | 用于创建安全描述符以及获取和设置安全描述符的组件的函数。 | 69 | | [Absolute and Self-Relative Security Descriptors](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/absolute-and-self-relative-security-descriptors) | 用于在绝对或自相关格式之间进行检查或转换的功能。 | 70 | | [Low-level ACL and ACE Functions](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/low-level-acl-and-ace-functions) | 用于管理ACL和ACE的功能。 | 71 | 72 | #### 低级安全描述符函数 73 | 74 | 有几对低级函数,用于设置和检索对象的安全描述符。这些对中的每对仅适用于一组有限的Windows对象。例如,一对使用文件对象,另一对使用注册表项。下表显示了与不同类型的可保护对象一起使用的低级函数。 75 | 76 | | 对象类型 | 低级函数 | 77 | | :--- | :--- | 78 | | [Files](https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-security-and-access-rights) [Directories](https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-security-and-access-rights) Mailslots [Named pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/named-pipe-security-and-access-rights) | 使用`GetFileSecurity`和`SetFileSecurity`函数。这些函数使用字符串标识安全对象,而不是使用句柄。 | 79 | | [Processes](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-security-and-access-rights) [Threads](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-security-and-access-rights) [Access tokens](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/access-rights-for-access-token-objects) [File-mapping objects](https://docs.microsoft.com/en-us/windows/desktop/Memory/file-mapping-security-and-access-rights) [Semaphores](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) [Events](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) [Mutexes](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) [Waitable timers](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) | 使用 [**GetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getkernelobjectsecurity) and [**SetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-setkernelobjectsecurity) 函数. | 80 | | [Window stations](https://docs.microsoft.com/en-us/windows/desktop/winstation/window-station-security-and-access-rights) [Desktops](https://docs.microsoft.com/en-us/windows/desktop/winstation/desktop-security-and-access-rights) | 使用 [**GetUserObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/nf-winuser-getuserobjectsecurity) and [**SetUserObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/nf-winuser-setuserobjectsecurity) 函数. | 81 | | [Registry keys](https://docs.microsoft.com/en-us/windows/desktop/SysInfo/registry-key-security-and-access-rights) | 使用 [**RegGetKeySecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winreg/nf-winreg-reggetkeysecurity) and [**RegSetKeySecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winreg/nf-winreg-regsetkeysecurity) 函数. | 82 | | [Windows service objects](https://docs.microsoft.com/en-us/windows/desktop/Services/service-security-and-access-rights) | 使用 [**QueryServiceObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winsvc/nf-winsvc-queryserviceobjectsecurity) and [**SetServiceObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/Winsvc/nf-winsvc-setserviceobjectsecurity) 函数. | 83 | | Printer objects | 使用 [**PRINTER\_INFO\_2**](https://docs.microsoft.com/en-us/windows/desktop/printdocs/printer-info-2) 结构 在 [**GetPrinter**](https://docs.microsoft.com/en-us/windows/desktop/printdocs/getprinter) and [**SetPrinter**](https://docs.microsoft.com/en-us/windows/desktop/printdocs/setprinter) 函数中. | 84 | | [Network shares](https://docs.microsoft.com/en-us/windows/desktop/NetMgmt/security-requirements-for-the-network-management-functions) | 使用502级别的 [**NetShareGetInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/lmshare/nf-lmshare-netsharegetinfo) and [**NetShareSetInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/lmshare/nf-lmshare-netsharesetinfo) 函数. | 85 | | [Private objects \(objects private to the creating application\)](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/acl-based-access-control) | 使用 [**CreatePrivateObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-createprivateobjectsecurity), [**DestroyPrivateObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-destroyprivateobjectsecurity), [**GetPrivateObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-getprivateobjectsecurity) and [**SetPrivateObjectSecurity**](https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-setprivateobjectsecurity) 函数. | 86 | 87 | #### 低级安全描述符创建 88 | 89 | 低级访问控制提供了一组用于创建安全描述符以及获取和设置安全描述符的组件的功能。用于初始化和设置安全描述符的组件的低级功能仅适用于绝对格式的安全描述符。用于获取安全描述符的组件的低级功能可同时使用绝对和自相关的安全描述符。 90 | 91 | `InitializeSecurityDescriptor`函数初始化`SECURITY_DESCRIPTOR`缓冲区。初始化的安全描述符为绝对格式,没有所有者,主组,任意访问控制列表(DACL)或系统访问控制列表(SACL)。您可以使用以下低级函数来获取或设置指定安全描述符的特定组件。 92 | 93 | | 函数 | 描述 | 94 | | :--- | :--- | 95 | | [**GetSecurityDescriptorControl**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorcontrol) | 从安全描述符中检索修订和控制信息。 | 96 | | [**GetSecurityDescriptorDacl**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptordacl) | 从安全描述符中检索DACL。 | 97 | | [**GetSecurityDescriptorGroup**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorgroup) | 从安全描述符中检索主组安全标识符(SID)。 | 98 | | [**GetSecurityDescriptorLength**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorlength) | 返回安全描述符的长度。 | 99 | | [**GetSecurityDescriptorOwner**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorowner) | 从安全描述符中检索所有者SID。 | 100 | | [**GetSecurityDescriptorSacl**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorsacl) | 从安全描述符中检索SACL。 | 101 | | [**SetSecurityDescriptorDacl**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptordacl) | 将DACL放入安全描述符中,取代任何现有的DACL。 | 102 | | [**SetSecurityDescriptorGroup**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptorgroup) | 设置安全描述符的主要组SID。 | 103 | | [**SetSecurityDescriptorOwner**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptorowner) | 设置安全描述符的所有者SID。 | 104 | | [**SetSecurityDescriptorSacl**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptorsacl) | 将SACL放入安全描述符中,以取代任何现有的SACL。 | 105 | 106 | **绝对和自相关的安全描述符** 107 | 108 | 安全描述符可以采用绝对或自相关格式。以绝对格式、安全描述符包含指向其信息的指针,而不是信息本身的指针。以自相关格式、安全描述符将`SECURITY_DESCRIPTOR`结构和关联的安全信息存储在连续的内存块中。要确定安全描述符是自相关的还是绝对的,请调用`GetSecurityDescriptorControl`函数并检查`SECURITY_DESCRIPTOR_CONTROL`参数的`SE_SELF_RELATIVE`标志。您可以使用`MakeSelfRelativeSD`和`MakeAbsoluteSD`函数在这两种格式之间进行转换。 109 | 110 | 当您构建安全描述符并具有指向所有组件的指针时,例如,当所有者、组和任意ACL的默认设置可用时,绝对格式很有用。在这种情况下,您可以调用`InitializeSecurityDescriptor`函数来初始化`SECURITY_DESCRIPTOR`结构,然后调用诸如`SetSecurityDescriptorDacl`之类的函数来将ACL和SID指针分配给安全描述符。 111 | 112 | 在自相关格式中,安全描述符始终以`SECURITY_DESCRIPTOR`结构开头,但是安全描述符的其他组件可以按任何顺序跟随该结构。安全描述符的组成部分不使用内存地址,而是通过从描述符开始处的偏移量来标识的。当安全描述符必须存储在磁盘上,通过通信协议传输或复制到内存中时,此格式很有用。 113 | 114 | 除了`MakeAbsoluteSD`,所有返回安全描述符的函数都使用自相关格式。作为参数传递给函数的安全描述符可以是自相关形式,也可以是绝对形式。有关更多信息,请参阅该功能的文档。 115 | 116 | **底层ACL和ACE功能** 117 | 118 | 要使用低级功能创建访问控制列表(ACL),请为ACL分配一个缓冲区,然后通过调用`InitializeAcl`函数对其进行初始化。要将访问控制条目(ACE)添加到任意访问控制列表(DACL)的末尾,请使用`AddAccessAllowedAce`和`AddAccessDeniedAce`函数。 `AddAuditAccessAce`函数将ACE添加到系统访问控制列表(SACL)的末尾。您可以使用AddAce函数在ACL中的指定位置添加一个或多个ACE。 `AddAce`函数还允许您将可继承的ACE添加到ACL。 `DeleteAce`函数从ACL中的指定位置删除ACE。 `GetAce`函数从ACL中的指定位置检索ACE。 `FindFirstFreeAce`函数检索指向ACL中第一个空闲字节的指针。 119 | 120 | 要修改对象的安全描述符中的现有ACL,请使用`GetSecurityDescriptorDacl`或`GetSecurityDescriptorSacl`函数来获取现有ACL。您可以使用`GetAce`函数从现有ACL复制ACE。分配并初始化新的ACL后,请使用`AddAccessAllowedAce`和`AddAce`之类的功能向其添加ACE。完成新ACL的构建后,请使用`SetSecurityDescriptorDacl或SetSecurityDescriptorSacl`函数将新ACL添加到对象的安全描述符中。 121 | 122 | 您可以使用`AddAccessAllowedObjectAce`、`AddAccessDeniedObjectAce`或`AddAuditAccessObjectAce`函数将特定于对象的ACE添加到ACL的末尾。 123 | 124 | -------------------------------------------------------------------------------- /san-acl.md: -------------------------------------------------------------------------------- 1 | # (三)ACL 2 | 3 | ## **访问控制列表** 4 | 5 | ![ACL分类](.gitbook/assets/image%20%281%29.png) 6 | 7 | DACL:自主访问控制列表\(DACL\)是安全描述符中最重要的,它里面包含零个或多个访问控制项(ACE,Access Control Entry),每个访问控制项的内容描述了允许或拒绝特定账户对这个对象执行特定操作。 8 | 9 | SACL:系统访问控制列表(SACL) 主要是用于系统审计的,它的内容指定了当特定账户对这个对象执行特定操作时,记录到系统日志中。 10 | 11 | 访问控制列表(ACL)是访问控制条目(ACE)的列表。 ACL中的每个ACE都标识一个对象(通常称这个对象为受托者,受托者可以是一个用户、用户组或者是一个登陆会话),并指定允许、拒绝或审核该受托者的访问权限。可保护对象的安全描述符可以包含两种类型的ACL:DACL和SACL。 12 | 13 | DACL标识是否允许或拒绝访问安全对象。当进程尝试访问安全对象时,系统将检查该对象的DACL中的ACE,以确定是否授予对该对象的访问权限。 14 | 15 | 1. 如果对象没有DACL,则系统将授予所有人完全访问权限。 16 | 2. 如果对象的DACL没有ACE,则系统将拒绝所有尝试访问该对象的尝试,因为DACL不允许任何访问权限。 17 | 3. 系统依次检查ACE,直到找到一个或多个允许所有请求的访问权限的ACE,或者直到拒绝任何请求的访问权限为止。 18 | 19 | 下图显示了对象的DACL如何允许访问一个线程而拒绝访问另一个线程。 20 | 21 | ![](.gitbook/assets/image%20%2813%29.png) 22 | 23 | 对于线程A,系统将读取第一条ACE并立即拒绝访问,因为拒绝访问的ACE适用于线程访问令牌中的用户。在这种情况下,系统将不检查之后的ACE。对于线程B,第一条ACE不适用,因此系统进入允许写入访问的ACE 2和允许读取和执行访问的ACE 3。 24 | 25 | SACL使管理员可以记录任何人对安全对象的访问。每个ACE指定受托者尝试访问的类型,这些访问使系统在安全事件日志中生成记录。当访问尝试失败或成功时,SACL中的ACE可以生成审核记录。 26 | 27 | 不要尝试直接使用ACL的内容。为确保ACL在语义上正确,需使用适当的函数来创建和操作ACL。 28 | 29 | ACL还提供对`Microsoft Active Directory`目录服务对象的访问控制。 `Active Directory`服务接口(ADSI)包括用于创建和修改这些ACL内容的例程。相关内容会另开文章详细介绍。 30 | 31 | ### **从ACL获取信息** 32 | 33 | 微软提供了几种从访问控制列表(ACL)中检索访问控制信息的功能。这些功能包括确定ACL授予或审核指定受托者的访问权限的功能。其他功能使您能够提取有关ACL中访问控制项(ACE)的信息。 34 | 35 | `GetExplicitEntriesFromAcl`函数检索描述在ACL中的ACE的`EXPLICIT_ACCESS`结构的数组。将ACE信息从一个ACL复制到另一个ACL时,此功能很有用。例如,对`GetExplicitEntriesFromAcl`的调用以在一个ACL中获取有关ACE的信息之后,可以通过在对`SetEntriesInAcl`函数的调用中传递返回的`EXPLICIT_ACCESS`结构,以在新的ACL中创建等效的ACE。 36 | 37 | `GetEffectiveRightsFromAcl`函数使您能够确定DACL授予指定受托者的有效访问权限。受托人的有效访问权是DACL授予受托人或受托人为成员的任何组的访问权。 `GetEffectiveRightsFromAcl`检查指定DACL中的所有允许访问和拒绝访问的ACE。 38 | 39 | 使用以下步骤确定受托者对对象的访问权限: 40 | 41 | 1. 调用`GetSecurityInfo`或`GetNamedSecurityInfo`函数以获取指向对象的DACL的指针。 42 | 2. 调用`GetEffectiveRightsFromAcl`函数以检索DACL授予指定受托者的访问权限。 43 | 44 | `GetAuditedPermissionsFromAcl`函数使您可以检查SACL,以确定指定受托人或受托人所属成员的任何组的审核访问权限。审核的权限指示导致系统在安全事件日志中生成审核记录的访问尝试的类型。该函数返回两个访问掩码:一个包含对失败的访问尝试进行监视的访问权限,另一个包含对成功的访问进行监视的访问权限。 `GetAuditedPermissionsFromAcl`检查SACL中的所有系统审核的ACE。 45 | 46 | ### **创建或修改ACL** 47 | 48 | Windows支持一组功能,这些功能可以创建访问控制列表(ACL)或修改现有ACL中的访问控制项(ACE)。 49 | 50 | `SetEntriesInAcl`函数创建一个新的ACL。 `SetEntriesInAcl`可以为ACL指定一组全新的ACE,也可以将一个或多个新ACE与现有ACL的ACE合并。 `SetEntriesInAcl`函数使用`EXPLICIT_ACCESS`结构的数组来指定新ACE的信息。每个EXPLICIT\_ACCESS结构都包含描述单个ACE的信息。此信息包括访问权限、ACE的类型、控制ACE继承的标志以及标识受托者的`TRUSTEE`结构。 51 | 52 | 向现有ACL添加新ACE 53 | 54 | 1. 使用`GetSecurityInfo`或`GetNamedSecurityInfo`函数可从对象的安全描述符获取现有的DACL或SACL。 55 | 2. 对于每个新的ACE,可调用`BuildExplicitAccessWithName`函数以使用描述ACE的信息填充`EXPLICIT_ACCESS`结构。 56 | 3. 调用`SetEntriesInAcl`,为新ACE指定现有的ACL和`EXPLICIT_ACCESS`结构的数组。`SetEntriesInAcl`函数分配并初始化ACL及其ACE。 57 | 4. 调用`SetSecurityInfo`或`SetNamedSecurityInfo`函数,将新的ACL附加到对象的安全描述符。 58 | 59 | 如果调用方指定了现有的ACL,则`SetEntriesInAcl`会将新的ACE信息与ACL中的现有ACE合并。例如,考虑以下情况:现有ACL授予对指定受托者的访问权限,而`EXPLICIT_ACCESS`结构拒绝对同一受托者的访问权限。在这种情况下,`SetEntriesInAcl`为受托者添加一个新的拒绝访问的ACE,并为受托者删除或修改现有的允许访问的ACE。 60 | 61 | 相关示例代码我准备了C++与C\#两个版本: 62 | 63 | C++版本代码,示例使用GetNamedSecurityInfo函数获取现有的DACL。然后,它使用有关ACE的信息填充EXPLICIT\_ACCESS结构,并使用SetEntriesInAcl函数将新ACE与DACL中的任何现有ACE合并。最后,该示例调用SetNamedSecurityInfo函数将新的DACL附加到对象的安全描述符。: 64 | 65 | ```text 66 | #include 67 | #include 68 | 69 | DWORD AddAceToObjectsSecurityDescriptor ( 70 | LPTSTR pszObjName, // name of object 71 | SE_OBJECT_TYPE ObjectType, // type of object 72 | LPTSTR pszTrustee, // trustee for new ACE 73 | TRUSTEE_FORM TrusteeForm, // format of trustee structure 74 | DWORD dwAccessRights, // access mask for new ACE 75 | ACCESS_MODE AccessMode, // type of ACE 76 | DWORD dwInheritance // inheritance flags for new ACE 77 | ) 78 | { 79 | DWORD dwRes = 0; 80 | PACL pOldDACL = NULL, pNewDACL = NULL; 81 | PSECURITY_DESCRIPTOR pSD = NULL; 82 | EXPLICIT_ACCESS ea; 83 | 84 | if (NULL == pszObjName) 85 | return ERROR_INVALID_PARAMETER; 86 | 87 | // Get a pointer to the existing DACL. 88 | 89 | dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, 90 | DACL_SECURITY_INFORMATION, 91 | NULL, NULL, &pOldDACL, NULL, &pSD); 92 | if (ERROR_SUCCESS != dwRes) { 93 | printf( "GetNamedSecurityInfo Error %u\n", dwRes ); 94 | goto Cleanup; 95 | } 96 | 97 | // Initialize an EXPLICIT_ACCESS structure for the new ACE. 98 | 99 | ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); 100 | ea.grfAccessPermissions = dwAccessRights; 101 | ea.grfAccessMode = AccessMode; 102 | ea.grfInheritance= dwInheritance; 103 | ea.Trustee.TrusteeForm = TrusteeForm; 104 | ea.Trustee.ptstrName = pszTrustee; 105 | 106 | // Create a new ACL that merges the new ACE 107 | // into the existing DACL. 108 | 109 | dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL); 110 | if (ERROR_SUCCESS != dwRes) { 111 | printf( "SetEntriesInAcl Error %u\n", dwRes ); 112 | goto Cleanup; 113 | } 114 | 115 | // Attach the new ACL as the object's DACL. 116 | 117 | dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, 118 | DACL_SECURITY_INFORMATION, 119 | NULL, NULL, pNewDACL, NULL); 120 | if (ERROR_SUCCESS != dwRes) { 121 | printf( "SetNamedSecurityInfo Error %u\n", dwRes ); 122 | goto Cleanup; 123 | } 124 | 125 | Cleanup: 126 | 127 | if(pSD != NULL) 128 | LocalFree((HLOCAL) pSD); 129 | if(pNewDACL != NULL) 130 | LocalFree((HLOCAL) pNewDACL); 131 | 132 | return dwRes; 133 | } 134 | ``` 135 | 136 | C\#版本,修改文件的ACL。在C\#中大部分的对象都拥有SetAccessControl方法来修改其ACL,该方法需要一个安全对象需要针对特定的对象进行获取,比如文件中是FileSecurity,在注册表中是RegistrySecurity。在传入这个安全对象之前调用AddAccessRule即可增加ACE,RemoveAccessRule即可删除ACE,下面是文件的详细代码: 137 | 138 | ```text 139 | using System; 140 | using System.IO; 141 | using System.Security.AccessControl; 142 | 143 | namespace FileSystemExample 144 | { 145 | class FileExample 146 | { 147 | public static void Main() 148 | { 149 | try 150 | { 151 | string FileName = "c:/test.xml"; 152 | 153 | Console.WriteLine("Adding access control entry for " + FileName); 154 | 155 | // Add the access control entry to the file. 156 | // Before compiling this snippet, change MyDomain to your 157 | // domain name and MyAccessAccount to the name 158 | // you use to access your domain. 159 | AddFileSecurity(FileName, @"MyDomain\MyAccessAccount", FileSystemRights.ReadData, AccessControlType.Allow); 160 | 161 | Console.WriteLine("Removing access control entry from " + FileName); 162 | 163 | // Remove the access control entry from the file. 164 | // Before compiling this snippet, change MyDomain to your 165 | // domain name and MyAccessAccount to the name 166 | // you use to access your domain. 167 | RemoveFileSecurity(FileName, @"MyDomain\MyAccessAccount", FileSystemRights.ReadData, AccessControlType.Allow); 168 | 169 | Console.WriteLine("Done."); 170 | } 171 | catch (Exception e) 172 | { 173 | Console.WriteLine(e); 174 | } 175 | 176 | } 177 | 178 | // Adds an ACL entry on the specified file for the specified account. 179 | public static void AddFileSecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType) 180 | { 181 | // Create a new FileInfo object. 182 | FileInfo fInfo = new FileInfo(FileName); 183 | 184 | // Get a FileSecurity object that represents the 185 | // current security settings. 186 | FileSecurity fSecurity = fInfo.GetAccessControl(); 187 | 188 | // Add the FileSystemAccessRule to the security settings. 189 | fSecurity.AddAccessRule(new FileSystemAccessRule(Account, 190 | Rights, 191 | ControlType)); 192 | 193 | // Set the new access settings. 194 | fInfo.SetAccessControl(fSecurity); 195 | 196 | } 197 | 198 | // Removes an ACL entry on the specified file for the specified account. 199 | public static void RemoveFileSecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType) 200 | { 201 | // Create a new FileInfo object. 202 | FileInfo fInfo = new FileInfo(FileName); 203 | 204 | // Get a FileSecurity object that represents the 205 | // current security settings. 206 | FileSecurity fSecurity = fInfo.GetAccessControl(); 207 | 208 | // Add the FileSystemAccessRule to the security settings. 209 | fSecurity.RemoveAccessRule(new FileSystemAccessRule(Account, 210 | Rights, 211 | ControlType)); 212 | 213 | // Set the new access settings. 214 | fInfo.SetAccessControl(fSecurity); 215 | 216 | } 217 | } 218 | } 219 | //This code produces output similar to the following; 220 | //results may vary based on the computer/file structure/etc.: 221 | // 222 | //Adding access control entry for c:\test.xml 223 | //Removing access control entry from c:\test.xml 224 | //Done. 225 | // 226 | ``` 227 | 228 | 注册表相关ACL修改代码: 229 | 230 | ```text 231 | using System; 232 | using System.Reflection; 233 | using System.Security; 234 | using System.Security.AccessControl; 235 | using Microsoft.Win32; 236 | 237 | public class Example 238 | { 239 | public static void Main() 240 | { 241 | // Delete the example key if it exists. 242 | try 243 | { 244 | Registry.CurrentUser.DeleteSubKey("RegistryRightsExample"); 245 | Console.WriteLine("Example key has been deleted."); 246 | } 247 | catch (ArgumentException) 248 | { 249 | // ArgumentException is thrown if the key does not exist. In 250 | // this case, there is no reason to display a message. 251 | } 252 | catch (Exception ex) 253 | { 254 | Console.WriteLine("Unable to delete the example key: {0}", ex); 255 | return; 256 | } 257 | 258 | string user = Environment.UserDomainName + "\\" + Environment.UserName; 259 | 260 | RegistrySecurity rs = new RegistrySecurity(); 261 | 262 | // Allow the current user to read and delete the key. 263 | // 264 | rs.AddAccessRule(new RegistryAccessRule(user, 265 | RegistryRights.ReadKey | RegistryRights.Delete, 266 | InheritanceFlags.None, 267 | PropagationFlags.None, 268 | AccessControlType.Allow)); 269 | 270 | // Prevent the current user from writing or changing the 271 | // permission set of the key. Note that if Delete permission 272 | // were not allowed in the previous access rule, denying 273 | // WriteKey permission would prevent the user from deleting the 274 | // key. 275 | rs.AddAccessRule(new RegistryAccessRule(user, 276 | RegistryRights.WriteKey | RegistryRights.ChangePermissions, 277 | InheritanceFlags.None, 278 | PropagationFlags.None, 279 | AccessControlType.Deny)); 280 | 281 | // Create the example key with registry security. 282 | RegistryKey rk = null; 283 | try 284 | { 285 | rk = Registry.CurrentUser.CreateSubKey("RegistryRightsExample", 286 | RegistryKeyPermissionCheck.Default, rs); 287 | Console.WriteLine("\r\nExample key created."); 288 | rk.SetValue("ValueName", "StringValue"); 289 | } 290 | catch (Exception ex) 291 | { 292 | Console.WriteLine("\r\nUnable to create the example key: {0}", ex); 293 | } 294 | if (rk != null) rk.Close(); 295 | 296 | rk = Registry.CurrentUser; 297 | 298 | RegistryKey rk2; 299 | 300 | // Open the key with read access. 301 | rk2 = rk.OpenSubKey("RegistryRightsExample", false); 302 | Console.WriteLine("\r\nRetrieved value: {0}", rk2.GetValue("ValueName")); 303 | rk2.Close(); 304 | 305 | // Attempt to open the key with write access. 306 | try 307 | { 308 | rk2 = rk.OpenSubKey("RegistryRightsExample", true); 309 | } 310 | catch (SecurityException ex) 311 | { 312 | Console.WriteLine("\nUnable to write to the example key." + 313 | " Caught SecurityException: {0}", ex.Message); 314 | } 315 | if (rk2 != null) rk2.Close(); 316 | 317 | // Attempt to change permissions for the key. 318 | try 319 | { 320 | rs = new RegistrySecurity(); 321 | rs.AddAccessRule(new RegistryAccessRule(user, 322 | RegistryRights.WriteKey, 323 | InheritanceFlags.None, 324 | PropagationFlags.None, 325 | AccessControlType.Allow)); 326 | rk2 = rk.OpenSubKey("RegistryRightsExample", false); 327 | rk2.SetAccessControl(rs); 328 | Console.WriteLine("\r\nExample key permissions were changed."); 329 | } 330 | catch (UnauthorizedAccessException ex) 331 | { 332 | Console.WriteLine("\nUnable to change permissions for the example key." + 333 | " Caught UnauthorizedAccessException: {0}", ex.Message); 334 | } 335 | if (rk2 != null) rk2.Close(); 336 | 337 | Console.WriteLine("\r\nPress Enter to delete the example key."); 338 | Console.ReadLine(); 339 | 340 | try 341 | { 342 | rk.DeleteSubKey("RegistryRightsExample"); 343 | Console.WriteLine("Example key was deleted."); 344 | } 345 | catch(Exception ex) 346 | { 347 | Console.WriteLine("Unable to delete the example key: {0}", ex); 348 | } 349 | 350 | rk.Close(); 351 | } 352 | } 353 | 354 | /* This code example produces the following output: 355 | 356 | Example key created. 357 | 358 | Retrieved value: StringValue 359 | 360 | Unable to write to the example key. Caught SecurityException: Requested registry access is not allowed. 361 | 362 | Unable to change permissions for the example key. Caught UnauthorizedAccessException: Cannot write to the registry key. 363 | 364 | Press Enter to delete the example key. 365 | 366 | Example key was deleted. 367 | */ 368 | ``` 369 | 370 | -------------------------------------------------------------------------------- /security-descriptor-definition-language-for-conditional-aces.md: -------------------------------------------------------------------------------- 1 | # (一)基于条件表达式ACE的SDDL 2 | 3 | ## ACE在的SDDL中的条件表达式 4 | 5 | 条件访问控制项(ACE)允许在执行访问检查时评估访问条件。安全描述符定义语言(SDDL)提供了用于以字符串格式定义条件ACE的语法。 6 | 7 | 条件ACE的SDDL与其他ACE相同,条件语句的语法是写在ACE字符串的末尾。 8 | 9 | 资源属性中的“#”符号与“ 0”同义。例如,`D:AI(XA; OICI; FA ;;; WD;(OctetStringType ==#1#2#3##))`等效并解释为`D:AI(XA; OICI; FA ;;; WD;(OctetStringType ==#01020300))`。 10 | 11 | ### **条件ACE字符串格式** 12 | 13 | 安全描述符字符串中的每个ACE都用括号括起来。 ACE的字段按以下顺序排列,并用分号(;)分隔。 14 | 15 | _AceType\*\*_;_**AceFlags**_;_**Rights**_;_**ObjectGuid**_;_**InheritObjectGuid**_;_**AccountSid**_;\(_**ConditionalExpression**_\)\*\* 16 | 17 | 这些字段如ACE字符串中所述,但以下情况除外。 18 | 19 | * AceType字段可以是以下字符串之一。(当然不止这些,更多可以参考ACE字符串章节) 20 | 21 | | ACE 类型的字符串 | Sddl.h中的常量 | AceType 值 | 22 | | :--- | :--- | :--- | 23 | | "XA" | SDDL\_CALLBACK\_ACCESS\_ALLOWED | ACCESS\_ALLOWED\_CALLBACK\_ACE\_TYPE | 24 | | "XD" | SDDL\_CALLBACK\_ACCESS\_DENIED | ACCESS\_DENIED\_CALLBACK\_ACE\_TYPE | 25 | 26 | * ACE字符串包含一个或多个条件表达式,并在字符串末尾的括号中。 27 | 28 | ### **条件表达式** 29 | 30 | 条件表达式可以包含以下任何元素。 31 | 32 | | 表达式元素 | 描述 | 33 | | :--- | :--- | 34 | | _AttributeName_ | 测试指定的属性是否具有非零值。 | 35 | | **exists** _AttributeName_ | 测试客户端上下文中是否存在指定的属性。 | 36 | | _AttributeName_ _Operator_ _Value_ | 返回指定操作的结果。 | 37 | | _ConditionalExpression\*\*_\|\|_\*\*ConditionalExpression_ | 测试指定的条件表达式中的任何一个是否为true。 | 38 | | _ConditionalExpression_ **&&** _ConditionalExpression_ | 测试两个指定的条件表达式是否为真。 | 39 | | **!\(\**\*ConditionalExpression\*_\_\)\*\* | 条件表达式的逆函数。 | 40 | | **Member\_of{\**\*SidArray\*_\_}\*\* | 测试客户端上下文的`SID_AND_ATTRIBUTES`数组是否包含`SidArray`指定的逗号分隔列表中的所有安全标识符(SID)。 对于允许ACE,客户端上下文SID必须将`SE_GROUP_ENABLED`属性设置为被视为匹配项。 对于`Deny ACE`,客户端上下文SID必须将`SE_GROUP_ENABLED`或`SE_GROUP_USE_FOR_DENY_ONLY`属性设置为被视为匹配项。 `SidArray`数组可以包含SID字符串(例如“ S-1-5-6”)或SID别名(例如“ BA”) | 41 | 42 | ### **属性** 43 | 44 | 属性表示客户端上下文中`AUTHZ_SECURITY_ATTRIBUTES_INFORMATION`数组中的元素。属性名称可以包含任何字母数字字符和任何字符“:”,“ /”,“。”和“ \_”。 45 | 46 | 属性值可以是以下任何类型。 47 | 48 | | 类型 | 描述 | 49 | | :--- | :--- | 50 | | Integer | 以十进制或十六进制表示的64位整数。 | 51 | | String | 用引号分隔的字符串值。 | 52 | | SID | 必须位于Member\_of或Device\_Member\_of的RHS上。 | 53 | | BLOB | #后跟十六进制数字。如果数字的长度为奇数,则将#转换为0使其变为偶数。同样,在值的其他位置出现的#也将转换为0。 | 54 | 55 | ### **操作符** 56 | 57 | 定义了以下运算符,供在条件表达式中使用以测试属性值。所有这些都是二进制运算符,并以`AttributeName`运算符值的形式使用。 58 | 59 | | Operator | Description | 60 | | :--- | :--- | 61 | | == | Conventional definition. | 62 | | != | Conventional definition. | 63 | | < | Conventional definition. | 64 | | <= | Conventional definition. | 65 | | > | Conventional definition. | 66 | | >= | Conventional definition. | 67 | | Contains | 如果指定属性的值是指定值的超集,则为TRUE;否则为TRUE。否则为FALSE. | 68 | | Any\_of | 如果指定值是指定属性值的超集,则为TRUE;否则为TRUE。否则为FALSE。 | 69 | 70 | 此外,一元运算符Exists,Member\_of和negation(!)的定义如条件表达式表中所述。 “ Contains”运算符必须在空格之前和之后,而“ Any\_of”运算符必须在空格之前。 71 | 72 | ### Unknown 73 | 74 | 条件表达式的结果有时返回值Unknown。例如,当指定的属性不存在时,任何关系操作都将返回“未知”。 75 | 76 | 下表描述了两个条件表达式`ConditionalExpression1`和`ConditionalExpression2`之间的逻辑与运算的结果。 77 | 78 | | _ConditionalExpression1_ | _ConditionalExpression2_ | _ConditionalExpression1_ **&&** _ConditionalExpression2_ | 79 | | :--- | :--- | :--- | 80 | | **TRUE** | **TRUE** | **TRUE** | 81 | | **TRUE** | **FALSE** | **FALSE** | 82 | | **TRUE** | **UNKNOWN** | **UNKNOWN** | 83 | | **FALSE** | **TRUE** | **FALSE** | 84 | | **FALSE** | **FALSE** | **FALSE** | 85 | | **FALSE** | **UNKNOWN** | **FALSE** | 86 | | **UNKNOWN** | **TRUE** | **UNKNOWN** | 87 | | **UNKNOWN** | **FALSE** | **FALSE** | 88 | | **UNKNOWN** | **UNKNOWN** | **UNKNOWN** | 89 | 90 | 下表描述了两个条件表达式`ConditionalExpression1`和`ConditionalExpression2`之间的逻辑或运算的结果。 91 | 92 | | _ConditionalExpression1_ | _ConditionalExpression2_ | _ConditionalExpression1_ **\|\|** _ConditionalExpression2_ | 93 | | :--- | :--- | :--- | 94 | | **TRUE** | **TRUE** | **TRUE** | 95 | | **TRUE** | **FALSE** | **TRUE** | 96 | | **TRUE** | **UNKNOWN** | **TRUE** | 97 | | **FALSE** | **TRUE** | **TRUE** | 98 | | **FALSE** | **FALSE** | **FALSE** | 99 | | **FALSE** | **UNKNOWN** | **UNKNOWN** | 100 | | **UNKNOWN** | **TRUE** | **TRUE** | 101 | | **UNKNOWN** | **FALSE** | **UNKNOWN** | 102 | | **UNKNOWN** | **UNKNOWN** | **UNKNOWN** | 103 | 104 | 值为`UNKNOWN`的条件表达式的否定也是`UNKNOWN`。 105 | 106 | ### **条件ACE评估** 107 | 108 | 下表描述了根据条件表达式的最终评估得出的条件ACE的访问检查结果。 109 | 110 | | ACE type | TRUE | FALSE | UNKNOWN | 111 | | :--- | :--- | :--- | :--- | 112 | | Allow | Allow | Ignore ACE | Ignore ACE | 113 | | Deny | Deny | Ignore ACE | Deny | 114 | 115 | ### **案例** 116 | 117 | 下面通过一些示例说明SDDL定义的条件ACE是如何来表示指定的访问策略。 118 | 119 | 条件:如果同时满足以下两个条件,则允许对所有人执行 120 | 121 | * Title = PM 122 | * Division = Finance or Division = Sales 123 | 124 | SDDL: 125 | 126 | `D:(XA; ;FX;;;S-1-1-0; (@User.Title=="PM" && (@User.Division=="Finance" || @User.Division ==" Sales")))` 127 | 128 | 129 | 130 | 条件: 如果任何用户项目与文件项目相交,则允许执行。 131 | 132 | SDDL: 133 | 134 | `D:(XA; ;FX;;;S-1-1-0; (@User.Project Any_of @Resource.Project))` 135 | 136 | ## 137 | 138 | -------------------------------------------------------------------------------- /security-descriptor-definition-language.md: -------------------------------------------------------------------------------- 1 | # 2. SDDL 2 | 3 | ## 安全描述符定义语言 4 | 5 | 安全描述符定义语言(SDDL)定义了`ConvertSecurityDescriptorToStringSecurityDescriptor`和`ConvertStringSecurityDescriptorToSecurityDescriptor`函数用来将安全描述符描述为文本字符串的字符串格式。该语言还定义了字符串元素,用于描述安全描述符的组成部分中的信息。 6 | 7 | 针对本章节的学习建议使用[AccessChk](https://docs.microsoft.com/en-us/sysinternals/downloads/accesschk)工具,该工具可以直接展示出指定对象的权限信息,并且能从SDDL到已解析的权限全面覆盖。 8 | 9 | 常用参数有: 10 | 11 | 1. -L,即展示SDDL; 12 | 2. -l显示解析后的安全描述符; 13 | 3. 不使用参数为展示通用的权限格式; 14 | 4. -v展示详细信息 15 | 16 | ![展示SDDL](.gitbook/assets/image%20%2812%29.png) 17 | 18 | ![展示安全描述符](.gitbook/assets/image%20%2817%29.png) 19 | 20 | ![展示权限](.gitbook/assets/image%20%2811%29.png) 21 | 22 | ## 安全描述符字符串格式 23 | 24 | 安全描述符字符串格式是一种文本格式,用于在安全描述符中存储或传输信息。 `ConvertSecurityDescriptorToStringSecurityDescriptor`和`ConvertStringSecurityDescriptorToSecurityDescriptor`函数使用此格式。 25 | 26 | 格式是一个以空值(**null**)结尾的字符串,带有令牌(tiken),用于指示安全描述符的四个主要组成部分:所有者(O :\),主要组(G :\),DACL(D :\)和SACL(S :\)。 27 | 28 | ```cpp 29 | O:owner_sid 30 | G:group_sid 31 | D:dacl_flags(string_ace1)(string_ace2)... (string_acen) 32 | S:sacl_flags(string_ace1)(string_ace2)... (string_acen) 33 | ``` 34 | 35 | owner\_sid : 标识对象所有者的SID字符串。 36 | 37 | group\_sid : 一个SID字符串,用于标识对象的主要组。 38 | 39 | dacl\_flags : 适用于DACL的安全描述符控制标志。有关这些控制标志的说明,请参见SetSecurityDescriptorControl函数。 dacl\_flags字符串可以是零个或多个以下字符串的串联。 40 | 41 | | Control | Constant in Sddl.h | Meaning | 42 | | :--- | :--- | :--- | 43 | | "P" | SDDL\_PROTECTED | The SE\_DACL\_PROTECTED flag is set. | 44 | | "AR" | SDDL\_AUTO\_INHERIT\_REQ | The SE\_DACL\_AUTO\_INHERIT\_REQ flag is set. | 45 | | "AI" | SDDL\_AUTO\_INHERITED | The SE\_DACL\_AUTO\_INHERITED flag is set. | 46 | | "NO\_ACCESS\_CONTROL" | SSDL\_NULL\_ACL | The ACL is null. | 47 | 48 | sacl\_flags : 适用于SACL的安全描述符控制标志。 sacl\_flags字符串使用与dacl\_flags字符串相同的控制位字符串。 49 | 50 | string\_ace : 在安全描述符的DACL或SACL中描述ACE的字符串。有关ACE字符串格式的说明,可参考本章第二节的ACE字符串。每个ACE字符串都括在括号(())中。 51 | 52 | 可以从安全描述符字符串中省略不需要的组件。例如,如果未在输入安全描述符中设置`SE_DACL_PRESENT`标志,则`ConvertSecurityDescriptorToStringSecurityDescriptor`在输出字符串中不包含D:组件。您还可以使用`SECURITY_INFORMATION`位标志来指示要包含在安全描述符字符串中的组件。 53 | 54 | 安全描述符字符串格式不支持NULL ACL。 55 | 56 | 为了表示一个空的ACL,安全描述符字符串包括D:或S:令牌,没有其他字符串信息。 57 | 58 | 安全描述符字符串以不同的方式存储“安全描述符控制”位。`SE_DACL_PRESENT`或`SE_SACL_PRESENT`位由字符串中D:或S:令牌的存在指示。适用于DACL或SACL的其他位存储在`dacl_flags`和`sacl_flags`中。 `SE_OWNER_DEFAULTED`、`SE_GROUP_DEFAULTED`、`SE_DACL_DEFAULTED`和`SE_SACL_DEFAULTED`位未存储在安全描述符字符串中。 `SE_SELF_RELATIVE`位未存储在字符串中,但是`ConvertStringSecurityDescriptorToSecurityDescriptor`始终在输出安全描述符中设置此位。 59 | 60 | 以下示例显示了安全描述符字符串和关联的安全描述符中的信息。 61 | 62 | ```cpp 63 | c:\users\public\videos\desktop.ini 64 | O:SYD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1301ff;;;IU)(A;ID;0x1301ff;;;SU)(A 65 | ;ID;0x1301ff;;;S-1-5-3) 66 | ``` 67 | 68 | O: SY代表该对象的Owner为System(类似O这样的表达为SID表达的可以在SID字符串章节找到对应的参考信息) 69 | 70 | ![SYSTEM](.gitbook/assets/image%20%2810%29.png) 71 | 72 | D:AI代表SDDL\_AUTO\_INHERITED为权限继承,之后的内容为ACE(ACE的具体解释在后面的小节逐一介绍) 73 | 74 | 另外一些例子如下: 75 | 76 | ```cpp 77 | "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)" 78 | ``` 79 | 80 | 安全描述符1: 81 | 82 | ```cpp 83 | Revision: 0x00000001 84 | Control: 0x0004 85 | SE_DACL_PRESENT 86 | Owner: (S-1-5-32-548) 87 | PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512) 88 | DACL 89 | Revision: 0x02 90 | Size: 0x001c 91 | AceCount: 0x0001 92 | Ace[00] 93 | AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE) 94 | AceSize: 0x0014 95 | InheritFlags: 0x00 96 | Access Mask: 0x100e003f 97 | READ_CONTROL 98 | WRITE_DAC 99 | WRITE_OWNER 100 | GENERIC_ALL 101 | Others(0x0000003f) 102 | Ace Sid : (S-1-0-0) 103 | SACL 104 | Not present 105 | ``` 106 | 107 | 字符串 2: 108 | 109 | ```cpp 110 | "O:DAG:DAD:(A;;RPWPCCDCLCRCWOWDSDSW;;;SY) 111 | (A;;RPWPCCDCLCRCWOWDSDSW;;;DA) 112 | (OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO) 113 | (OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO) 114 | (OA;;CCDC;6da8a4ff-0e52-11d0-a286-00aa003049e2;;AO) 115 | (OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO) 116 | (A;;RPLCRC;;;AU)S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)" 117 | ``` 118 | 119 | 安全描述符2: 120 | 121 | ```cpp 122 | Revision: 0x00000001 123 | Control: 0x0014 124 | SE_DACL_PRESENT 125 | SE_SACL_PRESENT 126 | Owner: (S-1-5-21-397955417-626881126-188441444-512) 127 | PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512) 128 | DACL 129 | Revision: 0x04 130 | Size: 0x0104 131 | AceCount: 0x0007 132 | Ace[00] 133 | AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE) 134 | AceSize: 0x0014 135 | InheritFlags: 0x00 136 | Access Mask: 0x000f003f 137 | DELETE 138 | READ_CONTROL 139 | WRITE_DAC 140 | WRITE_OWNER 141 | Others(0x0000003f) 142 | Ace Sid: (S-1-5-18) 143 | Ace[01] 144 | AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE) 145 | AceSize: 0x0024 146 | InheritFlags: 0x00 147 | Access Mask: 0x000f003f 148 | DELETE 149 | READ_CONTROL 150 | WRITE_DAC 151 | WRITE_OWNER 152 | Others(0x0000003f) 153 | Ace Sid: (S-1-5-21-397955417-626881126-188441444-512) 154 | Ace[02] 155 | AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE) 156 | AceSize: 0x002c 157 | InheritFlags: 0x00 158 | Access Mask: 0x00000003 159 | Others(0x00000003) 160 | Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT 161 | ObjectType: GUID_C_USER 162 | InhObjectType: GUID ptr is NULL 163 | Ace Sid: (S-1-5-32-548) 164 | Ace[03] 165 | AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE) 166 | AceSize: 0x002c 167 | InheritFlags: 0x00 168 | Access Mask: 0x00000003 169 | Others(0x00000003) 170 | Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT 171 | ObjectType: GUID_C_GROUP 172 | InhObjectType: GUID ptr is NULL 173 | Ace Sid: (S-1-5-32-548) 174 | Ace[04] 175 | AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE) 176 | AceSize: 0x002c 177 | InheritFlags: 0x00 178 | Access Mask: 0x00000003 179 | Others(0x00000003) 180 | Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT 181 | ObjectType: GUID_C_LOCALGROUP 182 | InhObjectType: GUID ptr is NULL 183 | Ace Sid: (S-1-5-32-548) 184 | Ace[05] 185 | AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE) 186 | AceSize: 0x002c 187 | InheritFlags: 0x00 188 | Access Mask: 0x00000003 189 | Others(0x00000003) 190 | Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT 191 | ObjectType: GUID_C_PRINT_QUEUE 192 | InhObjectType: GUID ptr is NULL 193 | Ace Sid: (S-1-5-32-550) 194 | Ace[06] 195 | AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE) 196 | AceSize: 0x0014 197 | InheritFlags: 0x00 198 | Access Mask: 0x00020014 199 | READ_CONTROL 200 | Others(0x00000014) 201 | Ace Sid: (S-1-5-11) 202 | SACL 203 | Revision: 0x02 204 | Size: 0x001c 205 | AceCount: 0x0001 206 | Ace[00] 207 | AceType: 0x02 (SYSTEM_AUDIT_ACE_TYPE) 208 | AceSize: 0x0014 209 | InheritFlags: 0xc0 210 | SUCCESSFUL_ACCESS_ACE_FLAG 211 | FAILED_ACCESS_ACE_FLAG 212 | Access Mask: 0x000d002b 213 | DELETE 214 | WRITE_DAC 215 | WRITE_OWNER 216 | Others(0x0000002b) 217 | Ace Sid: (S-1-1-0) 218 | ``` 219 | 220 | ## 221 | 222 | -------------------------------------------------------------------------------- /si-ace.md: -------------------------------------------------------------------------------- 1 | # (四)ACE 2 | 3 | ## **访问控制项** 4 | 5 | 访问控制条目(ACE)是访问控制列表(ACL)中的元素。一个ACL可以包含零个或多个ACE。每个ACE控制或监视指定受托者(Trustees)对对象的访问。 6 | 7 | ACE有六种类型,所有安全对象都支持其中三种。其他三种类型是目录服务对象支持的特定于对象的ACE. 8 | 9 | 所有类型的ACE都包含以下访问控制信息: 10 | 11 | * 安全标识符(SID),用于标识ACE适用于的受托者 12 | * 一个访问掩码(Access Mask),该掩码指定了具体的访问权限(Access Rights),也就是可以对该对象执行的操作(此掩码非常重要,后续很多漏洞会用到) 13 | * 一个位标记,指示ACE类型的标志。 14 | * 一组位标志,指示了安全描述符所属对象的子对象是否继承这个ACE。 15 | 16 | 下表列出了所有安全对象支持的三种ACE类型。 17 | 18 | | 类型 | 描述 | 19 | | :---: | :---: | 20 | | Access-denied ACE | 在自由访问控制列表(DACL)中使用,以拒绝对受托者的访问 | 21 | | Access-allowed ACE | 在DACL中使用,以允许对受托者的访问权限。 | 22 | | System-audit ACE | 当受托者尝试行使指定的访问权限时,用于系统访问控制列表(SACL)中以生成审核记录。 | 23 | 24 | ### **受托者** 25 | 26 | 受托者是访问控制条目(ACE)应用到的**用户帐户、组帐户或登录会话等**。访问控制列表(ACL)中的每个ACE都有一个安全标识符(SID),用于标识受托者。 27 | 28 | 1. 用户帐户包括人类用户或Windows Services等程序用于登录本地计算机的帐户。 29 | 2. 组帐户不能用于登录计算机,但是在ACE中它们非常有用,可以允许或拒绝组访问权限来达到对一个或多个用户帐户的权限控制。 30 | 3. 标识当前登录会话的登录SID仅在用户注销之前才允许允许或拒绝访问权限。 31 | 32 | 访问控制功能使用TRUSTEE结构来标识受托者。TRUSTEE结构可以使用名称字符串或SID来标识受托者。如果使用名称,则从TRUSTEE结构创建ACE的功能将执行分配SID缓冲区并查找与帐户名称相对应的SID的任务。有两个帮助程序函数`BuildTrusteeWithSid`和`BuildTrusteeWithName`,它们使用指定的SID或名称初始化TRUSTEE结构。 `BuildTrusteeWithObjectsAndSid`和`BuildTrusteeWithObjectsAndName`允许使用特定于对象的ACE信息初始化TRUSTEE结构。其他三个帮助函数`GetTrusteeForm`、`GetTrusteeName`和`GetTrusteeType`检索TRUSTEE结构的各个成员的值。 33 | 34 | TRUSTEE结构的`ptstrName`成员可以是指向`OBJECTS_AND_NAME`或`OBJECTS_AND_SID`结构的指针。这些结构除了指定受托人名称或SID之外,还指定有关特定于对象的ACE的信息。这使诸如`SetEntriesInAcl`和`GetExplicitEntriesFromAcl`之类的功能可以将特定于对象的ACE信息存储在`EXPLICIT_ACCESS`结构的Trustee成员中。 35 | 36 | ### **特定对象的ACE** 37 | 38 | 目录服务即域服务(DS)对象支持特定于对象的ACE。特定于对象的ACE包含一对GUID,它们扩展了ACE保护对象的方式。 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 62 | 63 | 64 | 66 | 67 | 68 | 69 |
GUID描述
ObjectType 50 | 52 |

标识以下之一: 53 |
54 |

55 |
    56 |
  1. 一种子对象。 ACE控制创建指定类型的子对象的权限。
  2. 57 |
  3. 属性集或属性。 ACE控制读取或写入属性或属性集的权限。
  4. 58 |
  5. 权限扩展的权利。 ACE控制执行与扩展权限相关的操作的权限。
  6. 59 |
  7. 经过验证的写入。 ACE控制执行某些写操作的权限。这些在ACL编辑器中定义和公开的经过验证的写入权限为经过验证的属性写入提供了权限,而不是对被授予“写入属性”权限的属性的任何值进行未经检查的低级写入。(这段话摘自微软官方,简单来说就是为写入的权限进行了格式的验证。)
  8. 60 |
61 |
InheritedObjectType 65 | 指示可以继承ACE的子对象的类型。继承也由ACE_HEADER中的继承标志以及放置在子对象上的任何防止继承的保护来控制。
70 | 71 | ### **DACL中的ACE顺序** 72 | 73 | 当进程尝试访问安全对象时,系统逐步浏览该对象的任意访问控制列表(DACL)中的访问控制项(ACE),直到找到允许或拒绝所请求访问的ACE。 DACL允许用户的访问权限可能会根据DACL中ACE的顺序而有所不同。因此,Windows XP操作系统在安全对象的DACL中为ACE定义了首选顺序。首选顺序提供了一个简单的框架,可确保拒绝访问的ACE实际上拒绝访问。上一节已经对该顺序有过介绍。 74 | 75 | 对于Windows Server 2003和Windows XP,引入特定于对象的ACE和自动继承会使得ACE的正确顺序变得复杂。 76 | 77 | 以下步骤描述了首选顺序: 78 | 79 | 1. 将所有显式ACE(即手动设置的ACE)放在一个组中,然后放在任何继承的ACE之前。 80 | 2. 在显式ACE组中,拒绝访问的ACE放置在允许访问的ACE之前。 81 | 3. 继承的ACE按照继承的顺序放置。从子对象的父对象继承的ACE首先出现,然后是从祖父母那里继承的ACE,依此类推。 82 | 4. 对于继承的ACE的每个级别,将拒绝访问的ACE放置在允许访问的ACE之前。 83 | 84 | 另外,并不是ACL中需要所有ACE类型。 85 | 86 | ### **ACE继承** 87 | 88 | 对象的ACL可以包含从其父容器继承的ACE。例如,注册表子项可以从注册表层次结构中位于其上方的项继承ACE。同样,NTFS文件系统中的文件可以从包含该文件的目录继承ACE。 89 | 90 | ACE的`ACE_HEADER`结构(该结构见本节最后一小节)包含一组继承标志,这些继承标志控制ACE继承以及ACE对它所连接的对象的影响。系统根据ACE继承规则解释继承标志和其他继承信息。 91 | 92 | 这些规则通过以下功能得到增强: 93 | 94 | * 支持自动传播可继承的ACE。 95 | * 一个标志,用于区分继承的ACE和直接应用于对象的ACE。 96 | * 特定于对象的ACE,允许指定可以继承ACE的子对象的类型。 97 | * 通过将除`SYSTEM_RESOURCE_ATTRIBUTE_ACE`和`SYSTEM_SCOPED_POLICY_ID_ACE`之外的安全描述符的控制位中的`SE_DACL_PROTECTED`或`SE_SACL_PROTECTED`位设置来防止DACL或SACL继承ACE的能力。 98 | 99 | ### **自动传播可继承的ACE** 100 | 101 | `SetNamedSecurityInfo`和`SetSecurityInfo`函数支持可继承访问控制项(ACE)的自动传播。**例如,如果使用这些功能将可继承的ACE添加到NTFS中的目录,则系统会将ACE适当地应用于任何现有子目录或文件的访问控制列表(ACL)。** 102 | 103 | 直接应用的ACE优先于继承的ACE。系统通过将直接应用的ACE放在任意访问控制列表(DACL)中继承的ACE之前来实现此优先级。当调用`SetNamedSecurityInfo`和`SetSecurityInfo`函数设置对象的安全信息时,系统会将当前继承模型强加于目标对象下方层次结构中所有对象的ACL上。对于已转换为当前继承模型的对象,在对象的安全描述符的控制字段中设置`SE_DACL_AUTO_INHERITED`和`SE_SACL_AUTO_INHERITED`位。 104 | 105 | 当构建一个反映当前继承模型的新安全描述符时,注意不要更改安全描述符的语义。因此,允许和拒绝ACE绝不会彼此相对移动。如果需要进行此类移动(例如,将所有非继承的ACE放在ACL的前面),则将该ACL标记为受保护,以防止语义更改。 106 | 107 | 将继承的ACE传播到子对象时,系统使用以下规则: 108 | 109 | * 如果没有DACL的子对象继承了ACE,则结果是带有DACL的子对象仅包含继承的ACE。 110 | * 如果带有空DACL的子对象继承了ACE,则结果是带有DACL的子对象仅包含继承的ACE。 111 | * 如果从父对象中删除可继承的ACE,则自动继承将删除子对象继承的ACE的所有副本。 112 | * 如果自动继承导致从子对象的DACL中删除所有ACE,则子对象具有空的DACL,而不是没有DACL。 113 | 114 | 这些规则可能会产生意外结果,即将没有DACL的对象转换为具有空DACL的对象。没有DACL的对象允许完全访问,但是具有空DACL的对象不允许访问。作为这些规则如何创建空DACL的示例,假设将可继承的ACE添加到对象树的根对象。自动继承将可继承的ACE传播到树中的所有对象。现在,没有DACL的子对象具有带有继承的ACE的DACL。如果从根对象中删除可继承的ACE,则系统会自动将更改传播到子对象。现在,没有DACL(允许完全访问)的子对象具有空的DACL(不允许访问)。 115 | 116 | 为确保没有DACL的子对象不受继承ACE的影响,在对象的安全描述符中设置`SE_DACL_PROTECTED`标志。 117 | 118 | ### **ACE继承规则** 119 | 120 | 系统根据一组继承规则将可继承访问控制项(ACE)传播到子对象。系统会根据DACL中ACE的首选顺序,将继承的ACE放置在子代的自由访问控制列表(DACL)中。系统在所有继承的ACE中设置`INHERITED_ACE`标志。 121 | 122 | 容器和非容器子对象继承的ACE有所不同,具体取决于继承标志的组合。这些继承规则对DACL和系统访问控制列表(SACL)均起作用。 123 | 124 | | 父ACE标志 | 对子ACL的影响 | 125 | | :---: | :---: | 126 | | OBJECT\_INHERIT\_ACE only | 非容器子对象:继承为有效的ACE。容器子对象:除非还设置了`NO_PROPAGATE_INHERIT_ACE`位标志,否则容器将继承仅继承ACE。 | 127 | | CONTAINER\_INHERIT\_ACE only | 非容器子对象:对子对象无影响。容器子对象:子对象继承有效的ACE。除非还设置了`NO_PROPAGATE_INHERIT_ACE`位标志,否则继承的ACE是可继承的。 | 128 | | CONTAINER\_INHERIT\_ACE and OBJECT\_INHERIT\_ACE | 非容器子对象:继承为有效的ACE。容器子对象:子对象继承有效的ACE。除非还设置了`NO_PROPAGATE_INHERIT_ACE`位标志,否则继承的ACE是可继承的。 | 129 | | No inheritance flags set | 对子容器或非容器对象没有影响。 | 130 | 131 | 如果继承的ACE是子对象的有效ACE,则系统会将所有通用权限映射到子对象的特定权限。类似地,系统将诸如`CREATOR_OWNER`之类的通用安全标识符(SID)映射到适当的SID。如果继承的ACE是仅继承的ACE,则任何通用权限或通用SID均保持不变,以便在下一代子对象继承ACE时可以正确地映射它们。 132 | 133 | 对于容器对象继承既对容器有效又可由其后代继承的ACE的情况,容器可以继承两个ACE。如果可继承ACE包含通用信息,则会发生这种情况。容器继承了一个仅继承ACE,该ACE包含了一般信息,而一个仅有效ACE映射了一般信息。 134 | 135 | 特定于对象的ACE具有`InheritedObjectType`成员,该成员可以包含GUID来标识可以继承ACE的对象的类型。 136 | 137 | 如果未指定`InheritedObjectType GUID`,则特定于对象的ACE的继承规则与标准ACE的继承规则相同。 138 | 139 | 如果指定了`InheritedObjectType GUID`,则如果设置了`OBJECT_INHERIT_ACE`,则可以由与GUID匹配的对象继承ACE,如果设置了`CONTAINER_INHERIT_ACE`,则可以由与GUID匹配的容器继承。注意当前只有DS对象支持特定于对象的ACE,并且DS将所有对象类型都视为容器。 140 | 141 | ### **ACE控制对对象属性的访问** 142 | 143 | 目录服务(DS)对象的任意访问控制列表(DACL)可以包含访问控制项(ACE)的层次结构,如下所示: 144 | 145 | 1. 保护对象本身的ACE 146 | 2. 特定对象的ACE,可保护对象上的指定属性集 147 | 3. 特定对象的ACE,用于保护对象上的指定属性 148 | 149 | 在此层次结构中,较高级别授予或拒绝的权利也适用于较低级别。例如,如果属性集上的特定于对象的ACE允许受托者获得`ADS_RIGHT_DS_READ_PROP`权限,则受托者具有对该属性集所有属性的隐式读取访问权限。同样,在对象本身上的ACE允许`ADS_RIGHT_DS_READ_PROP`访问,使受托者可以对对象的所有属性进行读取访问。 150 | 151 | 下图显示了假设的DS对象的树及其属性集和属性: 152 | 153 | ![directory service object hierarchy](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/accctrl2.png) 154 | 155 | 假设希望允许以下访问此DS对象的属性: 156 | 157 | * 允许A组对所有对象属性的读/写权限 158 | * 允许其他所有人对除属性D之外的所有属性具有读/写权限 159 | 160 | 为此,如下表所示,在对象的DACL中设置ACE: 161 | 162 | | 受托者 | 对象 GUID | ACE 类型 | 访问权限 | 163 | | :--- | :--- | :--- | :---: | 164 | | Group A | None | Access-allowed ACE | ADS\_RIGHT\_DS\_READ\_PROP \| ADS\_RIGHT\_DS\_WRITE\_PROP | 165 | | Everyone | Property Set 1 | Access-allowed object ACE | ADS\_RIGHT\_DS\_READ\_PROP \| ADS\_RIGHT\_DS\_WRITE\_PROP | 166 | | Everyone | Property C | Access-allowed object ACE | ADS\_RIGHT\_DS\_READ\_PROP \| ADS\_RIGHT\_DS\_WRITE\_PROP | 167 | 168 | 组A的ACE没有对象GUID,这意味着它允许访问所有对象的属性。属性集1的ACE允许所有人访问属性A和B。另一个属性集ACE允许所有人访问属性C。注意尽管此DACL没有任何访问被拒绝的ACE,但它隐式拒绝了属性D,与除A组之外的所有人访问。 169 | 170 | 当用户尝试访问对象的属性时,系统将按顺序检查ACE,直到显式授予,拒绝所请求的访问,或者不再有ACE,在这种情况下,访问将被隐式拒绝。 171 | 172 | 该方式的适用性评估: 173 | 174 | * 适用于对象本身的ACE 175 | * 适用于包含正在访问的属性的属性集的特定于对象的ACE 176 | * 适用于所访问属性的特定于对象的ACE 177 | 178 | 系统将忽略适用于其他属性集或属性的特定于对象的ACE。 179 | 180 | ### ACE Header 结构体 181 | 182 | ```text 183 | typedef struct _ACE_HEADER { 184 | BYTE AceType; 185 | BYTE AceFlags; 186 | WORD AceSize; 187 | } ACE_HEADER; 188 | ``` 189 | 190 | 191 | 192 | | 值 | 含义 | 193 | | :--- | :--- | 194 | | **ACCESS\_ALLOWED\_ACE\_TYPE** | 使用[ACCESS\_ALLOWED\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_allowed_ace)结构的允许访问的ACE 。 | 195 | | **ACCESS\_ALLOWED\_CALLBACK\_ACE\_TYPE** | 使用[ACCESS\_ALLOWED\_CALLBACK\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_allowed_callback_ace)结构的允许访问的回调ACE 。 | 196 | | **ACCESS\_ALLOWED\_CALLBACK\_OBJECT\_ACE\_TYPE** | 使用[ACCESS\_ALLOWED\_CALLBACK\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_allowed_callback_object_ace)结构的特定于对象的允许访问的回调ACE 。 | 197 | | **ACCESS\_ALLOWED\_COMPOUND\_ACE\_TYPE** | 保留。 | 198 | | **ACCESS\_ALLOWED\_OBJECT\_ACE\_TYPE** | 使用[ACCESS\_ALLOWED\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_allowed_object_ace)结构的特定于对象的允许访问的ACE 。 | 199 | | **ACCESS\_DENIED\_ACE\_TYPE** | 使用[ACCESS\_DENIED\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_denied_ace)结构的拒绝访问的ACE 。 | 200 | | **ACCESS\_DENIED\_CALLBACK\_ACE\_TYPE** | 使用[ACCESS\_DENIED\_CALLBACK\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_denied_callback_ace)结构的拒绝访问的回调ACE 。 | 201 | | **ACCESS\_DENIED\_CALLBACK\_OBJECT\_ACE\_TYPE** | 使用[ACCESS\_DENIED\_CALLBACK\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_denied_callback_ace)结构的特定于对象的访问被拒绝的回调ACE 。 | 202 | | **ACCESS\_DENIED\_OBJECT\_ACE\_TYPE** | 使用[ACCESS\_DENIED\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-access_denied_object_ace)结构的特定于对象的拒绝访问的ACE 。 | 203 | | **ACCESS\_MAX\_MS\_ACE\_TYPE** | 与SYSTEM\_ALARM\_OBJECT\_ACE\_TYPE相同。 | 204 | | **ACCESS\_MAX\_MS\_V2\_ACE\_TYPE** | 与SYSTEM\_ALARM\_ACE\_TYPE相同。 | 205 | | **ACCESS\_MAX\_MS\_V3\_ACE\_TYPE** | 保留。 | 206 | | **ACCESS\_MAX\_MS\_V4\_ACE\_TYPE** | 与SYSTEM\_ALARM\_OBJECT\_ACE\_TYPE相同。 | 207 | | **ACCESS\_MAX\_MS\_OBJECT\_ACE\_TYPE** | 与SYSTEM\_ALARM\_OBJECT\_ACE\_TYPE相同。 | 208 | | **ACCESS\_MIN\_MS\_ACE\_TYPE** | 与ACCESS\_ALLOWED\_ACE\_TYPE相同。 | 209 | | **ACCESS\_MIN\_MS\_OBJECT\_ACE\_TYPE** | 与ACCESS\_ALLOWED\_OBJECT\_ACE\_TYPE相同。 | 210 | | **SYSTEM\_ALARM\_ACE\_TYPE** | 保留以备将来使用。使用[SYSTEM\_ALARM\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_alarm_ace)结构的系统警报ACE 。 | 211 | | **SYSTEM\_ALARM\_CALLBACK\_ACE\_TYPE** | 保留以备将来使用。使用[SYSTEM\_ALARM\_CALLBACK\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_alarm_callback_ace)结构的系统警报回调ACE 。 | 212 | | **SYSTEM\_ALARM\_CALLBACK\_OBJECT\_ACE\_TYPE** | 保留以备将来使用。使用[SYSTEM\_ALARM\_CALLBACK\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_alarm_callback_object_ace)结构的特定于对象的系统警报回调ACE 。 | 213 | | **SYSTEM\_ALARM\_OBJECT\_ACE\_TYPE** | 保留以备将来使用。使用[SYSTEM\_ALARM\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_alarm_object_ace)结构的特定于对象的系统警报ACE 。 | 214 | | **SYSTEM\_AUDIT\_ACE\_TYPE** | 使用[SYSTEM\_AUDIT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_audit_ace)结构的系统审核ACE 。 | 215 | | **SYSTEM\_AUDIT\_CALLBACK\_ACE\_TYPE** | 使用[SYSTEM\_AUDIT\_CALLBACK\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_audit_callback_ace)结构的系统审核回调ACE 。 | 216 | | **SYSTEM\_AUDIT\_CALLBACK\_OBJECT\_ACE\_TYPE** | 使用[SYSTEM\_AUDIT\_CALLBACK\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_audit_callback_object_ace)结构的特定于对象的系统审核回调ACE 。 | 217 | | **SYSTEM\_AUDIT\_OBJECT\_ACE\_TYPE** | 使用[SYSTEM\_AUDIT\_OBJECT\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_alarm_object_ace)结构的特定于对象的系统审核ACE 。 | 218 | | **SYSTEM\_MANDATORY\_LABEL\_ACE\_TYPE**0x11 | 使用[SYSTEM\_MANDATORY\_LABEL\_ACE](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-system_mandatory_label_ace)结构的强制标签ACE 。 | 219 | 220 | AceFlags: 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 235 | 236 | 237 | 238 | 240 | 243 | 244 | 245 | 247 | 251 | 252 | 253 | 255 | 256 | 257 | 258 | 260 | 261 | 262 | 263 | 265 | 269 | 270 | 271 | 273 | 274 | 275 | 276 |
含义
CONTAINER_INHERIT_ACE 234 | 作为容器的子对象(例如目录)继承ACE作为有效ACE。除非还设置了NO_PROPAGATE_INHERIT_ACE位标志,否则继承的ACE是可继承的。
FAILED_ACCESS_ACE_FLAG 239 | 与系统访问控制列表(SACL)中的 241 | 系统审核ACE一起使用,以为失败的访问尝试生成审核消息。
INHERIT_ONLY_ACE 246 | 248 |

指示仅继承的ACE,它不控制对其附加对象的访问。如果未设置此标志,则ACE是有效的ACE,它控制对其附加对象的访问。

249 |

有效ACE和仅继承ACE均可被继承,具体取决于其他继承标志的状态。

250 |
INHERITED_ACE 254 | 表示ACE已被继承。当系统将继承的ACE传播到子对象时,系统会将其设置。
NO_PROPAGATE_INHERIT_ACE 259 | 如果ACE被子对象继承,则系统清除继承的ACE中的OBJECT_INHERIT_ACE和CONTAINER_INHERIT_ACE标志。这样可以防止ACE被后续的对象继承。
OBJECT_INHERIT_ACE 264 | 266 |

非容器子对象继承ACE作为有效ACE。

267 |

对于作为容器的子对象,除非还设置了NO_PROPAGATE_INHERIT_ACE位标志,否则ACE将作为仅继承ACE进行继承。

268 |
SUCCESSFUL_ACCESS_ACE_FLAG 272 | 与SACL中的系统审核ACE一起使用,以生成成功访问尝试的审核消息。
277 | 278 | ## \*\*\*\* 279 | 280 | -------------------------------------------------------------------------------- /sid-strings.md: -------------------------------------------------------------------------------- 1 | # (三)SID字符串 2 | 3 | ## SID字符串 4 | 5 | 在安全描述符定义语言(SDDL)中,安全描述符字符串将SID字符串用于安全描述符的以下部分: 6 | 7 | * Owner 8 | * Primary group 9 | * The [trustee](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/trustees) in an ACE 10 | 11 | 安全描述符字符串中的SID字符串可以使用SID的标准字符串表示形式(S-R-I-S-S)或Sddl.h中定义的字符串常量之一。 12 | 13 | 在Sddl.h中定义了以下用于常见SID的SID字符串常量。 14 | 15 | | SDDL SID 字符串 | Sddl.h 中的长度 | 帐户别名和相应的RID | 16 | | :--- | :--- | :--- | 17 | | "AN" | SDDL\_ANONYMOUS | 匿名登录。相应的RID为SECURITY\_ANONYMOUS\_LOGON\_RID | 18 | | "AO" | SDDL\_ACCOUNT\_OPERATORS | 帐户操作员。相应的RID为DOMAIN\_ALIAS\_RID\_ACCOUNT\_OPS。 | 19 | | "AU" | SDDL\_AUTHENTICATED\_USERS | 经过身份验证的用户。相应的RID是SECURITY\_AUTHENTICATED\_USER\_RID。 | 20 | | "BA" | SDDL\_BUILTIN\_ADMINISTRATORS | 内置管理员。相应的RID是DOMAIN\_ALIAS\_RID\_ADMINS。 | 21 | | "BG" | SDDL\_BUILTIN\_GUESTS | 内置来宾。相应的RID是DOMAIN\_ALIAS\_RID\_GUESTS。 | 22 | | "BO" | SDDL\_BACKUP\_OPERATORS | 备份运算符。相应的RID是DOMAIN\_ALIAS\_RID\_BACKUP\_OPS。 | 23 | | "BU" | SDDL\_BUILTIN\_USERS | 内置用户。相应的RID是DOMAIN\_ALIAS\_RID\_USERS。 | 24 | | "CA" | SDDL\_CERT\_SERV\_ADMINISTRATORS | 证书发布者。相应的RID是DOMAIN\_GROUP\_RID\_CERT\_ADMINS。 | 25 | | "CD" | SDDL\_CERTSVC\_DCOM\_ACCESS | 可以使用分布式组件对象模型(DCOM)连接到证书颁发机构的用户。相应的RID是DOMAIN\_ALIAS\_RID\_CERTSVC\_DCOM\_ACCESS\_GROUP。 | 26 | | "CG" | SDDL\_CREATOR\_GROUP | 创作者组。相应的RID是SECURITY\_CREATOR\_GROUP\_RID。 | 27 | | "CO" | SDDL\_CREATOR\_OWNER | 创作者所有者。相应的RID是SECURITY\_CREATOR\_OWNER\_RID。 | 28 | | "DA" | SDDL\_DOMAIN\_ADMINISTRATORS | 域管理员。相应的RID为DOMAIN\_GROUP\_RID\_ADMINS。 | 29 | | "DC" | SDDL\_DOMAIN\_COMPUTERS | 域计算机。相应的RID是DOMAIN\_GROUP\_RID\_COMPUTERS。 | 30 | | "DD" | SDDL\_DOMAIN\_DOMAIN\_CONTROLLERS | 域控制器。相应的RID是DOMAIN\_GROUP\_RID\_CONTROLLERS。 | 31 | | "DG" | SDDL\_DOMAIN\_GUESTS | 域来宾。相应的RID是DOMAIN\_GROUP\_RID\_GUESTS。 | 32 | | "DU" | SDDL\_DOMAIN\_USERS | 域用户。相应的RID是DOMAIN\_GROUP\_RID\_USERS。 | 33 | | "EA" | SDDL\_ENTERPRISE\_ADMINS | 企业管理员。相应的RID为DOMAIN\_GROUP\_RID\_ENTERPRISE\_ADMINS。 | 34 | | "ED" | SDDL\_ENTERPRISE\_DOMAIN\_CONTROLLERS | 企业域控制器。相应的RID是SECURITY\_SERVER\_LOGON\_RID。 | 35 | | "HI" | SDDL\_ML\_HIGH | 高诚信度。相应的RID是SECURITY\_MANDATORY\_HIGH\_RID。 | 36 | | "IU" | SDDL\_INTERACTIVE | 交互式登录的用户。这是在以交互方式登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_INTERACTIVE。相应的RID是SECURITY\_INTERACTIVE\_RID。 | 37 | | "LA" | SDDL\_LOCAL\_ADMIN | 本地管理员。相应的RID是DOMAIN\_USER\_RID\_ADMIN。 | 38 | | "LG" | SDDL\_LOCAL\_GUEST | 当地客人。相应的RID为DOMAIN\_USER\_RID\_GUEST。 | 39 | | "LS" | SDDL\_LOCAL\_SERVICE | 本地服务帐户。相应的RID是SECURITY\_LOCAL\_SERVICE\_RID。 | 40 | | "LW" | SDDL\_ML\_LOW | 完整性等级低。相应的RID是SECURITY\_MANDATORY\_LOW\_RID。 | 41 | | "ME" | SDDL\_MLMEDIUM | 中等完整性级别。相应的RID是SECURITY\_MANDATORY\_MEDIUM\_RID。 | 42 | | "MU" | SDDL\_PERFMON\_USERS | 性能监视器用户。 | 43 | | "NO" | SDDL\_NETWORK\_CONFIGURATION\_OPS | 网络配置运营商。相应的RID是DOMAIN\_ALIAS\_RID\_NETWORK\_CONFIGURATION\_OPS。 | 44 | | "NS" | SDDL\_NETWORK\_SERVICE | 网络服务帐户。相应的RID是SECURITY\_NETWORK\_SERVICE\_RID。 | 45 | | "NU" | SDDL\_NETWORK | 网络登录用户。这是在通过网络登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_NETWORK。相应的RID是SECURITY\_NETWORK\_RID。 | 46 | | "PA" | SDDL\_GROUP\_POLICY\_ADMINS | 组策略管理员。相应的RID为DOMAIN\_GROUP\_RID\_POLICY\_ADMINS。 | 47 | | "PO" | SDDL\_PRINTER\_OPERATORS | 打印机操作员。相应的RID是DOMAIN\_ALIAS\_RID\_PRINT\_OPS。 | 48 | | "PS" | SDDL\_PERSONAL\_SELF | 主要自我。相应的RID是SECURITY\_PRINCIPAL\_SELF\_RID。 | 49 | | "PU" | SDDL\_POWER\_USERS | 超级用户。相应的RID是DOMAIN\_ALIAS\_RID\_POWER\_USERS。 | 50 | | "RC" | SDDL\_RESTRICTED\_CODE | 受限制的代码。这是使用CreateRestrictedToken函数创建的受限令牌。相应的RID为SECURITY\_RESTRICTED\_CODE\_RID。 | 51 | | "RD" | SDDL\_REMOTE\_DESKTOP | 终端服务器用户。相应的RID是DOMAIN\_ALIAS\_RID\_REMOTE\_DESKTOP\_USERS。 | 52 | | "RE" | SDDL\_REPLICATOR | 复制器。相应的RID是DOMAIN\_ALIAS\_RID\_REPLICATOR。 | 53 | | "RO" | SDDL\_ENTERPRISE\_RO\_DCs | 企业只读域控制器。相应的RID为DOMAIN\_GROUP\_RID\_ENTERPRISE\_READONLY\_DOMAIN\_CONTROLLERS。 | 54 | | "RS" | SDDL\_RAS\_SERVERS | RAS服务器组。相应的RID是DOMAIN\_ALIAS\_RID\_RAS\_SERVERS。 | 55 | | "RU" | SDDL\_ALIAS\_PREW2KCOMPACC | 为使用与Windows 2000之前的操作系统兼容的应用程序的帐户授予权限的别名。相应的RID为DOMAIN\_ALIAS\_RID\_PREW2KCOMPACCESS。 | 56 | | "SA" | SDDL\_SCHEMA\_ADMINISTRATORS | 架构管理员。相应的RID是DOMAIN\_GROUP\_RID\_SCHEMA\_ADMINS。 | 57 | | "SI" | SDDL\_ML\_SYSTEM | 系统完整性级别。相应的RID是SECURITY\_MANDATORY\_SYSTEM\_RID。 | 58 | | "SO" | SDDL\_SERVER\_OPERATORS | 服务器操作员。相应的RID是DOMAIN\_ALIAS\_RID\_SYSTEM\_OPS。 | 59 | | "SU" | SDDL\_SERVICE | 服务登录用户。这是在作为服务登录时添加到进程令牌中的组标识符。相应的登录类型为LOGON32\_LOGON\_SERVICE。相应的RID是SECURITY\_SERVICE\_RID。 | 60 | | "SY" | SDDL\_LOCAL\_SYSTEM | 本地系统。相应的RID是SECURITY\_LOCAL\_SYSTEM\_RID。 | 61 | | "WD" | SDDL\_EVERYONE | 每个人。相应的RID是SECURITY\_WORLD\_RID。 | 62 | 63 | `ConvertSidToStringSid`和`ConvertStringSidToSid`函数始终使用标准SID字符串表示法,并且不支持SDDL SID字符串常量。 64 | 65 | -------------------------------------------------------------------------------- /wu-fang-wen-quan-xian-yu-quan-xian-ma.md: -------------------------------------------------------------------------------- 1 | # (五)访问权限与权限码 2 | 3 | ## **访问权限和访问掩码** 4 | 5 | 访问权限是一个位标志,它对应于线程可以在可保护对象上执行的一组特定操作。例如,注册表项具有`KEY_SET_VALUE`访问权限,这对应于线程在项下设置值的能力。如果线程尝试对某个对象执行操作,但没有对该对象的必要访问权限,则系统不会执行该操作。 6 | 7 | 访问掩码是一个32位的值,其位与对象支持的访问权限相对应。所有Windows安全对象均使用访问掩码格式,该格式包含用于以下类型的访问权限的位: 8 | 9 | * 通用访问权限 10 | * 标准访问权限 11 | * SACL访问权限 12 | * 目录服务(域)访问权限 13 | 14 | 当线程尝试打开对象的句柄时,该线程通常会指定访问掩码以请求一组访问权限。例如,需要设置和查询注册表项的值的应用程序可以通过使用访问掩码来请求`KEY_SET_VALUE`和`KEY_QUERY_VALUE`访问权限来打开注册表项。 15 | 16 | 下表显示了用于处理每种安全对象类型的安全信息的功能。这就是前两节ACL修改中会使用到的对象,以及其安全信息的资料。 17 | 18 | | Object type | Security descriptor functions | 19 | | :--- | :--- | 20 | | [Files or directories](https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-security-and-access-rights) on an NTFS file system | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 21 | | [Named pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/named-pipe-security-and-access-rights)[Anonymous pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/anonymous-pipe-security-and-access-rights) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 22 | | Console screen buffers | Not supported. | 23 | | [Processes](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-security-and-access-rights)[Threads](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-security-and-access-rights) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 24 | | [File-mapping objects](https://docs.microsoft.com/en-us/windows/desktop/Memory/file-mapping-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 25 | | [Access tokens](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/access-rights-for-access-token-objects) | [**SetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-setkernelobjectsecurity), [**GetKernelObjectSecurity**](https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getkernelobjectsecurity) | 26 | | Window-management objects \([window stations](https://docs.microsoft.com/en-us/windows/desktop/winstation/window-station-security-and-access-rights) and [desktops](https://docs.microsoft.com/en-us/windows/desktop/winstation/desktop-security-and-access-rights)\) | [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 27 | | [Registry keys](https://docs.microsoft.com/en-us/windows/desktop/SysInfo/registry-key-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 28 | | [Windows services](https://docs.microsoft.com/en-us/windows/desktop/Services/service-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 29 | | Local or remote printers | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 30 | | Network shares | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 31 | | [Interprocess synchronization objects](https://docs.microsoft.com/en-us/windows/desktop/Sync/synchronization-object-security-and-access-rights) \(events, mutexes, semaphores, and waitable timers\) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 32 | | [Job objects](https://docs.microsoft.com/en-us/windows/desktop/ProcThread/job-object-security-and-access-rights) | [**GetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getnamedsecurityinfoa), [**SetNamedSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setnamedsecurityinfoa), [**GetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-getsecurityinfo), [**SetSecurityInfo**](https://docs.microsoft.com/en-us/windows/desktop/api/Aclapi/nf-aclapi-setsecurityinfo) | 33 | 34 | ### **访问掩码格式** 35 | 36 | 所有安全对象都使用下图所示的访问掩码格式来安排其访问权限。 37 | 38 | ![access mask format](https://docs.microsoft.com/zh-cn/windows/win32/secauthz/images/accctrl4.png) 39 | 40 | 在这种格式中,低16位用于特定对象的访问权限,后8位用于标准访问权限,这些权限适用于大多数类型的对象,而4个高位用于指定通用访问权限每种对象类型可以映射到一组标准和特定于对象的权限。 `ACCESS_SYSTEM_SECURITY`位对应于访问对象的SACL的权限。 41 | 42 | ### **通用访问权限** 43 | 44 | 全对象使用访问掩码格式,其中四个高位指定通用访问权限。每种可保护对象的类型都将这些位映射到一组其标准和特定于对象的访问权限。(也就是说通用权限是由标准位和特殊位映射出来的)例如,Windows文件对象将`GENERIC_READ`位映射到`READ_CONTROL`和`SYNCHRONIZE`标准访问权限以及`FILE_READ_DATA`,`FILE_READ_EA`和`FILE_READ_ATTRIBUTES`这三个对象特定的访问权限。其他类型的对象将`GENERIC_READ`位映射到适合该类型对象的任何访问权限集。 45 | 46 | 可以使用通用访问权限来指定打开对象的句柄时所需的访问类型。会比指定所有相应的标准和特定权限要简单。 47 | 48 | 下表显示了为通用访问权限定义的常量。 49 | 50 | | 常量 | 通用含义 | 51 | | :--- | :--- | 52 | | GENERIC\_ALL | All possible access rights | 53 | | GENERIC\_EXECUTE | Execute access | 54 | | GENERIC\_READ | Read access | 55 | | GENERIC\_WRITE | Write access | 56 | 57 | ### **标准访问权限** 58 | 59 | 每种类型的可保护对象都有一组访问权限,这些访问权限对应于特定于该类型对象的操作。除了这些特定于对象的访问权限之外,还有一组标准访问权限,它们对应于大多数类型的可保护对象的通用操作。 60 | 61 | 访问掩码格式包括一组用于标准访问权限的位。 Winnt.h中定义了以下Windows标准访问权限常量。 62 | 63 | | 常量 | 含义 | 64 | | :--- | :--- | 65 | | DELETE | 删除对象的权利 | 66 | | READ\_CONTROL | 有权读取对象的安全描述符中的信息,但不包括系统访问控制列表(SACL)中的信息。 | 67 | | SYNCHRONIZE | 使用对象进行同步的权利。这使线程可以等待,直到对象处于信号状态。某些对象类型不支持此访问权限。 | 68 | | WRITE\_DAC | 修改对象的安全描述符中的任意访问控制列表(DACL)的权限。 | 69 | | WRITE\_OWNER | 在对象的安全描述符中更改所有者的权利。 | 70 | 71 | Winnt.h还定义了标准访问权限常量的以下组合 72 | 73 | | 常量 | 含义 | 74 | | :--- | :--- | 75 | | STANDARD\_RIGHTS\_ALL | 合并DELETE,READ\_CONTROL,WRITE\_DAC,WRITE\_OWNER和SYNCHRONIZE访问 | 76 | | STANDARD\_RIGHTS\_EXECUTE | 当前定义为等于READ\_CONTROL。 | 77 | | STANDARD\_RIGHTS\_READ | 当前定义为等于READ\_CONTROL。 | 78 | | STANDARD\_RIGHTS\_REQUIRED | 合并DELETE,READ\_CONTROL,WRITE\_DAC和WRITE\_OWNER访问。 | 79 | | STANDARD\_RIGHTS\_WRITE | 当前定义为等于READ\_CONTROL | 80 | 81 | ### **SACL访问权限** 82 | 83 | `ACCESS_SYSTEM_SECURITY`访问权限控制在对象的安全描述符中获取或设置SACL的能力。仅当在请求线程的访问令牌中启用`SE_SECURITY_NAME`特权时,系统才会授予此访问权限。 84 | 85 | 访问对象的SACL : 86 | 87 | 1. 调用`AdjustTokenPrivileges`函数以启用`SE_SECURITY_NAME`特权。 88 | 2. 打开对象的句柄时,请求`ACCESS_SYSTEM_SECURITY`访问权限。 89 | 3. 通过使用诸如`GetSecurityInfo`或`SetSecurityInfo`之类的函数来获取或设置对象的SACL。 90 | 4. 调用`AdjustTokenPrivileges`以禁用`SE_SECURITY_NAME`特权 91 | 92 | 要使用`GetNamedSecurityInfo`或`SetNamedSecurityInfo`函数访问SACL,请启用`SE_SECURITY_NAME`特权。该函数在内部请求访问权限。 93 | 94 | `ACCESS_SYSTEM_SECURITY`访问权限在DACL中无效,因为DACL不控制对SACL的访问。但是,您可以在SACL中使用`ACCESS_SYSTEM_SECURITY`访问权限来审核使用该访问权限的尝试。 95 | 96 | ### **域服务访问权限** 97 | 98 | 每个`Active Directory`对象都有一个分配给它的安全描述符。可以在这些安全描述符中设置特定于目录服务对象的一组受托者权限。下表列出了这些权利也对应域服务ACE的权限图。 99 | 100 | ![域服务ACE编辑器](.gitbook/assets/image%20%2814%29.png) 101 | 102 | | 权限 | Meaning | 103 | | :--- | :--- | 104 | | ACTRL\_DS\_OPEN | 打开DS对象 | 105 | | ACTRL\_DS\_CREATE\_CHILD | 创建子DS对象 | 106 | | ACTRL\_DS\_DELETE\_CHILD | 删除子DS对象 | 107 | | ACTRL\_DS\_LIST | 枚举DS对象 | 108 | | ACTRL\_DS\_READ\_PROP | 读取DS对象的属性 | 109 | | ACTRL\_DS\_WRITE\_PROP | 写入DS对象的属性 | 110 | | ACTRL\_DS\_SELF | 仅在执行对象支持的经过验证的权限检查后才允许访问。该标志可以单独用于执行对象的所有已验证权限检查,也可以与特定已验证权限的标识符组合以仅执行该检查。 | 111 | | ACTRL\_DS\_DELETE\_TREE | 删除DS对象树 | 112 | | ACTRL\_DS\_LIST\_OBJECT | 列出DS对象树 | 113 | | ACTRL\_DS\_CONTROL\_ACCESS | 仅在执行对象支持的扩展权限检查之后才允许访问。该标志可以单独用于对对象执行所有扩展权限检查,也可以与特定扩展权限的标识符组合以仅执行该检查。 | 114 | 115 | ### **请求对对象的访问权限** 116 | 117 | 当您打开对象的句柄时,返回的句柄具有对该对象的访问权限的某种组合。某些功能(例如`CreateSemaphore`)不需要特定的请求访问权限集。这些功能总是尝试打开手柄以进行完全访问。其他功能,例如`CreateFile`和`OpenProcess`,允许您指定所需的访问权限集。您应该仅请求所需的访问权限,而不是为完全访问打开句柄。这样可以防止意外使用该句柄,并增加了如果对象的DACL仅允许有限的访问,则访问请求成功的机会。 118 | 119 | 使用通用访问权限来指定打开对象的句柄时所需的访问类型。这通常比指定所有相应的标准和特定权限要简单。或者,使用`MAXIMUM_ALLOWED`常量请求以对调用者有效的所有访问权限打开对象。 120 | 121 | 122 | 123 | --------------------------------------------------------------------------------