本文部分节选于《域渗透攻防指南》,购买请长按如下图片扫码。
由活动目录域服务ADDS控制的域林中的每个域控制器都包含目录分区Directory Partitions。目录分区Directory Partitions也被称为命名上下文(Naming Context,简称NC)。目录分区Directory Partitions是具有独立的复制范围和调度数据的整个目录的连续部分。默认情况下,企业的活动目录域服务包含以下目录分区:
-
域目录分区(Domain Directory Partition):每一个域各有一个域目录分区,域目录分区包含与本地域相关联的目录对象,如用户和计算机等。一个域可以有多个域控制器,一个林可以有多个域。每个域控制器为其本地域存储域目录分区的完整副本,但不存储其他域的域目录分区的副本。如图中的 DC=xie,DC=com 就是域目录分区。
-
配置目录分区(Configuration Directory Partition):配置目录分区包含复制拓扑和必须复制的其他配置数据。整个林内所有域共享一份相同的配置目录分区,林中的每个域控制器都有一个相同的配置目录分区的副本,对配置目录分区所做的任何更改都将复制到林中的每个域控制器。如图中的 CN=Configuration,DC=xie,DC=com 就是配置目录分区。
-
架构目录分区(Schema Directory Partition):架构目录分区包含所有类和所有属性的条目对象,这些条目对象定义了林中可以使用的类和属性的类型。整个林内所有域共享一份相同的架构目录分区,林中的每个域控制器都有一个相同的架构目录分区的副本,对架构目录分区所做的任何更改都将复制到林中的每个域控制器。因为架构目录分区规定了信息的存储方式,因此在执行测试后,应该在必要时通过严格控制的过程对架构目录分区进行更改,以确保不会对林中的其他部分产生不利影响。如图中的 DC=Schema,CN=Configuration,DC=xie,DC=com 就是架构目录分区。
-
应用程序目录分区(Application Directory Partition):从 Windows Server 2003 开始 ,微软引入了应用程序目录分区,其允许用户自定义分区来扩展目录分区。它提供了控制复制范围的能力,并允许以更适合动态数据的方式放置副本。应用程序目录分区会被复制到林中特定的域控中,而不是所有的域控中。如图中的 DC=DomainDnsZones,DC=xie,DC=com 和 DC=ForestDnsZones,DC=xie,DC=com 就是应用程序目录分区。
我们使用ADExplorer连接活动目录数据库就可以看到不同的目录分区,如图所示,用红色框住的分别是域目录分区、配置目录分区和架构目录分区,而后面两个则是应用程序目录分区。
Domain Directory Partition
每一个域各有一个域目录分区(Domain Directory Partition),不同的域有不同的域目录分区,域目录分区包含与本地域相关联的目录对象,如用户和计算机等。我们打开Active Directory用户和计算机查看的默认分区就是域目录分区。
如图所示,打开“Active Directory用户和计算机”查看到的就是域目录分区。
如果使用AD Explorer查看域目录分区的话,默认会比“Active Directory用户和计算机” 查看的东西要多,如图所示:
如下表所示,是域目录分区的顶级对象以及这些顶级对象的说明:
|
|
|
|
|
|
|
|
CN=ForeignSecurityPrincipals
|
|
CN=Managed Service Accounts
|
|
|
各种预配置对象的容器。包括信任对象,DNS对象和组策略对象
|
|
|
Configuration Directory Partition
配置目录分区(Configuration Directory Partition)包含复制拓扑和必须复制的其他配置数据,整个林内所有域共享一份相同的配置目录分区。配置目录分区是林根域的子容器。例如,xie.com 林的配置目录分区为 CN=Configuration,DC=xie,DC=com。使用“Active Directory用户和计算机”默认无法查看到配置目录分区。
如图所示,使用AD Explorer查看配置目录分区。
如下表所示,是配置目录分区的顶级对象以及这些顶级对象的说明:
|
|
|
定义了Active Directory管理单元的各种显示格式
|
|
扩展权限对象的容器,我们将在域内ACL那篇文章里面详解
|
|
|
|
包含每个Naming Context,Application Partitions以及外部LDAP目录引用的对象
|
|
包含位置对象,可以将其与其他对象关联 以表示该对象的位置。
|
|
|
|
|
CN=WellKnown Security Principals
|
包含常用的外部安全性主题的对象,比如Anonymous,Authenticated Users,Everyone等等
|
Schema Directory Partition
架构目录分区(Schema Directory Partition)包含所有类和所有属性的条目对象,这些条目对象定义了林中可以使用的类和属性的类型。整个林内所有域共享一份相同的架构目录分区,林中的每个域控制器都有一个相同的架构目录分区的副本,对架构目录分区所做的任何更改都将复制到林中的每个域控制器。因为架构目录分区规定了信息的存储方式,所以在执行测试后,应该在必要时通过严格控制的过程对架构目录分区进行更改,以确保不会对林的其他部分产生不利影响。与域目录分区和配置目录分区不同的是,架构目录分区不维护容器或组织单位的层次结构。相反,它是具有 Class-Schema ,Attribute-Schema 和 subSchema 对象的单个容器。活动目录数据库中所有类都是Class-Schema的实例,而所有属性是Attribute-Schema的实例。也就是说,架构目录分区定义了Active Directory中使用的所有类和属性。
如图所示,可以看到域内定义的所有属性和类与Class-Schema、Attribute-Schema的关系。
查看Schema Directory Partition
“Active Directory用户和计算机”默认无法查看到架构目录分区,因此如果我们要查看架构目录分区的内容,可以使用AD Explorer。
如图所示,使用ADExplorer连接查看架构目录分区。
也可以使用微软自带的 Active Directory Schema,但是默认没有注册该功能。可以通过运行regsvr32 schmmgmt.dll 命令注册该dll。
如图所示,运行regsvr32 schmmgmt.dll命令。
即可看到schmmgmt.dll注册成功,如图所示。
在弹出的控制台,点击文件——> 添加/删除管理单元(M),如图所示。
然后点击Active Directory架构——>添加——>确定,如图所示:
即可看到活动目录中定义的所有类和属性了,如图所示:
在详细讲架构目录分区之前我们先来讲一下LDAP里面的类和继承,LDAP里面的类和继承,跟开发里面的面向对象一样。
继承,也被称为派生,是指从现有对象类构建新对象类。新对象类称为其父对象的子类。所有结构对象类都直接或间接是抽象对象类Top的子类。在目录中表示的每个对象都属于Top,因此每个条目都必须具有一个对象类属性。创建新类时,必须指定超类。如果不创建现有类的子类,则新类是Top的子类。新类可以从多个现有类继承强制属性和可选属性。但是,任何附加的类都必须由辅助类属性指定。如果将另一个属性添加到具有子类或辅助子类的类中,则在更新Schema缓存后,新属性将自动添加到子类中。这样说起来有点抽象,且看后文分析。
比如域内机器CN=WIN2012R2,CN=Computers,DC=xie,DC=com 在 Active Directory 里面是一个条目对象,里面有众多属性描述该机器对象WIN2012R2的一些信息。
而WIN2012R2条目对象有哪些属性是由他继承的类决定的。条目 CN=WIN2012R2,CN=Computers,DC=xie,DC=com 是类Computer的实例,在objectClass属性中可以看到。
如图所示,可以看到机器WIN2012R2继承自Computer。
而类是可继承的,子类继承父类的所有属性,top类是所有类的父类。所以我们看到objectClass里面的值除了computer之外,还有top、person、organizationPerson、user。这是因为computer是user的子类,user是organizationPerson的子类,organizationPerson是person的子类,而person是top的子类。因此,computer类可以继承top、person、organizationPerson、user的所有属性。
那么,computer类默认到底继承父类的哪些属性呢?这跟父类对象的以下几个属性相关:
-
systemMustContain 和 MustContain 属性里的值是必选继承的属性
-
systemMayContain 和 MayContain 属性里的值是可选继承的属性
我们就以computer类来看。该类继承于 user——>organizationalPerson——>person——>top。
如图查看top类的systemMustContain属性,可以看到top类的强制继承属性如下:
如图查看person类的systemMustContain属性,可以看到person类的强制继承属性为cn
如图查看organizationalPerson类的systemMustContain属性,可以看到organizationalPerson类没有强制属性。
如图查看user类的systemMustContain属性,可以看到user类也没有强制继承属性。
因此通过继承,computer类的强制继承属性有如下:
我们通过Active DirectorySchema查看,就会看到强制继承的属性和可选继承的属性,以及源类是哪个类。
如图所示,可以看到computer类默认强制继承的有如下属性。
为什么会比我们上面查询的强制继承的属性还要多了来自于securityPrincipal源类的sAMAccountName属性和objectSid属性呢以及mailRecipient源类的cn属性呢?
如图所示,可以看到user类有个systemAuxiliaryClass属性(也就是辅助类),而该辅助类属性的值也是需要继承的。因此computer类还需要继承来自辅助类msDS-CloudExtensions、securityPrincipal和mailRecipient的强制继承属性。
查询msDS-CloudExtensions、securityPrincipal和mailRecipient三个辅助类的强制继承属性。
如图,查看msDS-CloudExtensions类的systemMustContain属性,可以看到msDS-CloudExtensions类没有强制继承属性。
如图,查看securityPrincipal类的systemMustContain属性,可以看到securityPrincipal类的强制继承属性为sAMAccountName和objectSid。
如图,查看mailRecipient类的systemMustContain属性,可以看到mailRecipient类的强制继承属性为cn。
综上所述,computer类默认的强制继承属性有如下:
-
-
-
来自top类的nTSecurityDescriptor
-
-
-
-
来自securityPrincipal类的objectSid
-
来自securityPrincipal类的sAMAccountName
这正好与我们通过Active DirectorySchema查询的相符合,如图所示。
Schema Directory Partition中的类
活动目录中所有的类都在Schema Directory Partition内定义了,所有类都是 classSchema 的实例。
-
结构类(Structural):结构类规定了对象实例的基本属性,每个条目属于且仅属于一个结构对象类。前面说过域内每个条目都是类的实例,这个类必须是结构类,结构类是唯一可以在目录中有实例的类,结构类可以派生于抽象类或其他结构类,可以在结构类定义中包含任意数量的辅助类。
-
抽象类(Abstract):抽象类是用于导生新结构类的模板,他没有实例,只能充当结构类或者抽象类的父类。一个新的抽象类可以从一个现有的抽象类中派生出来,它只为子类提供属性,将对象属性中公共的部分组织在一起。跟面对对象里面的抽象方法一样,比如说top类。
-
辅助类(Auxiliary):辅助类包含一个属性列表,在结构类或抽象类的定义中添加一个辅助类会将辅助类属性添加到实例中。虽然不能实例化辅助类,但是可以从现有的辅助类或抽象类派生出新的辅助类。例如,Security-Principal类是一个辅助类,它从名为Top的父抽象类中派生。虽然不能实例化辅助类,但可以创建一个结构类User的对象,该用户将Security-Principal类作为辅助类。因此,该用户对象将拥有辅助类Security-Principal的属性,Security-Principal类的属性可以帮助系统将用户对象识别为安全帐户。辅助类规定了对象实体的扩展属性。虽然每个条目只属于一个结构对象类,但可以同时属于多个辅助对象类。
注:其实还有个88类,88类不属于上述任何一个类别。88类可以用作抽象类、结构类或辅助类,88 类的类可以继承自所有类。
条目的objectClassCategory属性的count为1说明他是一个结构类,为2说明他是一个抽象类,为3说明他是一个辅助类。
如图所示,Computer类的objectClassCategory的属性为1,说明他是一个结构类。而Computer类的实例就是域内的机器。
如图所示,Top类的objectClassCategory的属性为2,说明他是一个抽象类。
如图所示,Security-Principal类的objectClassCategory的属性为3,说明他是一个辅助类。
Schema Directory Partition中的属性
Schema Directory Partition中除了定义了Active Directory中使用的类之外,还定义了Active Directory中使用的属性。每个属性在Schema Directory Partition内也是一个条目,是类 Attribute-Schema 的实例。
如图所示,查看Attribute-Schema 的属性。
在域内的所有属性必须在这里定义,而这里的条目,最主要的是限定了属性的语法定义,其实就是数据类型。属性的值的数据类型由属性条目的attributeSyntax属性和oMSyntax属性决定。这听起来有点绕口,有点像先有鸡还是先有蛋的感觉,我们往下看。
如图所示,以属性Object-Sid (CN=Object-Sid,CN=Schema,CN=Configuration,DC=xie,DC=com)为例。
他的attributeSyntax属性是2.5.5.17,如图所示。
如图所示,通过查表可以得知Object-Sid属性的值是一个安全辨识符(SID),因此Object-Sid属性的值的数据类型为SID。
如图所示,查看hack对象的objectsid属性的值的数据类型,可以看到确实是sid。
而这里的Object-Sid属性条目的attributeSyntax属性和oMSyntax属性又可以在Schema Directory Partition中找到定义。而attributeSyntax属性条目和oMSyntax属性条目自身又是通过他们自身的attributeSyntax属性和oMSyntax属性来定义数据类型的。
如图所示,查看条目attribute-Syntax的attributeSyntax属性和oMSyntax属性。
如图所示,查看条目oM-Syntax的attributeSyntax属性和oMSyntax属性。
Application Directory Partition
从 Windows Server 2003 开始 ,微软引入了应用程序目录分区(Application Directory Partition),其允许用户自定义分区来扩展目录分区。它提供了控制复制范围的能力,并允许以更适合动态数据的方式放置副本。应用程序目录分区会被复制到林中特定的域控中,而不是所有的域控中。管理员可以创建应用程序目录分区,以将数据存储在他们选择的特定域控制器上。
Application Directory Partitions主要有以下特点:
-
如果用户想要定义一个分区,可以通过Application Directory Partitions。虽然微软也预置了两个Application Directory Partitions,但是Application Directory Partitions的设计更多是为了让用户可以自定义自己的数据。设计Application Partitions最大的用途就是,让用户自己来定义分区。
-
Application Directory Partitions可以存储动态对象。动态对象是具有生存时间(TTL) 值的对象,该值确定它们在被Active Directory自动删除之前将存在多长时间。也就说Application Directory Partitions可以给数据设置个TTL,时间一到,Active Directory就删除该数据。
如图所示,通过ntdsutil创建应用程序目录分区DC=test,DC=xie,DC=com。
如图所示,使用ADExplorer连接活动目录查看应用程序目录分区,可以看到应用程序目录分区DC=test,DC=xie,DC=com。
我们下面具体分析一下条目的一些比较重要的属性。首先看看条目属性的四列分别代表着什么?
如图所示,我们就拿默认的域管理员administrator(CN=Administrator,CN=Users,DC=xie,DC=com)为例。
adminCount属性代表该条目是否是受保护组的对象,如果其值是1的话,就是受保护的;如果其值是0的话,就是不受保护的。
如图所示,这里我们可以看到administrator的adminCount属性为1,说明他是受保护组的对象。具体关于受保护组的对象,我们会在后面的文章中讲解。
badPasswordTime属性的话很好理解,就是该用户最后一次输错密码的时间。
如图所示,这里我们可以看到administrator的badPasswordTime属性为2021/10/16 11:29:34。
badPwdCount属性的话很好理解,就是该用户输错密码的次数。其实可以根据这一属性,来查看哪些用户可能被爆破。
如图所示,administrator的badPwdCount为0,说明没输错过密码。
cn属性的话就是条目的通用名称,不具有唯一性。默认是对象的DN的最后一级子节点的名称。
如图所示,administrator的CN就是为administrator。
description属性的话很好理解,就是对该条目的一个描述。
如图所示,域管理员administrator的描述为“管理计算机(域)的内置帐户”。
distinguishedName属性的话就是该条目的可分辨名称DN,每个对象拥有的distinguishedName属性的值都是唯一的。
如图所示,administrator用户的DN为CN=Administrator,CN=Users,DC=xie,DC=com。
如图所示,可以看到administrator用户最后一次登录时间为2021/10/26 22:12:01。
如图所示,代表administrator用户登录过20次。
如图所示,可以看到administrator所属的组很多,有Group Policy Creator Owners 、Domain Admins、Enterprise Admins、Schema Admins和Administrators。
member属性与memberOf属性相反,意思是该组内有哪些用户。但是由于administrator不是组,因此没有该属性。
我们可以看Domain Admins组的member属性,如图所示,可以看到有administrator用户。
name属性就是条目的名字。如图所示,administrator用户的name属性的值就为administrator。
nTSecurityDescriptor属性的值是这个条目的ACL。
如图所示,可以看到nTSecurityDescriptor属性的值的类型为NTSecurityDescriptor,其值就是该条目的ACL,是用SDDL语言描述的。
其实与用户ACL相关的还有一个属性,就是defaultSecurityDescriptor属性。defaultSecurityDescriptor属性是实例默认的ACL。但是在administrator条目这里没看到这个属性,我们可以在Schema Directory Partition里面查询一下即可看到User类还有一个defaultSecurityDescriptor属性。也就是说,当User类在实例化的时候,没有指定ACL的话,则nTSecurityDescriptor属性的值就为CN=User,CN=Schema,CN=Configuration,DC=xie,DC=com条目的defaultSecurityDescriptor属性的值。如果在实例化的过程中,指定了ACL的话,则nTSecurityDescriptor属性的值就为指定的ACL。
objectClass属性代表该实例对象继承的类有哪些。
如图所示,是administrator对象的objectClass属性,OID代表其值数据类型为OID,4代表其值有4个,而top;person;organizationalPerson;user就是其属性的值。
而objectClass这个属性在Schema Directory Partition里面就有定义,如图所示:
如图所示,通过定义的语法查表可以得知其值的数据类型为String(Object-Identifier),也就是我们看到的OID。
objectGUID属性就是对象的GUID属性的值。
如图所示,可以看到administrator的objectGUID属性为{7B73B1AA-7830-48F7-9106-0BE3FA003BCE}。
objectSid属性代表该条目SID的值,域管理员administrator的SID默认为域SID+500。
如图所示,可以看到administrator的objectSid属性S-1-5-21-域SID-500。
pwdLastSet属性的值就是该用户最后一次修改密码的时间。
如图所示,可以看到administrator的最后一次修改密码时间为2021/11/8 15:11:28。
whenChanged属性就是代表该对象最近一次被改动的时间,比如最近一次密码被修改的时间。
如图所示,可以看到administrator的whenChanged属性为2021/11/8 15:11:28。
whenCreated属性就是代表该对象被创建的时间。
如图所示,可以看到administrator的whenCreated属性为2021/10/16 11:24:44。
非常感谢您读到现在,由于作者的水平有限,编写时间仓促,文章中难免会出现一些错误或者描述不准确的地方,恳请各位师傅们批评指正。如果你想一起学习AD域安全攻防的话,可以加入下面的知识星球一起学习交流。
https://docs.microsoft.com/en-us/windows/win32/adschema/active-directory-schema-site
https://docs.microsoft.com/en-us/windows/win32/ad/naming-contexts-and-partitions
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/f0f1e85a-3ac2-466a-87bf-2a8a1d18e4b8
https://docs.microsoft.com/en-us/windows/win32/adschema/classes
https://docs.microsoft.com/en-us/windows/win32/adschema/attributes
https://docs.microsoft.com/zh-cn/previous-versions/windows/it-pro/windows-server-2003/cc773309(v=ws.10)
原文始发于微信公众号(谢公子学安全):域目录分区Directory Partitions
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
点赞
https://cn-sec.com/archives/1962179.html
复制链接
复制链接
-
左青龙
- 微信扫一扫
-
-
右白虎
- 微信扫一扫
-
评论