为什么会有这篇文章?
本指南的目的是从攻击者的角度来看待活动目录。我将尝试回顾活动目录的不同方面以及每个渗透测试人员应该掌握的术语,以理解可以在域中进行的攻击。
为了理解如何攻击活动目录(以及任何其他技术),我认为重要的是不仅要知道工具怎么用,还要知道工具是如何工作的,它们使用什么协议 / 机制,以及为什么存在这些协议 / 机制。
出现在本文的信息来源于公开的知识以及我在 AD 方面的一些经验。然而,我无法确定这里写的都是对的,所以希望你能自己做一些测试。如果发现有错误,请联系我 zer1t0ps@protonmail.com。
此外,我知道这里并没有涵盖关于活动目录的所有内容,但我的本意是至少涵盖理解活动目录及其攻击所需的基本知识,并在将来扩大这一来源。所以,如果你觉得这里漏掉了一些 AD 相关的基础知识,请联系我 zer1t0ps@protonmail.com。
免责声明:本文仅用于教育目的,请不要做未授权的攻击。
我尽可能尝试将这些内容介绍清楚,但有一些内容是很复杂的,所以我也引用了很多外部的链接。
我的主要目的是将所有的活动目录主题收集在一个地方,可以用来咨询攻击 / 协议 / 技术,而不是解释一个具体技术的每一个细节(即使我试图这样做)。因此,我们完全鼓励你跟随超链接去发现更多关于特定主题的信息,那里有很多很棒的资源。
顺便说一下,我想感谢所有的内容创作者,他们多年来通过工具、博客、会议讲座等与社区分享知识。我查阅了很多资料,不可能逐一感谢所有的内容创造者,但是如果你发现了你的资源链接,或者你直接合作的资源(通过给工具添加功能,或者帮助你的朋友写文章),又或者间接合作的资源(例如创建一个库/代码片段/语言/操作系统/IDE/编辑器,被一个工具使用,或者一个博客被用作这里链接的文章的基础),谢谢你~
在整个文章中,我将使用 Powershell 来展示如何获取活动目录的信息。
为此,我将使用 ActiveDirectory Powershell模块,但也可以使用其他工具,如 Powerview 或 ldapsearch 来代替。
好了,让我们开始吧~
什么是活动目录(Active Directory)?
在我看来,活动目录是一个系统,它允许从一个中央服务器上管理连接在同一网络中的一系列的计算机和用户。
当然,这个定义并非完全准确,但我希望它足够简单,能让你了解什么是活动目录。
Active Directory 网络:
____ __
o | | |==|
/|\ |____| <--------. .-----> | |
/ \ /::::/ | | |__|
v v
.---.
/ /|
.---. |
| | '
| |/
'---'
____ ^ ^ ____
o | | | | | | \o/
/|\ |____| <-------' '-----> |____| |
/ \ /::::/ /::::/ / \
想象一下,一个有数百名员工的公司,每个人都在自己的(可能是 Windows)电脑中工作。这个公司有几个不同的部门,如销售、人力资源、IT 等。
销售部门要求在他们的工作站上安装一个新的程序。或者,每天都有不同办公室的用户忘记了密码,需要恢复。或者,新的实习生小组只需要处理文件服务器上的一些文件。
IT 团队应该在所有销售的工作站中逐一安装该程序吗?他们应该到不同的办公室去恢复用户密码吗?他们是否应该为每个实习生创建一个新的用户,从而只允许查看文件服务器的一个目录中的文件?
好吧,他们可以这样做,虽然这将是一个很大的工作(对公司来说是一种浪费)。但是,由于他们是聪明人,他们把所有的计算机都连接在一个活动目录网络中,所以他们可以从自己的工作站上执行所有这些操作。
活动目录通过维护一个集中的数据库来实现这一点,所有关于用户、计算机、策略、权限等信息都存储在这里。所以,例如 IT 团队可以连接到这个数据库,为实习生创建新的用户,并给他们分配权限,只允许他们读取其部门的特定服务器的指定目录中的文件。
然后,当这些实习生试图登录到活动目录网络内的计算机时,计算机会查询中央数据库,以检查该实习生用户是否存在(以及密码是否正确)。这样,用户可以登录到公司的任何一台电脑上(如果他们有权限的话),通过允许员工只使用一个用户在公司所有的电脑上(可以是工作站、数据库服务器、文件服务器等)做所有的工作。
同样,如果一个用户忘记了密码,她可以提醒 IT 团队,他们可以在这个中央数据库中更改用户密码(并要求用户将这个密码改为只有她知道的新密码)。
就销售部门而言,IT 部门可以在数据库中创建一个新的策略,指出该部门的计算机必须安装指定的程序,以及他们必须如何做。然后,当销售的工作站读取数据库时,它们就会知道它们必须执行这个策略,新的程序就会被安装。
我希望这个例子能让你理解为什么活动目录如此有用,为什么世界上几乎所有的(中大型)组织都使用它。也许你已经使用过它,通常是一台需要在提示你的用户名和密码之前按 Ctrl+Alt+Del 的电脑。
那么……如果有人能窃取一个 IT 用户的密码会怎样?她能更改其他用户的密码吗?以及对数据库的访问?
现在清楚了为什么 活动目录是如此的重要,接下来再看一些它们的术语。
域(Domain)
首先,我们一直所说的活动目录网络就是通常所说的域(Domain)。一个域是一组连接的计算机,它们共享一个活动目录数据库,该数据库由一个域的中央服务器管理,这些服务器被称为域控制器(Domain Controllers)。
域名(Domain name)
每个域都有一个 DNS 名称。在许多公司里,域名就是他们的网站名,例如 contoso.com
,也有一些有不同的内网域名,如 contoso.local
。
获取当前用户域:
PS C:\Users\Anakin> $env:USERDNSDOMAIN
CONTOSO.LOCAL
PS C:\Users\Anakin> (Get-ADDomain).DNSRoot
contoso.local
获取当前计算机域:
PS C:\Users\Anakin> (Get-WmiObject Win32_ComputerSystem).Domain
contoso.local
除了 DNS 名,每个域也可以用 NetBIOS 名标识。例如,域 contoso.local
的 NetBIOS 名 CONTOSO
。你可以看到 NetBIOS 名被用于登录操作,在这里使用类似 CONTOSO\Administrator
来区分用户,这里的第一部分是 NetBIOS 名,第二部分是用户名。
最后,一个域可以通过其 SID(安全标识符,Security Identifier)来识别。SID 更多的是被程序使用(使用 Windows API),而不是被用户使用,但你应该知道如何获得它,以防你需要它。
获取域的 DNS 名、NetBIOS 名、SID:
PS C:\Users\Anakin> Get-ADDomain | select DNSRoot,NetBIOSName,DomainSID
DNSRoot NetBIOSName DomainSID
------- ----------- ---------
contoso.local CONTOSO S-1-5-21-1372086773-2238746523-2939299801
林(Forests)
使用 DNS 名称是非常有用的,因为它允许为管理目的创建子域。
例如,一个公司有一个根域叫做 contoso.local
,然后为不同的(通常是大的)部门创建子域名,像 it.contoso.local
或者 sales.contoso.local
。
正如你将看到的,活动目录提供了许多方法来组织你的基础设施,所以一个组织可以在不同的地方使用子域,有些为部门创建子域,而有些则为不同的办公室使用子域。
contoso.local 林:
contoso.local
|
.-------'--------.
| |
| |
it.contoso.local hr.contoso.local
|
|
|
webs.it.contoso.local
这种树状的域被称为林 Forest。林的名称与域树的根域的名称相同。
获取林信息:
PS C:\Users\Anakin> Get-ADForest
ApplicationPartitions : {DC=DomainDnsZones,DC=contoso,DC=local, DC=ForestDnsZones,DC=contoso,DC=local}
CrossForestReferences : {}
DomainNamingMaster : dc01.contoso.local
Domains : {contoso.local}
ForestMode : Windows2016Forest
GlobalCatalogs : {dc01.contoso.local, dc02.contoso.local}
Name : contoso.local
PartitionsContainer : CN=Partitions,CN=Configuration,DC=contoso,DC=local
RootDomain : contoso.local
SchemaMaster : dc01.contoso.local
Sites : {Default-First-Site-Name}
SPNSuffixes : {}
UPNSuffixes : {}
在一个林中,每个域都有自己的数据库以及域控。不过,域用户也可以访问林中的其他域。
这意味着,即使一个域可以是自治的,不需要与其他域进行交互。但从安全角度来看,它并不是孤立的。因为,正如我们将看到的,一个域的用户可以访问同一林中其他域的资源(默认情况下)。然而,一个林的用户默认不能访问其他林的资源,所以能够提供安全隔离的逻辑结构是林。
正如我之前所说,每个域都有自己的域控制器,所以如果一个部门发展得令人难以置信,你可能需要专门的域控制器来处理该部门所有计算机的请求。你可以通过创建一个新的子域来实现这一点,而用户仍然能够访问同一林中其他子域的计算机。
功能级别(Functional Levels)
除了 Windows 电脑之外,域 / 林也可以有自己的“版本”,叫做功能级别。基于域 / 林的功能级别,可以使用新的特性。
这些模式是根据使用它们所需的最低 Windows Server 操作系统版本来命名的。例如 下面的林功能级别:
- Windows2000
- Windows2000MixedDomains
- Windows2003
- Windows2008
- Windows2008R2
- Windows2012
- Windows2012R2
- Windows2016
获取域 / 林的功能级别:
PS C:\Users\Administrator\Downloads> (Get-ADForest).ForestMode
Windows2016Forest
PS C:\Users\Administrator\Downloads> (Get-ADDomain).DomainMode
Windows2016Domain
如果你发现一个具有 Windows2012 级别的域/林,你可以知道所有的域控制器至少是 Windows Server 2012。
你必须了解域的级别,以便使用域的一些特性,例如,“受保护用户”组需要 Windows2012R2 级别。
信任(Trusts)
如果域之间建立了信任关系,可以访问对方域内的资源,这种联系就叫信任(Trusts)。A trust is a connection from a domain to another). 信任不是物理网络连接,而是一种认证 / 授权连接。
你可能能够接触到网络上属于其他域的计算机,但你不能用这个域的用户登录到这些计算机上。这就是信任允许你做的事情。
信任方向(Trust direction)
信任是一种定向关系,其中一方是信任方(trusting),另一方是被信任方trusted)。当这种联系建立后,受信域的(trusted)用户可以访问信任域的(trusting)资源。
信任方向)与访问方向相反。你可以认为,如果你信任你的朋友,你就允许她进入你的房子,在她需要时吃你的食物。
A 域信任 B 域:
(trusting) trusts (trusted)
Domain A --------------------> Domain B
outgoing incoming
outbound inbound
access
<--------------------
当一个信任指向你的域时,称为入站(Inbound)或传入(Incoming)信任。传入信任允许你的域用户访问对方的域。
信任方向反过来,则反之,其他域的用户可以访问你的域。
当两个域同时被传入和传出的信任所连接时,可以说它们被双向信任所连接(即使真的有两个信任)。
列出域信任关系:
PS C:\Users\Administrator> nltest /domain_trusts
List of domain trusts:
0: CONTOSO contoso.local (NT 5) (Direct Outbound) ( Attr: foresttrans )
1: ITPOKEMON it.poke.mon (NT 5) (Forest: 2) (Direct Outbound) (Direct Inbound) ( Attr: withinforest )
2: POKEMON poke.mon (NT 5) (Forest Tree Root) (Primary Domain) (Native)
The command completed successfully
这里我们可以看到,我们当前的域是 poke.mon
(因为有 Primary Domain
属性),并且有几个信任。
对 contoso.local
的出站(Outbound)信任表明它的用户可以访问我们的域 poke.mon
。
此外,还有一个与 it.poke.mon
的双向信任,它是 poke.mon
的一个子域,而且是在同一个林中。
contoso.local
的信任关系:
PS C:\Users\Anakin> nltest /domain_trusts
List of domain trusts:
0: POKEMON poke.mon (NT 5) (Direct Inbound) ( Attr: foresttrans )
1: CONTOSO contoso.local (NT 5) (Forest Tree Root) (Primary Domain) (Native)
The command completed successfully
因此,如果我们检查 contoso.local
的信任,我们可以看到一个来自 poke.mon
的入站(Inbound)信任,这与之前的信息一致。所以 contoso.local
的用户可以访问 poke.mon
。
信任传递性(Trust transitivity)
此外,一个信任可以是传递的,也可以是非传递的。trust can be transitive or nontransitive)
一个非传递的(nontransitive)信任只能由信任的双方,即信任方和被信任方使用。而传递性信任可以充当桥梁,用于与被传递性信任连接的域相连的第三域。
(trusting) trusts (trusted) (trusting) trusts (trusted)
Domain A -------------------> Domain B --------------------> Domain C
access access
<------------------- <--------------------
例如,如果域 A 与域 B 之间的信任是可传递的,那么域 C 的用户就可以访问域 A。如果域 A 与域 B 的信任 Domain A --> Domain B
是不可传递的,那么域 C 的用户无法访问域 A,但是域 B 的用户仍然可以访问域 A。
因此,在同一林中的域关系中,所有的域用户都可以访问其他的域,因为所有的父域和子域都是通过双向的、可传递的信任连接的。这样一来,林中的任何域都可以穿越所需的信任来访问同一林中的其他域。
在一个林中,所有的根域、林根域之间都建立了双向的、可传递的信任关系,因此每一个域树的每一个域内的用户,只要有权限,就可以访问任意的其他域。
contoso.local
林信任关系:
contoso.local
^ v v ^
.----' | | '----.
| .----' '----. |
^ v v ^
it.contoso.local hr.contoso.local
^ v
| |
^ v
webs.it.contoso.local
所以,webs.it.contoso.local
的用户要访问 hr.contoso.local
的计算机的话,必须穿过三个信任关系。
信任类型(Trust types)
在活动目录中,有几个用于不同目的的信任类型:
- Parent-Child:父域和其子域之间创建的默认信任。
- Forest:一个在林之间共享资源的信任。这样,林的任何域都可以访问另一个林的任何域(如果信任的方向和传递性允许的话)。如果一个林的信任被错误地配置了,那么它就可以允许控制另一个林。
- External:一个信任连接到一个非信任林中的特定域。
- Realm:一个特殊的信任来连接活动目录和一个非 Windows 域。
- Shortcut:当林中的两个域经常通信但不直接连接时,你可以通过创建一个直接捷径信任来避免穿过许多信任。
信任密钥(Trust key)
从技术上讲,当你使用信任时,在你的域的域控制器和目标域(或中介域)的域控制器之间存在着一种通信。
如何进行通信取决于正在使用的协议(可能是 NTLM、Kerberos 等),但在任何情况下,域控需要共享一个密钥以保证通信安全。这个密钥被称为信任密钥(Trust key),它是在建立信任的时候创建的。
当一个信任被创建时,一个信任账户被创建在域数据库中,就像它是一个用户一样(名字以 $
结束)。然后,信任密钥被存储,就像它是信任用户的密码一样(NT 哈希和 Kerberos 密钥)。
更多的信任相关知识
要想知道信任如何在渗透中被利用,你可以查看下面的帖子(建议有一点 Kerberos 的知识再来阅读这些帖子)。
- It’s All About Trust – Forging Kerberos Trust Tickets to Spoof Access across Active Directory Trusts
- A Guide to Attacking Domain Trusts
- Active Directory forest trusts part 1 – How does SID filtering work?
- Inter-Realm Key Roasting (well… within the first 30 days)
- Not A Security Boundary: Breaking Forest Trusts
用户(Users)
使用活动目录的关键点之一是用户管理。每个组织都以不同的方式管理其用户,为他们设置名称格式,分配不同的权限等等。
在活动目录中,为了轻松地管理用户,它们以对象的形式存在中央数据库中,可以在域中的任意一个地方对其进行查询和操作(如果你有足够的权限)。
用户属性
用户对象存储了许多不同的数据,但首先要考虑的属性是那些允许我们识别一个用户的属性。
对于识别用户,通常使用用户名,它被存储在 SamAccountName 属性中。此外,SID(安全标识符,Security Identifier)也可用于识别用户。
用户 SID 与域 SID 相似,事实上,是域 SID 加上用户 RID(相对标识符,Relative Identifier)的组合,RID 是出现在用户 SID 中的最后一个数字。
获取用户信息:
PS C:\Users\Anakin> Get-ADUser Anakin
DistinguishedName : CN=Anakin,CN=Users,DC=contoso,DC=local
Enabled : True
GivenName : Anakin
Name : Anakin
ObjectClass : user
ObjectGUID : 58ab0512-9c96-4e97-bf53-019e86fd3ed7
SamAccountName : anakin
SID : S-1-5-21-1372086773-2238746523-2939299801-1103
Surname :
UserPrincipalName : anakin@contoso.local
在这个例子中,域 SID 是 S-1-5-21-1372086773-2238746523-2939299801
,用户的相对标识符 RID 是 1103
。
一些工具在其输出中显示 SID,而不是用户名(因为它在一些结构中使用,如安全描述符),所以你应该了解它的格式,以便识别它。
另外,DistinguishedName
被 LDAP API 用于识别对象,所以如果你使用 LDAP 查询数据库(这是最常见的方式之一),你可能会看到通过其DistinguishedName
对对象的引用。
此外,数据库还需要存储用户的秘密,以便让域控制器对用户进行认证。用户密码不是以明文形式存储的,但从它衍生出来的以下秘密被保存。
- NT 哈希(LM 哈希用于老账户)
- Kerberos 密钥
不用多说,非管理员用户不能获取到用户的秘密。甚至域内的计算机也不能访问它们,而是将认证工作留给域控制器。
为了获得用户秘密,你需要管理员权限(或同等权限),用 dcsync 攻击或从域控制器上抓取 C:\Windows\NTDS\ntds.dit
文件来转储域数据库。
LM 和 NT 哈希值同时存储在 Windows 本地 SAM 和活动目录 NTDS 数据库中,以分别验证本地和域的用户。这些哈希值,无论是 LM 还是 NT 都是16字节长。
一个密码的 LM 和 NT 哈希:
Password: 123456
LM hash: 44EFCE164AB921CAAAD3B435B51404EE
NT hash: 32ED87BDB5FDC5E9CBA88547376818D4
然而,LM 哈希值相当弱,所以从 Windows Vista/Server 2008 开始就不使用它们了。创建 LM 哈希值的步骤如下:
- 将用户密码转换成大写字母。(这就减少了暴力破解的搜索空间)
- 如果用户密码少于 14 个字符,则用 NULL 字符填充,直到长度为 14。如果密码超过 14 个字符,就会被截断。(超过 14 个字符的密码是没有用的)
- 然后,密码被分割成两个字符串,每个字符串为 7 字节。
- 每个 7 字节的字符串被用作密钥,使用 DES 加密算法对
KGS!+#$%
字符串进行加密。这就产生了两个哈希值。 - 由此产生的两个值被连接起来,以形成 LM 哈希值。(你可以分别破解每个部分)
LM 哈希计算伪代码:
upper_password = to_uppercase(password)
14_password = truncate_to_14_bytes(upper_password)
7_part1, 7_part2 = split_7(14_password)
hash1 = des(7_part1, "KGS!+#$%")
hash2 = des(7_part2, "KGS!+#$%")
lm_hash = hash1 + hash2
另一方面,NT 哈希值更强一些,但没有使用盐)来计算它,所以它可以通过使用预先计算的值(如彩虹表)进行破解。
如果你感到好奇,NT 哈希值是通过将MD4算法(该算法已过时)直接应用于用户密码的 Unicode 版本(特别是 UTF-16LE 编码)来计算的。
NT 哈希计算伪代码:
nt_hash = md4(encode_in_utf_16le(password))
很多时候,NT 哈希值被称为 NTLM 哈希值,然而这可能会引起混淆,因为 NTLM 协议也使用哈希值,称为 NTLM 哈希值。在本文中,NTLM 哈希将是 NTLM 协议的哈希。
许多工具允许你提取 LM 和 NT 哈希值,它们通常会返回几行输出,每个用户一行,格式为 <username>:<rid>:<LM>:<NT>:::
。
如果 LM 没有被使用,它的值将是aad3b435b51404eeaad3b435b51404ee
(空字符串的 LM 散列)。
Dump 哈希的格式:
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:6535b87abdb112a8fc3bf92528ac01f6:::
user:1001:aad3b435b51404eeaad3b435b51404ee:57d583aa46d571502aad4bb7aea09c70:::
识别 NT 哈希对渗透人员来说非常重要,因为即使它们不是用户的密码,也能用于 Windows 机器的认证,所以它们非常有用。它们可以用来进行 Pass-The-Hash 或 Overpass-the-Hash 攻击,以冒充远程机器上的用户。
此外,你可以尝试用 hashcat 破解 LM 和 NT 哈希值来恢复原始密码。如果你运气好,存在 LM 的哈希值,这应该是很快的。
除了 LM / NT 哈希值之外,还存储了 Kerberos 密钥,它来自用户密码,用于 Kerberos 认证协议。
Kerberos 密钥可以用来要求在 Kerberos 认证中代表用户的 Kerberos 票据。有几种不同的密钥,不同的密钥用于不同的 Kerberos 加密支持:
- AES 256 密钥:使用 AES256-CTS-HMAC-SHA1-96 算法。这是 Kerberos 常用的一种,也是渗透人员应该使用的一种,以避免触发警报。
- AES 128 密钥:使用 AES128-CTS-HMAC-SHA1-96 算法。
- DES 密钥:使用 废弃的 DES-CBC-MD5 算法。
- RC4 密钥:这是 RC4-HMAC 算法所使用的用户的 NT 哈希值。
从域数据库中提取 Kerberos 密钥:
$ secretsdump.py 'contoso.local/Administrator@192.168.100.2' -just-dc-user anakin
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation
Password:
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
contoso.local\anakin:1103:aad3b435b51404eeaad3b435b51404ee:cdeae556dc28c24b5b7b14e9df5b6e21:::
[*] Kerberos keys grabbed
contoso.local\anakin:aes256-cts-hmac-sha1-96:ecce3d24b29c7f044163ab4d9411c25b5698337318e98bf2903bbb7f6d76197e
contoso.local\anakin:aes128-cts-hmac-sha1-96:18fe293e673950214c67e9f9fe753198
contoso.local\anakin:des-cbc-md5:fbba85fbb63d04cb
[*] Cleaning up...
这些 key 可以用于 Pass-The-Key 攻击,获取一个仿冒用户的票据,然后你可以使用这个 Kerberos 票据代表此用户去认证不同的域内服务。
用户类的一个有趣的属性是 UserAccountControl(不要把它与用户账户控制机制 UAC 混淆,以避免在 Windows 机器中执行高权限程序)。
UserAccountControl 属性包含了一系列与安全和域非常相关的标志,并在本文章提到的许多攻击中使用。下面是最相关的:
- ACCOUNTDISABLE:帐户被禁用,无法使用。
- DONT_REQUIRE_PREAUTH:该账户不需要 Kerberos 预认证。
- NOT_DELEGATED:这个账户不能通过 Kerberos 委派来进行委派。
- TRUSTED_FOR_DELEGATION:该账户及其服务启用了 Kerberos 非约束委派。SeEnableDelegationPrivilege 需要修改。
- TRUSTED_TO_AUTH_FOR_DELEGATION:该账户及其服务启用了 S4U2Self 扩展。SeEnableDelegationPrivilege 需要修改。
一些渗透中非常有用的用户属性:
- Description:用户的描述。它可以提供一个关于用户权限的 idea,有时甚至包括密码。
- AdminCount:表示用户(或组)是否受到 AdminSDHolder 对象的保护,或已经被保护。因为有时不更新,所以只作为参考使用。
- MemberOf:用户是其成员的组。这个属性是逻辑性的,是由组的成员属性生成的。
- PrimaryGroupID:用户的主要组别。这个组不会出现在 MemberOf 属性中。
- ServicePrincipalName:用户的服务。对 Kerberoast 攻击有用。
- msDS-AllowedToDelegateTo:用户(和它自己的服务)可以使用 Kerberos 约束委派冒充 client 的服务列表。SeEnableDelegationPrivilege 需要修改。
重要的用户
要查询用户,有几个选项,如 net user /domain
命令,或 Powershell。不需要有特殊的权限来列出用户,任何用户都可以这样做。
列用户:
PS C:\Users\Anakin> Get-ADUser -Filter * | select SamAccountName
SamAccountName
--------------
Administrator
Guest
krbtgt
anakin
han
POKEMON$
正如你可能注意到的,我的测试域只有很少的用户,但在真正的环境中,会有成百上千的用户。因此,区分哪些是真正重要的用户应该是很重要的。这可能有点棘手,因为这取决于组织,但通常 IT 团队的成员都有特权用户,他们需要特权用户来做他们的工作。
默认情况下,内置的 Administrator 用户是域中最有特权的账户。它可以在任何计算机中执行任何操作。因此,如果你能够拿下这个账户,你就可以完全控制该域(甚至通过使用 SID History 攻击来控制林)。
此外, krbtgt 帐户也非常重要,它的秘密(NT 哈希值和 Kerberos 密钥)用于加密 Kerberos 所使用的票据(特别是 TGT),以便对用户进行认证。如果你能够攻破 krbtgt 账户,你将能够创建黄金票据。通常,这个账户只能通过转储域数据库来入侵,因为它只在域控制器中使用,这需要你在域中有管理员权限。
计算机账户
另一件需要考虑的事情是,在一个组织中,每个人都有自己的用户,甚至某些人,如 IT 部门,可以有多个用户来执行不同的任务。此外,域中的每台计算机也有自己的用户,因为它们也需要在域中执行自己的操作。
用户账户和计算机账户的区别在于,前者在数据库中被存储为用户类的实例,而后者则被存储为计算机类的实例(它是用户类的一个子类)。
此外,计算机账户名称是以美元符号$
结尾的计算机主机名。
获取域内的所有用户:
PS C:\> Get-ADObject -LDAPFilter "objectClass=User" -Properties SamAccountName | select SamAccountName
SamAccountName
--------------
Administrator
Guest
DC01$
krbtgt
anakin
WS01-10$
WS02-7$
DC02$
han
POKEMON$
正如你所看到的,比使用 Get-ADUser
命令的用户要多得多,因为现在包含了 User 类的子类。你可以体会到,新账户以美元符号结尾,似乎有一个计算机名称。例如,DC01$
和 DC02$
代表域控制器,WS01-10$
和WS02-7$
代表工作站。
此外,计算机对象还保存了关于其操作系统的信息,这些信息可以从属性 OperatingSystem
或 OperatingSystemVersion
中获取到。
此外,许多组织都有选择计算机和用户名称的规则,所以如果你能够理解这些名称,你就可以知道计算机和用户账户的使用情况,以及哪些账户可以有特权或对敏感信息的访问权限。此外,你还可以检查对象的其他属性,如 Description
,以便在那里找到更多的信息(甚至是明文密码)。对于这个目的,Powerview 的 Find-DomainObjectPropertyOutlier Cmdlet 很有用。
信任账户(Trust accounts)
然而,还有一个 POKEMON$
账户出现在 Get-ADUser 和 Get-ADObject 中,但其名称以美元符号结尾。
这可能是正常的用户(创建以 $ 结尾的用户名没有问题),正如我们之前看到的,poke.mon 域名存在信任关系。
当建立信任时,在每个域中都会创建一个相关的用户对象来存储信任密钥(trust key)。用户的名称是另一个域的 NetBIOS 名称,以 $ 结束(类似于计算机账户名)。例如,在 FOO 域和 BAR 域之间建立信任的情况下,FOO 域将在 BAR$
用户中存储信任密钥,而 BAR 域将在 FOO$
用户中存储它。
列出域内的信任用户:
PS C:\> Get-ADUser -LDAPFilter "(SamAccountName=*$)" | select SamAccountName
SamAccountName
--------------
POKEMON$
这个 POKEMON$
用户对象被用来存储信任密钥,它是 NT 哈希或 Kerberos 密钥(根据上下文使用其中之一)。如果你能得到这个账户的秘密,你就可以创建跨域 Kerberos 票据。
组(Groups)
但是,如果没有分组,用户的管理就会很麻烦。想象一下,你有一个需要访问高度敏感文件的经理部门。你应该给每个经理逐一授予权限吗?很多工作你可以处理,因为每年只增加一个新经理。但现在政策改变了,经理们也应该能够访问人力资源部门的文件。你应该一个一个地改变所有经理的权限吗?不,那是太多的工作,而且是相当无聊的。
解决办法是使用组。在这种情况下,你可以有一个“经理”组,将经理用户加入其中,当政策发生变化时,你必须为该组增加或删除权限。
和用户一样,组也被存储在域数据库中。而且以同样的方式,它们可以通过 SamAccountName
属性或 SID 来识别。
列出域内的组:
PS C:\Users\Anakin> Get-ADGroup -Filter * | select SamAccountName
SamAccountName
--------------
Administrators
Users
Guests
<-- stripped output -->
Domain Computers
Domain Controllers
Schema Admins
Enterprise Admins
Cert Publishers
Domain Admins
Domain Users
<-- stripped output -->
Protected Users
Key Admins
Enterprise Key Admins
DnsAdmins
DnsUpdateProxy
DHCP Users
DHCP Administrators
重要的组
在活动目录中,有许多默认组定义为域 / 林中的不同角色。作为攻击者,最重要的组之一是域管理员组,该组为其成员在域中提供管理员权限,因此了解谁是这个组的很重要。
获取域管理员组信息:
PS C:\Users\Anakin> Get-ADGroup "Domain Admins" -Properties members,memberof
DistinguishedName : CN=Domain Admins,CN=Users,DC=contoso,DC=local
GroupCategory : Security
GroupScope : Global
MemberOf : {CN=Denied RODC Password Replication Group,CN=Users,DC=contoso,DC=local,
CN=Administrators,CN=Builtin,DC=contoso,DC=local}
Members : {CN=Administrator,CN=Users,DC=contoso,DC=local}
Name : Domain Admins
ObjectClass : group
ObjectGUID : ac3ac095-3ea0-4922-8130-efa99ba99afa
SamAccountName : Domain Admins
SID : S-1-5-21-1372086773-2238746523-2939299801-512
但也有其他重要的组,可以给你很多特权,还有的甚至更多。这就是企业管理员组 Enterprise Admins
的情况,它在所有林中提供管理员权限。
企业管理员 Enterprise Admins
是一个只存在于林根域中的组,但默认情况下被添加到林中所有域的管理员组中。
另一方面,域管理员组 Domain Admins
被添加到域的管理员组 Administrators
,以及域计算机的管理员组 Administrators
中。
林中的管理员组成员资格:
.------------------------.
| contoso.local |
.-------------------------------------------------------------.
| |
| .----------------. |
| .-->| Administrators |<-. .->Administrators |
| | '----------------' | | ____ |
| | .---------------. | | | | |
| | | Domain Admins |>-'---' |____| |
| | '---------------' /::::/ |
| | .-------------------. |
| '--<| Enterprise Admins | |
| '-------------------' |
| v v |
'-----------------------------|-|-----------------------------'
| | | |
| | | |
.---------' | | '-----------.
| v v |
.----------------------------------. | | .----------------------------------.
| it.contoso.local | | | | hr.contoso.local |
|----------------------------------| | | |----------------------------------|
| | v v | |
| .----------------. | | | | .----------------. |
| .->| Administrators |<---------' '--------->| Administrators |<-. |
| | '----------------' | | '----------------' | |
| | .---------------. | | .---------------. | |
| '-<| Domain Admins | | | | Domain Admins |>--' |
| '---------------' | | '---------------' |
| | | | | |
| .-------'---------. | | .-------'---------. |
| | | | | | | |
| v v | | v v |
| Administrators Administrators | | Administrators Administrators |
| ____ ____ | | ____ ____ |
| | | | | | | | | | | |
| |____| |____| | | |____| |____| |
| /::::/ /::::/ | | /::::/ /::::/ |
'----------------------------------' '----------------------------------'
还有其他的重要组需要考虑:
- DNSAdminsDNSAdmins 组可以允许其成员通过使用任意的 DLL 在域控制器中以 SYSTEM 身份执行代码。
- Protected UsersProtected Users 组强制执行账户的安全性措施。他们的成员不允许:
- 用 NTLM 认证(只有Kerberos);
- 在 Kerberos 预认证中使用 DES 或 RC4 加密类型;
- 用非约束委派或约束委派;
- 超过最初的四小时寿命后更新 Kerberos TGT;
这可以阻止通过 NTLM relay 或 Kerberos 委派攻击滥用这些账户的企图。
- Schema AdminsSchema Admins 可以修改 Active Directory 数据库的架构。
- Account OperatorsAccount Operators 组可以修改域的许多组的成员,不包括许多管理员组,但是可以修改 Server Operators group。
- Backup OperatorsBackup Operators 的成员可以备份和恢复域控制器中的文件(他们也可以登录到域控制器)。这可以允许修改域控制器中的文件。
- Print OperatorsPrint Operators 可以登录到域控制器。
- Server OperatorsServer Operators 可以登录到域控制器并且管理它的配置。
- Remote Desktop UsersRemote Desktop Users 的成员可以通过 RDP 登录到域控制器。
- Group Policy Creator OwnersGroup Policy Creator Owners 的成员可以编辑域中的 GPOs。
在微软的文档中还描述了许多其他组。许多组织添加了自定义组,这些组也可能是非常有特权的,比如 IT 成员使用的组。
此外,许多软件(尤其是微软的软件)都会添加自己的管理组。例如 Exchange 可以添加特权组,如Exchange Windows Permissions
,可以让用户进行 DCSync 攻击(如果没有正确更新)。
组范围
在活动目录中,根据其范围有三种不同类型的组。了解它们就能理解如何管理域和林:
-
通用组,Universal groups,可以有来自同一林的成员,并在同一林或受信任林中授予权限。企业管理员组
Enterprise Admins
是通用组的一个例子。 -
全局组,Global groups,只能有同一域的成员,并在同一林的域或信任域或林中授予权限。域管理员组
Domain Admins
是全局组的一个例子。 -
DomainLocal groups 可以有来自本域或任何受信任域的成员,并且只在其域内授予权限。
Administrators
组是DomainLocal
组的一个例子。
除此之外,你还应该知道,域组(和域用户)可以是计算机本地组的成员。例如,默认情况下,域管理员组 Domain Admins
被添加到机器的 Administrators 本地组中。
发表评论
您还未登录,请先登录。
登录