注:此篇内容节选自红队笔记的导学服务包。
活动目录 (Active Directory,AD) 是用于Windows网络环境的目录服务。它是一个分布式的、层次化的结构,允许组织中心化管理资源,包括用户、计算机、组、网络设备和文件共享、组策略、服务器和工作站以及信任关系。活动目录在Windows域环境中提供认证和授权功能。像活动目录域服务 (AD DS) 这样的目录服务为组织提供了存储目录数据并使其可供网络上的标准用户和管理员使用的方式。AD DS存储信息,如用户名和密码,并管理授权用户访问此信息所需的权限。它首次随Windows Server 2000发布;近年来越来越多地受到攻击。它设计为向后兼容,许多功能可以说不是“默认安全”的。尤其在大型环境中,它很难被正确管理,容易配置错误。
活动目录的缺陷和错误配置经常可以被用来获得立足点、在内网中横向和纵向移动,以及获得对受保护资源的未授权访问,如数据库、文件共享、源代码等。活动目录本质上是一个对域内所有用户无论权限级别如何都可访问的大型数据库。一个没有额外权限的基础活动目录用户账户就可以用来枚举活动目录中包含的大部分对象,包括域计算机、域用户、域组信息、组织单位 (OUs)、默认域策略、功能域级别 、密码策略、组策略对象 (GPOs)、域信任、访问控制列表 (ACLs)等等。因此,我们必须在尝试攻击它之前了解活动目录的设置和管理基础。
活动目录按层次树状结构排列,顶部是包含一个或多个域的森林,这些域本身可以有嵌套的子域。森林是所有对象处于行政控制之下的安全边界。一个森林可能包含多个域,一个域可能包括进一步的子域或子域。域是一个结构,在其中包含的对象(用户、计算机和组)是可访问的。它有许多内置的组织单位(OUs),如 Domain Controllers
、 Users
、 Computers
,并且可以根据需要创建新的OUs。OUs可能包含对象和子OUs,允许分配不同的组策略。
在一个非常(简化的)高层次上,一个活动目录结构可能如下所示:
RedteamNotes.LOCAL/
├── ADMIN.RedteamNotes.LOCAL
│ ├── GPOs
│ └── OU
│ └── EMPLOYEES
│ ├── COMPUTERS
│ │ └── FILE01
│ ├── GROUPS
│ │ └── HQ Staff
│ └── USERS
│ └── RedteamNotes.Redteam
├── CORP.RedteamNotes.LOCAL
└── DEV.RedteamNotes.LOCAL
在这里,我们可以说 RedteamNotes.LOCAL
是根域,包含了子域(子域或树根域)ADMIN.RedteamNotes.LOCAL
、 CORP.RedteamNotes.LOCAL
和 DEV.RedteamNotes.LOCAL
,以及构成一个域的其他对象,比如用户、组、计算机等,我们将在下面详细展开。在机构复杂的组织中,通常可以看到多个域(或森林)通过信任关系连接在一起。与在当前域中重新创建所有新用户相比,与另一个域/森林建立信任关系通常更快更容易。如果没有适当管理,域信任可能会导致一系列安全问题。
比如两个森林, RedteamNotes.LOCAL
和 Redteam.LOCAL
。两个森林之间是双向信任,意味着 RedteamNotes.LOCAL
中的用户可以访问 Redteam.LOCAL
中的资源,反之亦然。
每个根域下可以有多个子域。根域信任每个子域,但两个森林中的子域不一定建立了信任关系。这意味着,属于 admin.dev.Redteam.local
的用户默认情况下无法对 beijing.corp.RedteamNotes.local
域中的机器进行认证,即使在顶级 RedteamNotes.local
和 Redteam.local
域之间存在双向信任关系。要实现 admin.dev.Redteam.local
和 beijing.corp.RedteamNotes.local
之间的直接通信,需要建立另一个信任关系。
对象可以定义为活动目录环境中的任何资源,如组织单位(OUs)、打印机、用户、域控制器
等。
活动目录中的每个对象都有一组相关联的属性,用于定义给定对象的特性。计算机对象包含诸如主机名和DNS名称等属性。活动目录中的所有属性都有一个关联的LDAP名称,可以在执行LDAP查询时使用,例如 displayName
用于 全名
和 given name
用于 名字
。
活动目录的模式,也可以理解为架构,本质上是任何企业环境的蓝图。它定义了可以存在于活动目录数据库中的对象类型及其相关属性。它列出了与活动目录对象相对应的定义,并保存每个对象的信息。例如,活动目录中的用户属于“user”类别,计算机对象属于“computer”类别等。每个对象都有自己的信息(一些是必须设置的,其他是可选的),存储在属性中。当一个对象从一个类别创建时,被称为实例化,从特定类别创建的对象称为该类别的实例。例如,计算机RNDS01,这个计算机对象是活动目录中“computer”类别的一个实例。
域是计算机、用户、组织单位(OUs)、群组等对象的逻辑组。我们可以将每个域视为国家内的不同城市。域可以完全独立地运作,也可以通过信任关系相连。
森林是活动目录域的集合。它是最高级别的容器,包含所有介绍过的活动目录对象,包括但不限于域、用户、群组、计算机和组策略对象。森林可以包含一个或多个域,可以被视为相对国家的一个省。每个森林独立运作,但可能与其他森林有各种信任关系。
树是以单个根域开始的活动目录域的集合。森林是活动目录树的集合。树中的每个域与其他域共享边界。当一个域被添加到另一个域下时,会形成父子信任关系。同一个森林中的两棵树不能共享名称(命名空间)。假设我们在一个活动目录森林中有两棵树: RedteamNotes.local
和 RedPen.local
。第一棵树的子域可能是 corp.RedteamNotes.local
,而第二棵树的子域可能是 corp.RedPen.local
。树中的所有域共享一个标准的全局编录,其中包含属于该树的所有对象的所有信息。
容器对象保存其他对象,并在目录子树层次结构中有一个定义的位置。
叶对象不包含其他对象,并位于子树层次结构的末端。
GUID 是在创建域用户或群组时分配的唯一的128位值。这个GUID值在企业范围内是唯一的,类似于MAC地址。活动目录创建的每个单个对象都被分配了一个GUID,GUID存储在ObjectGUID
属性中。当查询活动目录对象(如用户、群组、计算机、域、域控制器等)时,我们可以使用PowerShell查询其 objectGUID
值,或通过指定其专有名称、GUID、SID或SAM帐户名来搜索。活动目录使用GUID内部识别对象。通过GUID值搜索活动目录可能是找到你正在寻找的确切对象的最准确可靠的方法,特别是如果全局编录可能包含对象名称的类似匹配项。指定 ObjectGUID
值进行活动目录枚举时,将确保我们获得与我们正在寻找的对象信息最相关的结果。 ObjectGUID
属性 永远
不会改变,并且与对象相关联,只要该对象在域中存在。
安全主体是操作系统可以认证的任何东西,包括用户、计算机帐户,甚至在用户或计算机帐户的上下文中运行的线程/进程(即,在域内的服务帐户上下文中运行的应用程序,如Tomcat)。在活动目录中,安全原则是可以管理对域内其他资源的访问的域对象。我们还可以有本地用户帐户和安全组,用于控制对仅限于该特定计算机的资源的访问。这些不是由活动目录管理的,而是由安全帐户管理器(SAM)管理的。
安全标识符(SID)用作安全主体或安全组的唯一标识符。每个帐户、组或进程都有自己独特的SID,在活动目录环境中,由域控制器发放并存储在安全数据库中。一个SID只能使用一次。即使安全主体被删除,它也永远不能再在该环境中用于识别另一个用户或组。当用户登录时,系统为他们创建一个访问令牌,其中包含用户的SID、授予的权限以及用户所属的任何组的SIDs。每当用户在计算机上执行操作时,系统就会使用此令牌检查权限。还有一些众所周知的SIDs,用于识别通用用户和群组。这些在所有操作系统中都是相同的。一个例子是Everyone 群组。
专有名称(DN)描述了活动目录中对象的完整路径(例如 cn=redpen, ou=IT,ou=Employees, dc=RedteamNotes, dc=local
)。在这个例子中,用户 redpen
在RedteamNotes公司的IT部门工作,他的帐户创建在一个保存公司员工帐户的组织单位(OU)中。通用名称(CN)redpen
只是可以搜索或访问域中用户对象的一种方式。
相对专有名称(RDN)是专有名称中的单个组件,用于从当前层级中的其他对象区分识别对象。在我们的例子中, redpen
是对象的相对专有名称。活动目录不允许在同一个父容器下有两个同名的对象,但可以有两个具有相同RDN的对象,在域中仍然是独一无二的,因为它们有不同的DN。例如,对象 cn=redpen,dc=dev,dc=RedteamNotes,dc=local
会被识别为与cn=redpen,dc=RedteamNotes,dc=local
不同。
sAMAccountName 是用户的登录名。在这里,它只是 redpen
。它必须是唯一的值,且不超过
20个字符。
userPrincipalName 属性是识别活动目录中用户的另一种方式。这个属性由前缀(用户帐户名)
和后缀(域名)组成,格式为 redpen@RedteamNotes.local
。这个属性不是必需的。
在活动目录的早期,如果一个环境中有多个域控制器(DC),它们会争夺哪个DC可以进行更改,有时更改可能无法正确进行。微软随后实施了“最后写入者胜出”策略,但如果最后的更改导致问题,这本身可能引入新的问题。之后,他们引入了一种模型,其中一个单一的“主”DC可以对域进行更改,而其他DC只负责处理身份验证请求。这是一个有缺陷的设计,因为如果主DC宕机,直到其恢复之前,无法对环境进行任何更改。为了解决这一单点故障模型,微软将DC可以担任的各种职责分离为 Flexible Single Master Operation (FSMO)角色。这些角色使得域控制器(DC)能够在不中断地进行用户身份验证和授权(授权和认证)。
FSMO角色共有五个: Schema Master
和 Domain Naming Master
(每个森林一个),Relative ID (RID) Master
(每个域一个), Primary Domain Controller (PDC)Emulator
(每个域一个)和 Infrastructure Master
(每个域一个)。在新的活动目录森林中,所有五个角色都被分配给森林根域中的第一个DC。每当向森林中添加新域时,只有RID Master
、PDC Emulator
和Infrastructure Master
角色被分配给新域。FSMO角色通常在创建域控制器时设置,但系统管理员如有需要可以转移这些角色。这些角色有助于活动目录中的复制顺利运行,并确保关键服务正常运行。
全局编录(GC)是一种存储活动目录森林中所有对象副本的域控制器。GC存储当前域中所有对象的完整副本和森林中其他域的对象的部分副本。标准域控制器保存其域中对象的完整副本,但不包括森林中不同域的对象。GC允许用户和应用程序查找森林中任何域的任何对象的信息。GC是在域控制器上启用的功能,执行:
只读域控制器(RODC) 拥有一个只读的活动目录数据库。在RODC上不缓存任何活动目录账户密码(RODC计算机账户和RODC KRBTGT密码除外)。通过RODC的活动目录数据库、SYSVOL或DNS不会推送任何更改。RODC还包括一个只读DNS服务器,允许管理员角色分离,减少环境中的复制流量,并防止SYSVOL的修改被复制到其他DC。
在活动目录中,当活动目录对象被更新并从一个域控制器传输到另一个域控制器时发生复制。
每当添加DC时,都会创建连接对象以管理它们之间的复制。这些连接由所有DC上存在的知识一致性检查器(KCC)服务创建。复制确保与森林中的所有其他DC同步更改,有助于在某个域控制器失败时创建备份。
服务主体名称(SPN)唯一地标识一个服务实例。它们被Kerberos认证用来将服务实例与登录帐户关联起来,允许客户端应用程序请求服务以对帐户进行认证,而无需知道帐户名称。
组策略对象(GPO)是策略设置的虚拟集合。每个GPO都有一个唯一的GUID。GPO可以包含本地文件系统设置或活动目录设置。GPO设置可以应用于用户和计算机对象。它们可以应用于域中的所有用户和计算机,也可以在OU级别更细致地定义。
访问控制列表(ACL)是应用于对象的访问控制条目(ACE)的有序集合。
ACL中的每个访问控制条目(ACE)标识了受信人(用户帐户、组帐户或登录会话),并列出了允许、拒绝或审计给定受信人的访问权。
DACL定义了哪些安全原则被授予或拒绝对对象的访问;它包含了一系列ACEs。当进程尝试访问一个可保护对象时,系统会检查对象的DACL中的ACEs,以确定是否授予访问权。如果一个对象没有DACL,那么系统将授予所有人完全访问权,但如果DACL没有ACE条目,系统将拒绝所有访问尝试。DACL中的ACEs按顺序检查,直到找到允许请求的权限的匹配项或拒绝访问。
允许管理员记录对受保护对象的访问尝试。ACEs指定导致系统在安全事件日志中生成记录的访问尝试类型。
FQDN是特定计算机或主机的完整名称。它以[主机名].[域名].[顶级域]的格式书写。这用于在DNS的树层次结构中指定对象的位置。FQDN可以用于在活动目录中定位主机,而无需知道IP 地址,就像在浏览器中输入 redteamnotes.com 而不是输入关联的IP地址一样。例如,域RedteamNotes.LOCAL
中的主机 DC01
的FQDN将是 DC01.RedteamNotes.LOCAL
墓碑是活动目录中保存已删除活动目录对象的容器对象。当活动目录中的对象被删除时,该对象会在称为 Tombstone Lifetime
的一段时间内保留,同时 isDeleted
属性被设置为 TRUE
。
一旦对象超过了 Tombstone Lifetime
,它将被完全移除。微软建议墓碑生命周期为180天,以提高备份的有效性,但这个值可能在不同的环境中有所不同。根据DC操作系统版本的不同,此值默认为60天或180天。
如果在没有活动目录回收站的域中删除了一个对象,它将变成墓碑对象。发生这种情况时,该对象将被剥离大多数属性,并在 Deleted Objects
容器中放置 tombstoneLifetime
的持续时间。它可以被恢复,但任何丢失的属性都无法再被恢复。
活动目录回收站首次在Windows Server 2008 R2中引入,以便于恢复已删除的活动目录对象。这使系统管理员更容易恢复对象,避免了从备份中恢复、重启活动目录域服务(AD DS)或重新启动域控制器的需要。当启用活动目录回收站时,任何被删除的对象都会在一段时间内被保留,以便在需要时进行恢复。如果没有指定,对象将在默认值60天内可恢复。使用活动目录回收站的最大优势是,大多数被删除对象的属性被保留下来(与墓碑的区别),这使得将被删除对象完全恢复到其之前状态变得更加容易。
SYSVOL 文件夹或共享存储了域中的公共文件副本,如系统策略、组策略设置、登录/注销脚本,以及通常包含在活动目录环境中执行各种任务的其他类型的脚本。SYSVOL文件夹的内容通过文件复制服务(FRS)复制到环境中的所有DC。您可以在这里阅读更多关于SYSVOL结构的信息。
AdminSDHolder,(Admin Security Descriptor Holder)对象用于管理活动目录中标记为特权的内置组成员的ACL(访问控制列表)。它充当一个容器,持有应用于受保护组成员的安全描述符。SDProp(SD Propagator)进程按计划在PDC仿真器域控制器上运行。当此进程运行时,它会检查受保护组的成员以确保正确的ACL被应用于他们。默认情况下,它每小时运行一次。
例如,假设攻击者能够创建一个恶意的ACL条目,以授予用户对域管理员组成员的某些权利。在这种情况下,除非他们修改AD中的其他设置,否则这些权利将在SDProp进程按设定间隔运行时被移除(并且他们将失去他们希望实现的任何持久化)。
dsHeuristics 属性是一个设置在目录服务对象上的字符串值,用于定义多个森林范围的配置设置。其中一个设置是从受保护组 列表中排除内置组。这个列表中的组通过 AdminSDHolder
对象受到修改保护。如果一个组通过 dsHeuristics
属性被排除,那么当SDProp进程运行时,影响该组的任何更改都不会被还原。这个词是由“DS”(代表 Directory Services)和“heuristics”(启发式,通常用于描述解决问题的方法或策略,特别是在计算领域)组合而成的。
adminCount 属性决定是否由 SDProp
进程保护用户。如果值设置为 0
或未指定,则用户不受保护。如果属性值设置为 value
,则用户受到保护。攻击者通常会在内部环境中寻找adminCount 属性设置为 1
的账户来攻击。这些通常是特权账户,可能会导致进一步的访问或完全的域控制权泄露。
ADUC 是一个常用的图形界面控制台,用于管理活动目录中的用户、群组、计算机和联系人。在 ADUC 中所做的更改也可以通过 PowerShell 完成。
ADSI (Active Directory Service Interfaces)编辑器是一个用于管理活动目录中对象的图形界面工具。它提供了远超 ADUC 的访问权限,可以用来设置或删除对象上的任何属性,添加、移除和移动对象等。它是一个强大的工具,允许用户更深层次地访问 活动目录。使用此工具时需要格外小心,因为这里的更改可能会在活动目录中引起重大问题。
这个属性 保存了对象之前被分配的任何SID(安全标识符)。它通常用于迁移过程中,以便用户在从一个域迁移到另一个域时保持相同的访问权限。如果设置不安全,这个属性可能会被滥用,允许攻击者获得账户在迁移前拥有的先前提升的访问权限,特别是在没有启用SID过滤(或者从用户的访问令牌中移除来自另一个域的、可用于提升访问权限的SID)的情况下。
NTDS.DIT 文件可以被认为是活动目录的核心。它存储在域控制器的 C:\Windows\NTDS\
目录下,是一个存储活动目录数据的数据库,如用户和组对象的信息、组成员关系,以及对攻击者和渗透测试人员最重要的,域中所有用户的密码哈希。一旦实现了完全的域控制权,攻击者可以检索此文件,提取哈希值,并使用它们进行哈希传递攻击,或使用如 Hashcat 之类的工具离线破解,以访问域中的其他资源。如果启用了可逆加密存储密码设置,则 NTDS.DIT 还将存储所有用户在此策略设置后创建或更改密码的明文密码。
虽然很少见,但如果某些组织使用需要使用用户现有密码(而非 Kerberos)进行认证的应用程序或协议,他们可能会启用此设置。
我们经常看到提及活动目录时使用“对象”一词。对象是什么?对象可以定义为活动目录环境中存在的任何资源,如组织单位 (OUs)、打印机、用户、域控制器。
组织的活动目录环境中的用户。用户被认为是 叶子对象,这意味着它们不能包含它们内部的任何其他对象。另一个叶子对象的例子是 Microsoft Exchange 中的邮箱。用户对象被认为是一个安全主体,拥有安全标识符 (SID) 和全局唯一标识符 (GUID)。用户对象有许多可能的属性,如其显示名称、上次登录时间、上次密码更改日期、电子邮件地址、账户描述、经理、地址等。根据特定活动目录环境的设置,当考虑到所有可能的属性时,可能有超过 800 个可能的用户属性,详见此处。这个例子远远超出了大多数环境中标准用户通常填充的范围,但显示了活动目录的庞大和复杂性。它们是攻击者的关键目标,因为即使获得低权限用户的访问权限也可以访问许多对象和资源,并允许对整个域(或森林)进行详细的枚举。
联系人对象通常用于表示外部用户,并包含诸如名字、姓氏、电子邮件地址、电话号码等信息属性。它们是叶子对象,不是安全主体(可保护对象),因此它们没有 SID,只有 GUID。一个例子可能是第三方供应商或客户的联系卡。
打印机对象指活动目录网络内可访问的打印机。像联系人一样,打印机是一个叶子对象,而不是一个安全主体,因此它只有一个GUID。打印机具有诸如打印机名称、驱动程序信息、端口号等属性。
计算机对象是指加入活动目录网络的任何计算机,可能是工作站,也可能是服务器。计算机是叶子对象,因为它们不包含其他对象。然而,它们被视为安全主体,并拥有SID和GUID。像用户一样,它们是攻击者的主要目标,因为对计算机的完全管理访问权限(作为全能的 NT AUTHORITY\SYSTEM
账户)授予了类似于标准域用户的权利,并且可以用来执行用户账户可以执行的大部分枚举任务,跨域信任的几个例外情况除外。
共享文件夹对象指向特定计算机上的共享文件夹。共享文件夹可以应用严格的访问控制,并且可以对所有人开放(即使是那些没有有效活动目录账户的人)、仅对经过身份验证的用户开放(这意味着即使是权限最低的用户账户或计算机账户 NT AUTHORITY\SYSTEM
也可以访问),或者仅允许特定用户/组访问。任何未被明确允许访问的人都将被拒绝列出或读取其内容。共享文件夹不是安全主体,只有一个GUID。共享文件夹的属性可以包括名称、系统上的位置、安全访问权限等。
组被视为容器对象(container object),因为它可以包含其他对象,包括用户、计算机甚至其他组。组被视为一个安全主体,有SID和GUID。在活动目录中,组是管理用户权限和访问其他可安全对象的一种方式。例如,我们想要让10名用户访问跳转主机上的远程管理用户组。我们可以添加该组,而不是逐个添加用户,用户将通过组成员身份继承预期的权限。在活动目录中,我们通常看到所谓的“嵌套组”,即作为另一组的成员添加的组,这可能导致用户获得意外的权利。嵌套组成员身份是我们在渗透测试中常见并经常利用的。工具BloodHound有助于在网络中发现攻击路径,并以图形界面展示它们。它非常适合审核组成员身份,揭示嵌套组成员身份偶有的意外影响。活动目录中的组可以有许多属性,最常见的是名称、描述、成员身份以及组所属的其他组。还可以设置许多其他属性,我们稍后更深入地讨论。
组织单位(以下简称OU)是系统管理员用来存储相似对象以便于管理的容器。OU通常用于任务的管理委派,而不授予用户账户完全的管理权。例如,我们可能有一个名为Employees的顶级OU,然后在其下有各个部门的子OU,如Marketing、HR、Finance、Help Desk等。如果一个账户被赋予了对顶级OU重置密码的权利,这个用户将有权重置公司所有用户的密码。然而,如果OU结构是特定部门作为HR OU的子OU,则任何放置在HR OU中的用户将在授予该权利时被委派这个权利。可能在OU级别委派的其他任务包括创建/删除用户、修改组成员身份、管理组策略链接和执行密码重置等。OU对于在域内的用户和组子集中,管理组策略设置非常有用。例如,我们可能想要为特权服务账户设置特定的密码策略,这些账户可以放在一个特定的OU中,然后有一个组策略对象分配给它,这将对放置在其中的所有账户强制执行此密码策略。一些OU属性包括其名称、成员、安全设置等。
域是活动目录网络的结构。域包含诸如用户和计算机等对象,这些对象被组织到容器对象中:组和OU。每个域都有自己的独立数据库和可以应用于域内对象的一套策略。一些策略是默认设置的(并且可以调整),例如域密码策略。与此相反,其他策略是根据组织的需要创建和应用的,例如阻止所有非管理用户访问cmd.exe或登录时映射共享驱动器。
域控制器本质上是活动目录网络的大脑。它们处理身份验证请求,验证网络上的用户,并控制谁可以访问域中的各种资源。所有访问请求都通过域控制器验证,特权访问请求基于分配给用户的预定角色。它还执行安全策略,并存储有关域中每个其他对象的信息。
活动目录中的站点是一组跨一个或多个子网的计算机,使用高速链接连接。它们用于使域控制器间的复制高效运行。
在活动目录中,内置是一个容器,包含活动目录域中的默认组。它们在创建活动目录域时预定义。
外部安全主体(FSP)是在活动目录中创建的对象,用于表示属于受信任外部林的安全主体。
当将一个来自外部(当前林之外)林的对象(如用户、组或计算机)添加到当前域中的组时,就会创建FSP。在将安全主体添加到组后,FSP会自动创建。每个外部安全主体都是一个占位符对象,保存外部对象(属于另一个林的对象)的SID。Windows使用这个SID通过信任关系解析对象的名称。FSP在名为 ForeignSecurityPrincipals
的特定容器中创建,其专有名称类似于 cn=ForeignSecurityPrincipals,dc=RedteamNotes,dc=local