深入解析Active Directory访问检查机制与技术实现

本文详细探讨了Active Directory的访问检查技术,包括安全描述符结构、对象ACE机制、Authz API的使用方法,以及通过PowerShell模块进行AD安全审计的实际操作和结果解读。

Active Directory访问检查机制

与许多Windows相关技术类似,Active Directory使用安全描述符和访问检查流程来确定用户对目录各部分的访问权限。目录中的每个对象都包含一个nTSecurityDescriptor属性,用于存储安全描述符的二进制表示形式。当用户通过LDAP访问对象时,将使用远程用户的令牌和安全描述符来确定他们是否有权执行所请求的操作。

安全描述符配置不当是常见的错误配置,可能导致整个域被攻陷。因此,管理员能够发现并修复安全弱点至关重要。遗憾的是,Microsoft没有为管理员提供审计AD安全性的方法,至少在我知道的任何默认工具中都没有。虽然有第三方工具(如Bloodhound)可以离线执行此分析,但从其检查实现来看,它们往往不使用真正的访问检查API,因此可能会遗漏一些错误配置。

我编写了自己的AD访问检查器,并包含在我的NtObjectManager PowerShell模块中。我用它发现了一些漏洞,例如CVE-2021-34470,这是Exchange对AD的更改引起的问题。这个工具是"在线"工作的,也就是说你需要在域中有一个活跃账户才能运行它,但据我所知,如果你关心特定用户对AD对象的访问权限,它应该能提供最准确的结果。

复杂的过程

访问检查过程主要由Microsoft在[MS-ADTS]: Active Directory技术规范中记录,特别是在5.1.3节。然而,这留下了许多未解答的问题。我也不打算完整介绍它的工作原理,但让我快速概述一下。我假设您对AD的结构及其对象有基本了解。

AD对象包含许多资源,可能需要为特定用户授予或拒绝对这些资源的访问权限。例如,您可能希望允许用户仅创建特定类型的子对象,或仅修改特定属性。Microsoft本可以用多种方式实现安全性,但他们决定扩展ACL格式以引入对象ACE。

例如,ACCESS_ALLOWED_OBJECT_ACE结构在普通的ACCESS_ALLOWED_ACE基础上添加了两个GUID。第一个GUID ObjectType表示ACE适用的对象类型。例如,可以将其设置为属性的架构ID,ACE将仅授予对该属性的访问权限。第二个GUID InheritedObjectType仅在ACL继承期间使用。它表示允许继承此ACE的对象类的架构ID。

要执行访问检查,您需要使用诸如AccessCheckByType之类的API,它支持检查对象ACE。调用API时,您需要传递要检查访问权限的对象类型GUID列表。在处理DACL时,如果ACE的ObjectType GUID不在传递的列表中,它将被忽略。否则,将根据正常的访问检查规则进行处理。

使用Get-AccessibleDsObject和解释结果

让我们最终使用PowerShell命令,这是本文的真正目的。要进行简单检查,请运行以下命令。首次运行时可能需要一些时间来收集有关域和用户的信息。

1
PS> Get-AccessibleDsObject -NamingContext Default

访问检查默认使用当前用户的组,基于他们在DC上的组。这显然很重要,特别是如果当前用户是本地管理员,因为他们不能保证在DC上拥有管理员权限。您可以使用UserSid属性通过SID指定不同的用户进行检查,或使用UserName属性通过名称指定。

基本表格格式的访问检查结果显示五列:对象的通用名、其架构类、被检查的用户以及访问检查是否导致授予任何可修改或可控制的访问权限。可修改指的是能够写入属性或创建/删除子对象等操作。可控制表示授予用户一个或多个可控制的扩展权限,例如允许更改用户密码。

由于这是PowerShell,访问检查结果是一个具有许多属性的对象。在确定授予用户的访问权限时,以下属性可能是最感兴趣的:

  • GrantedAccess - 仅在检查期间指定对象的架构类时授予的访问权限
  • WritableAttributes - 用户可以修改的属性列表
  • WritablePropertySets - 用户可以修改的可写属性集列表
  • GrantedControl - 授予用户的控制扩展权限列表
  • GrantedWriteValidated - 授予用户的写入验证扩展权限列表
  • CreateableClasses - 可以创建的子对象类列表
  • DeletableClasses - 可以删除的子对象类列表
  • DistinguishedName - 对象的完整DN
  • SecurityDescriptor - 用于检查的安全描述符
  • TokenInfo - 检查中使用的用户信息,例如组列表

该命令应该很容易使用。也就是说,它确实带有一些注意事项。首先,您只能使用域账户直接访问AD来使用该命令。从技术上讲,没有理由不能像Bloodhound那样实现收集器并离线进行访问检查,但我没有这样做。我还没有在更复杂的设置(如复杂的域层次结构或RODC)中测试它。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计