NTLM Relay
参考:
08-Ntlm-Relay-Reloaded-Attack-methods-you-do-not-know.pdf
Exploiting Windows Network with Responder and SmbRelayX
D2T2 - NTLM Relay Is Dead Long Live NTLM Relay - Jianing Wang and Junyu Zhou.pdf
NTLM Pass-Through Authentication
对于前面的实验虽然成功了,但是你可能很懵,前面实验中我并未详细介绍 NTLM Relay的技术细节,本小节就是为了介绍一些细节。
其主要学习的资料为 @hackndo的 NTLM Relay ,建议阅读原文,因为本文大部分内容都是原文中提到过的,笔者也只是阅读加以理解记录。
实际上以前笔者也介绍过NTLM ,这里为了连贯,简要的描述NTLM 协议。
NTLM Protocol
NTLM 全称 NT LAN Manager,在Windows 中用于 客户端和 服务器之间的身份验证。
注意,客户端和服务器是相对而言,并不是说Windows Server 才是 服务器。
NTLM 具体来说有两个版本 NTLM v1 和NTLM v2 。
NTLM 的身份验证分3个阶段:
- 协商(Negotiate):协商版本、加密算法等等
- 质询(Challenge):生成Challenge (你理解为随机数就行)
- 响应(Response):发送对 Challenge 的 Response
1 | Client->>Server:客户端发起链接请求 |
注意:整个过程中用户的 NT hash 没有网络中明文传输,这里仅代表大致的传输过程,具体传输细节请参考MSDN
由于存在NTLMv1 和NTLM v2 ,细节上会有一些区别:
- Challenge 长度不同,NTLM v1 8 byte ,NTLM v2 16 byte
- Response的算法不同,NTLM v1 主要是DES ,NTLM v2 主要算法是Hmac-MD5
在Windows 中NTLM 验证有两种情况:
Workgroup
Active Directory
为什么需要介绍着两种情况,我完整的描述质询(Challenge)/响应(Response)的过程:
Server 生成 Challenge 并发送给 Client ,Client 收到Challenge 之后,使用用户名对应的 NTLM HASH 加密 Challenge ,得到Response (其实也就是我们说的 Net-NTLM),Client 发送Response 到 Server ,Server 比较自己计算的 Response ,是否相同来判断是否验证成功。
这段描述中的隐含了一些问题,这里明确下:
Server 需要用户对应的 NTLM Hash 来计算 Response(不要被我绕晕,这里有两个Response,一个是Clinent 计算的Response 和 Server 计算的 Response)
NTLM HASH 是什么?(有时候说NT HASH 也是指的同样的事物),Windows 不保存用户明文密码,保存的内容为密码的hash ,NT HASH的算法为 :
NT Hash = MD4(UTF-16-LE(password))
这里不讨论LM hash。
NTLM HASH 具体存放在哪里?非域环境在本地的 sam文件中,路径为
%windir%\System32\config\SAM
,域环境中则保存在 域控的 ntds 中,路径为%windir%\NTDS\ntds.dit
.既然明确了 NTLM hash 在哪里,那么域环境中,Server 没有存放 用户的NTLM hash ,如何验证?转发请求给域控即可,于是在域中NTLM 认证过程如下:
1
2
3
4
5Client->>Server: NTLM NEGOTIATE_MESSAGE
Server->>Client:NTLM CHALLENGE_MESSAGE
Client->>Server:NTLM AUTHENTICATE_MESSAGE
Server->>DC: NETLOGON_NETWORK_INFO
DC->>Server:NETLOGON_VALIDATION_SAM_INFO4
大致的过程没有改变,只是多了一个从Server 到DC 的交互过程。
到这里,我想你大致理解了NTLM 在工作组和域环境中大概的工作机制,这也是前面在 SMB Realy 的过程中,我提到如果使用域账号需要保证DC 能够通信的原因。
Poisoning
我想用 欺骗 、毒化等词语 ,没找到比较合适的词 ,原理上都是通过网络协议进行欺骗。限于篇幅,这里不介绍更多的协议。
在介绍 Relaying 之前,需要解决如何将认证流量导向目标。
LLMNR/NBNS
参考:
Microsoft TCP/IP Host Name Resolution Order
Chapter 7 - Host Name Resolution
Chapter 11 - NetBIOS over TCP/IP
我非常推荐 MSDN 中关于 TCP /IP 的一本手册,[TCP/IP Fundamentals for Microsoft Windows](TCP/IP Fundamentals for Microsoft Windows)
Windows 名称解析机制探究及缺陷利用——@her0in
如果想详细的研究这一部分,请阅读@her0in 相关博文
Microsoft 中有两种解析:NetBIOS 名称解析 和 主机名解析。
主机名解析顺序如下:
- 客户端检查查询的名称是否自己的名称
- 搜索本地 Hosts 文件,Hosts 文件位置:
%Systemroot%\System32\Drivers\Etc
- 通过DNS 查询
- 如果名称任然无法解析,则使用NetBIOS 名称解析顺序作为备用
NetBIOS 名称解析顺序如下:
- 查询 NetBIos 名称缓存
- 通过 NetBIOS 名称服务器(NBNS)查询,NBNS在Micrsoft 中的实现是 WINS 服务器
- 本地广播(LLMNR):在本地广播3次 寻找响应。
- 读取 lmhosts 文件, lmhosts 文件位置:
%Systemroot%\System32\Drivers\Etc
- 查询 DNS 缓存
- 通过 DNS 查询
在主机名解析顺序启用备用解析顺序之前,实际上还会检查 DNS 缓存,按照解析顺序,解析成功则停止解析过程。
备注:这部分描述可能还有问题,自认为没有写清楚,尽量以官方为准。
比如Windows 如何判断使用那种顺序等等
说了这么多,我想说的关键点在于:LLMNR 和NBNS 可影响解析结果。
这一点对我们来说如何利用?如果能够在诱导目标发起解析请求,构造响应,声明我是某某,就能够成功欺骗目标。
如果实现?各种工具都有实现,这里介绍几款常用的:
你可能会找到另一个版本lgandx/Responder, Kali linux 中使用的是后者。
在各种框架中也有相关模块:
Empire 中 module
Metasploit module
Wpad劫持
参考:
相关案例——【技术分享】Windows更新服务-WSUS中间人劫持
为了简化基于WinHTTP 应用程序的代理配置,Microsoft Windows HTTP Services(WinHTTP)实现了WPAD(Web Proxy Auto-Discovery Protocol),并且该协议目前几乎所有的 Windows 客户端都会启用(从Windows 2000 sp 3 开始)。
WPAD 的工作原理如下:
- Web浏览器向 DHCP 服务器发送DCHP INFORM查询PAC文件位置
- Web浏览器向 DNS 服务器发送WPAD +x 的查询(x 值为当前域的域名),DNS服务器返回WPAD主机的ip地址,Web浏览器通过该IP的 80 端口下载 wpad.dat
- 如果上面两种都没有响应,使用 LLMNR 广播,没有响应再使用 NetBIOS 查询(也就是 NBNS),如果有主机回应 Pac 文件位置,通过该 ip 的80端口下载 wpad.dat (仅在Windows 上 支持)
相关配置项:
组策略中配置选项为:“用户配置” — “管理模板” — “Windows 组件” — “Internet Explorer”
对应的注册表:
HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ **EnableAutoproxyResultCache
,设置为 0 或者 1,0 禁用 ,1 启用。
有什么利用点?根据上面的工作原理,可以在内网中构造恶意的答复(DHCP DNS LLMNR 都可以)将流量导向代理服务器(一般是攻击机),到这里,我想你应该明白该 Wpad 劫持的重点。
这里不在详细介绍 Responder ,这里推荐一篇文章。
Relaying
先概括的说,这就是中间人(MITM,Man In The Middle)攻击。
字面意思,我不想用一个概念解释另一个概念,这会引入新的未知。
如果有一个中间的角色,在Client 和 Server 之间不停的转换角色,对 Client 说,我是Server;然后把Client 给的数据转发给Server,对Server 说,我是 Client。于是 Client 和 Server 之间的加密都没有意义,在中间的角色看来数据都是透明的。
整个流程如下:
1 | Client->>Attacker:NTLM NEGOTIATE_MESSAGE |
整个过程中最为关键的是NTLM AUTHENTICATE_MESSAGE
, 对应 Attacker 来讲,并没有直接获取到 Client 的 NTLM HASH,而是获取了 Response 中的 Net-NTLM HASH,由于 NTLM 的两个版本,也就有着两种 Net-NTLM hash :Net-NTLM v1 hash 和 Net-NTLM v2 hash。
我会混用
NTLM AUTHENTICATE_MESSAGE
、Response、Net-NTLM 这些词语,在数据层面尽管不严谨,但是可以浅显的理解为同样的事物。
这里就不展示在域环境中 进行 Relaying 的过程,大致的逻辑已经很清晰了。
结合前面所说的 Poisoning ,造成 ”我是 Server”的效果,使得 Client 向 Attacker 发送 Net-NTLM Hash 。
Attacker 再向 Server 发送 Net-NtLM Hash ,造成我是 “Client” 的效果。
为了理解这个过程,这里抓取前面的流量具体分析为例。
Brim中顺序为从下往上。
具体到数据包中细节是这样:
顺序为从上往下。省略
NTLMSSP_NEGOTIATE
部分
192.168.3.131
得到192.168.3.71
的NTLMSSP_CHALLENGE
之后,直接将内容原封不动发送给192.168.3.62
:
192.168.3.62
发送NTLMSSP_AUTH
到192.168.3.131
:
192.168.3.131
转发同样的内容给192.168.3.71
:
注意 192.168.3.62
发送给 192.168.3.131
的Security Blob
和192.168.3.131
发送给192.168.3.71
的Security Blob
部分,完全一致。
到这里应该明白 NTLM Relaying 的过程 relaying 的并不是 NTLM ,而是 Net-NTLM 。
Authentication vs Session
参考:
The NTLM Authentication Protocol and Security Support Provider
实际上笔者一直在回避一个问题,即 NTLM Authentication 之后,如何保持 session (会话)?或者在NTLM 认证过程中如何使得 Client 和 Server 之间的彼此信任对方,注意,我是在说认证之后如何证明我(Client)经过了认证,这里的答案我觉得是 Session 机制。
这部分笔者感觉非常复杂,这里仅泛泛而谈,我能找到的大部分文档都在讲一件事,就是NTLM 如何如何验证,但是验证之后就没有下文,也算是给自己挖个坑,请教了@车大 ,暂时还未理解,这里建议阅读上面的参考连接。
总结一下,NTLM 认证过程 中重要的两个问题:
实际上不仅是ntlm 认证 ,其他认证协议也同理
- Authentication:Client 和 Server 相互认证
- Session :在此期间能够执行操作、访问资源等,无需再次验证。
NTLM 作为认证层,在数据包中的体现就是嵌套在其他协议中。NTLM 在其他协议认证完成后,基本就没他什么事了,就需要
如果你查看相关数据包,就会发现
SSPI 和 NTLMSSP
这个写的很棒
SSPI是什么?全称 Security Support Provider Interface,中文 安全支持提供者接口,SSPI 定义了由支持提供程序实现的核心安全功能集。
NTLMSSP是什么?NTLMSSP 就是SSPI 中的提供程序(Support Provider),实际上不仅有NTLM SSP ,和SSPI交互的SSP 有(默认情况下):
在笔者””凭据收集””小节中曾演示过 mimikatz 利用SSP(mimilib.dll) 记录登录过程中的密码输出到txt文件中。在系统层面,SSP 就是一个DLL。
参考:Security Support Provider Interface Architecture
- Kerberos SSP
- NTLM SSP
- Digest SSP
- Schannel SSP
- Negotiate SSP
- Cradential SSP
- Negotiate Extensions SSP
- PKU2U SSP
其实到这里已经比较明白了,用以前笔者的大白话来说,NTLM 只是协议,在Windows 中具体的实现就是 NTLM SSP ,Windows 通过调用 SSPI,从而调用 NTLM SSP 。
SSPI定义了NTLM SSP 实现以下核心操作:
- Authentication:质询响应(challenge-response)机制
- Signing:NTLM SSP 提供对消息应用数字“签名”的方法,确保消息未被修改,只能由拥有共享key的各方生成和验证
- Sealing Concepts(可以理解为加密):NTLM SSP 使用各种对称加密机制为NTLM消息提供加密,防止消息在传输过程中被第三方查看。
Session signing
大部分原理性的东西非常枯燥,耐心看完,跟着这个思路。
在前面的 SM Relaying 中,未开启 SMB signing 才能进行攻击 ,为什么 signing 能够防御此类攻击呢?
这也是这小节所要思考的问题。
Principle
签名是什么?签名是一种真实性验证的方法,确保数据在传输过程中未被篡改。
具体到NTLM 中,则是 确保 NTLM 消息在传输过程中未被修改
如何做到的?例如 ,Client 向 Server 发送数据,并附上数据的数字签名,签名需要使用 Cleint 的 key (具体是什么 key ,暂未理解),在 NTLM Relay 中,攻击者不知道 Client 的 key ,无法代表 Client 进行数字签名,Server 将拒绝该请求。
推荐看数字签名是什么?
Client 和 Server 是如何对数据包签名达成共识?
有两个设置在在起作用:
- 是否支持签名,这是在 NTLM negotiation (协商)期间完成
- 是否需要签名,可选还是禁用,这是在 客户端和服务器级别之间完成。
NTLM Negotiation
如果你查看 NTLM Negotiation 数据包的相关细节,就会发现其中的的 Negotiation Flags 位置:
还有另一个标志位记得补充 …. …. …. …. 1… …. …. …. = Negotiate Always Sign: Set
这是一个 Client 发送给 Server 的 NTLMSSP_NEGOTIATE
,当Negotiate Sign
为 1 时,仅表示客户端有能力签名,当Server 响应 Client 时,也类似:
注意:这里仅表明 Client 和 Server 可以进行签名,并不是说他一定会在数据包上进行签名。
例子
根据协议的不同,通常可以设置2个或3个选项来决定是否强制执行签名,这三个选项是:
- Disabled 禁用
- Enabled 启用
- Mandatory 强制性
SMB
参考:The Basics of SMB Signing (covering both SMB1 and SMB2)
Microsoft 文档中提供了一个表格,根据客户端和服务端的设置确定SMB数据包是否签名:
注:对于SMBv2及更高版本,没有Disabled 选项。
Server – Required | Server – Enabled | Server – Disabled(SMBv1) | |
---|---|---|---|
Client – Required | Signed | Signed | Signed |
Client – Enabled | Signed* (其他SMB流量默认值) |
SMBv1:Signed SMBv2: Not signed** |
Not signed*** (DC SMB流量默认值) |
Client – Disabled(SMBv1) | Signed | Not signed | Not signed |
补充相关默认值
Settings
相关组策略设置选项:
对应的 SMB Server 注册表配置项为:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
的EnableSecuritySignature
和RequireSecuritySignature
注:该图为域控上的默认值
SMB Client 的注册表位置有些不同,位置位于:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
对应SMB 签名的3 种设置:
- Required:
RequireSecuritySignature = 1
- Enabled:
EnableSecuritySignature = 1, RequireSecuritySignature = 0
- Disabled:
EnableSecuritySignature = 0, RequireSecuritySignature = 0
注:对应的组策略请自行配置
SETUP
在认证之前,Client 连接到 Server 时,步骤为:
- 协商SMB 版本和签名要求
- 认证方式
- 具有协商参数的 SMB Session
这里表明他具有 Enable参数,但是不需要签名
总结下上面的逻辑:
- Negociation :会协商很多事,其中之一表明是否支持签名
- Authentication:表明他支持什么,有没有签名能力
- Session :如果功能和要求兼容,则使用协商的内容进行会话
以下是域成员机器访问域控 C
目录的流量:
PC-jerry-0day(192.168.3.71)
向OWA2010SP3(192.168.3.142)
(域控)发送了 Negotiate Protocol Request ,Security mode
中的标志位表明开启了签名,但是不需要签名。
OWA2010SP3(192.168.3.142)
则在 Negotiate Protocol Response中标识开启了签名且需要签名。
在协商阶段,PC-jerry-0day
和OWA2010SP3
都将NEGOTIATE_SIGN
标志设置为 1,因为他们都支持签名。
注:这里可能让你迷惑,签名说的 Negotiate 是 SMB 的 ,这里的协商指的是 NTLM 的 Negotiate ,或者说 NTLMSSP_NEGOTIATE,
在NTLM Authentication 阶段完成后,SMB Session 将被签名:
LDAP
参考:
How to enable LDAP signing in Windows Server
2020 LDAP channel binding and LDAP signing requirements for Windows
Windows 新版中添加了新的内容
和 SMB 类似,LDAP 的签名设置也有 3 个等级:
- Disabled:不支持数据包签名
- Negotiated Signing:表明可以处理签名
- Required:表明不仅支持签名,而且必须对数据包进行签名
很容易得到这样的一个表格:
Server – Required | Server – Enabled | Server – Disabled | |
---|---|---|---|
Client – Required | Signed | Signed | Signed |
Client – Enabled | Signed | Signed | Not signed |
Client – Disabled | Signed | Not signed | Not signed |
和SMB 的不同在于,所有主机的设置为 “Negotiated Signing”,域控制器则不需要 签名。
Settings
相关组策略
对应的注册表选项
对于域控,对应的注册表配置项为 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters
中的 ldapserverintegrity
,值可以为 0、1、2,域控上默认为1:
0、1、2 分别对应着签名说的 禁用、协商签名、需要签名。
在 Client 上,对应的配置项位于注册表HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ldap
的ldapclientintegrity
中:
Client 的值也设置为1,默认情况下,所有的 Client 和 域控制器都具有协商签名,因此,所有LDAP 数据包都经过签名。
Setup
和SMB 签名的情况有点不同:
LDAP 没有标志位表明是否对数据包进行了签名
LDAP 使用
NEGOTIATE_SIGN
中的标志如果 Client 和 Server 都支持 签名,将设置
NEGOTIATE_SIGN
标志,并进行签名。如果一方要求签名,一方不支持,则需要签名的一方将忽略为未签名的数据包
如果想要将 LDAP 中继到服务器,需要两个要求:
- LDAP Server 不能要求签名,域控默认设置为 协商签名,这一点很容易。
- Client 未设置
NEGOTIATE_SIGN
标志,如果NEGOTIATE_SIGN
为 1,则结果协商为签名,由于不知道 Client 的 key,因此无法构造数据包进行签名,也就无法进行中继。
对应第二个条件,,默认情况下,Windwos SMB 设置了该标志,这一点导致无法将 SMB 中继到 LDAP ,能否修改NTLM 消息中的 NEGOTIATE_FLAG
,将其至为0,不能,因为, NTLM 消息也被签名了,这是下一小节的内容。
Authentication signing (MIC)
MIC 全称 Message Integrity Code(消息完整性代码),MIC是NTLM Authentication 的最后一条信息(Authentication 消息)中发送的签名,MIC使用 HMAC-MD5计算,使用 Session key 计算:
1 | MIC=HMAC_MD5(Session key, NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE) |
从上面的 MIC 计算方法看到,破环了其中任意一个消息完整性都将导致 MIC 值得改变,所以,修改
NEGOTIATE _ sign
这个办法不适用。
能不能删除MIC ,可以,MIC 是可选得,但是在 NTLM Response 存在 msAvFlags 标志,如果值是0x00000002
,它告诉 Server 必须有 MIC,因此,Server 如果没有看到 MIC ,将终止 验证。
能不能将 msAvFlags 标志位置为0,反正也没有MIC,也无法验证消息是否被更改过,这个逻辑有没有问题?
我上面没有截取完整的数据包截图,可能你没有意识到:
msAvFlags 是 NTLM Response( NTLM v2 )的一部分,如果更改此数据,NTLMv2 hash 将无效。
注:这里NTLMv2 实际上更准确的是说法应该是 NetNTLMv2 hash
现在理下逻辑,MIC 保护了 NTLM 认证过程中 3 类消息(Negotication、Changange、Authenion) 的完整性,msAvFlags 保护了 MIC 的存在,NTLMv2 hash 保护了 msAvFlags 存在,攻击者不知道用户的 key (ntlm hash),无法重新计算 NTLMv2 hash。
Drop the MIC(CVE-2019-1040)
参考链接:
CVE-2019-1040 | Windows NTLM Tampering Vulnerability
结合 CVE-2019-1040 漏洞的两种域提权利用深度分析
Exploiting CVE-2019-1040 - Combining relay vulnerabilities for RCE and Domain Admin
Drop The MIC 2 (CVE 2019-1166) & Exploiting LMv2 Clients (CVE-2019-1338)
Your Session Key is My Session Key: How to Retrieve the Session Key for Any Authentication
题外话,搜索这个洞的时候,提到Preempt的Eyal Karni,然后搜索了下国内的博文,看了一会儿安全客的文章,瞅了一眼作者,QAX发布的,文中提到A-Team发现,然后再看了下微软致谢名单,熟悉的id——n1nty ,Sanrㄟ( ▔, ▔ )ㄏ。
简单的描述下这个漏洞,删除 MIC之后,即使 msAvFlags 标志存在,Server 仍然接受身份验证。
已经集成到 ntlmrelayx 中
--remove-mic
参数。
可以看到区别,没删除该标志前,提示”The client requested signing. Relaying to LDAP will not work! “(可能有点缺乏说法力),删除该标志后,smb中继到LDAP 成功。
注:有兴趣的读者可以查看上面参考中最后一篇文章,介绍了关于MIC的另外两漏洞:CVE 2019-1166和CVE 2019-1338
Session key
在谈论 Session 和 MIC 时,反复提到 Session Key ,Session Key 取决于用户的 Key,他的计算方法是这样:
1 | # For NTLMv1 |
可以看出 NTLMv1 Session key 的算法非常脆弱,作者第二次强调不要使用 NTLMv1 。
回忆一下一开始的 NTLM Protocol 的两种认证情况。
本地身份认证,Server 直接从 Sam 中读取 key(hash);
域用户身份认证,Server 则需要使用 NETLOGON_NETWORK_INFO结构发送请求到域控,域控以NETLOGON_VALIDATION_SAM_INFO4结构进行响应。如果验证成功,则在此响应中包含 Session Key 。
这时候要说到另一个漏洞:CVE-2015-0005。
CVE-2015-0005的这个漏洞在于:执行NETLOGON 协议时,域控制器没有验证正在发送的 Authentication 信息,实际上域内的机器都可以对域控制器进行验证,获得域内任何 Session 的 Session key 。
笔者写这篇笔记的时候,微软已经修复该漏洞,为了验证只有用户进行 Authentication 的 Server 才有权请求 Session Key ,域控制器会验证 Authentication 中的目标机器和发出 NetLogon 请求的主机相同,如果不同,域控制器将拒绝该请求。
在 NTLM_AUTHENTICATION消息中,标识了 Authentication 的目标机器的相关信息。
NetLogon的相关请求可以看到第一个红色请求框部分,这里数据太多,分片多次传输。
笔者也没法在数据包层面上验证这一点,查看对应TCP 流,可以从可读字符中看到“PC-JERRY-0DAY“等字样。
修复之后,貌似这个问题解决了,@Marina Simakov发现了CVE-2019-1019,这个漏洞在于
尽管域控制器会拒绝请求,但是它会接受仅缺少计算机名称的请求。
这个漏洞如何利用?
- 考虑的第一个问题,删除字段会破环 MIC
- MIC能不能重新计算?可以,前面说过 MIC 的算法为通过 Session Key 对 3 类消息进行 HMAC-MD5 计算,重新计算MIC 即可
笔者只是泛泛而谈,一些技术细节笔者暂时未懂也无法描述。
已经集成到
ntlmrelayx.py
的-remove-target
参数中。
这里直接访问
ntlmrelayx.py
所在的地址,触发401认证,实战中建议更隐蔽的方式(比如直接dir 下 ,或者配合前面的劫持)。并且这里还存在一些问题,看提示已经拿到了bootkey ,貌似因为其他原因无法dump ntds,无法更进一步的解密。
笔者在github 上 搜索到一个脚本,但是在使用上貌似有些问题,有解决的师傅求指导。
题外话:笔者在写这段的时候,觉得这个故事真的非常好玩。
Channel Binding
前面不断地的强调验证层(NTLM)几乎独立于应用层(SMB、LDAP等),为什么说几乎,因为部分协议使用NTLM 的标志位来确认是否签名。
由于这个特性,导致了跨协议中继称为可能。
于是,出现了一种新的机制来防御这种攻击,称为 Channel Binding 或 EPA(Enhanced Protection for Authentication ,身份增强保护)。
笔者补充下,EPA 为 Windows 中对 rfc5056的实现。
它的保护原理为将身份验证层和使用的协议进行绑定,即使存在TLS层(比如LDAPS和HTTPS),一般是在最后一条 NTLM AUTHENTICATE 中加入额外的信息,并且攻击者无法修改。该信息说明使用的服务,并且可能包含服务器证书的哈希的信息。
Service binding
如果 Client 希望向 Server 进行身份验证使用服务,则在 NTLM Response 添加标识服务的信息(实际上就是SPN)。
当Server 收到该 AUTHENTICATE 时,如果NTLM Response 中的服务和实际请求的内容不同,将不同意该服务。
Service name 在NTLM Response 中,受MIC 保护,想想前面为了修改这部分的内容有多困难。
如果配合前面的 CVE-2019-1040 ,是可以 bypass EPA的。
笔者仍是没找到如何开启EPA。。,这里用的作者的图。
最后说一点,显然需要 Client 和所有 Server (包括DC)都支持EPA。
TLS Binding
这种保护的的目的是为了保护认证层(NTLM)和可能使用的TLS 层联系。
如果 Client 使用封装在 TLS中的协议(HTTPS、LDAPS),它将与 Server 建立 TLS Sessioin ,计算 Server 证书的 hash。这个散列称为 Channel Binding Token(CBT),将CDN 放入 NTLM response 中。Server 在认证结束时读取 CBT ,和自己证书的 hash 比较,如果不同,这意味着它不是NTLM exchange 的最初接受者。
同样,由于这个散列在 NTLM response ,MIC 同样保护了它,利用CVE-2019-1040 同样可以 bypass 它(未实验,猜测可以)。
由于这种特性,以下两种攻击将不会发生:
将没有使用 TLS 的协议 中继到具有 TLS 的协议(如HTTP到LDAPS)
将使用TLS 的协议中继到另一个使用TLS 的协议(如HTTPS到LDAPS)
如果 Client 在 attacker 之间建立TLS 链接,它无法提供 Server 证书,只能提供一个自制的证书,这个证书 的 hash 放入 NTLM response 中时,Server 比较和实际的证书不相同将拒绝该验证。
What can be relayed?
上面介绍了诸多情况,大致可以了解跨协议中继的不同情况,作者提供了一个表格,可方便快速的查询。
Stop. Using. NTLMv1
对比下 NTLMv1 hash 和 NTLM v2 的算法:
1 | # NTLMv1 Response |
来源:LM-Hash、NTLM-Hash、Net-NTLMv1、Net-NTLMv2详解
可以看出 NTLMv2 hash 不仅考虑了 Client Challenge、Server Challenge,还考虑了msAvFlags 标志、说明 MIC 的存在,表明 Authentication 的NetBIOS 名称的字段,Service binding 下有着 SPN 信息,TLS binding 下有着 证书 hash(CBT)。
NTLMv1 仅考虑 Server Challenge,无法添加其他信息(NetBIOS 名称、msAvFlags、 SPN or CBT).
如果使用的是NTLMv1 ,攻击者可以删除 MIC,中继到 LDAP 或者 LDAPS。
并且可以构造 NetLogon 请求检索 Session Key ,域控无法检查 它是否有对应权力这样做。
有了Session Key (不是数据包中的 明文的 Key ,签名的 Key),就可以签名任意数据包。
Conclusion
总结下本篇 NTLM Relay 中的重点:
- 对 NTLM relay 的相关细节认识 Authentication 和 Session 独立性,使得跨协议中继称为可能。
- signing (签名) 保护了 Server 免受中间人攻击,那么要想在签名的情况下中继就需要考虑更改签名。
- MIC 保护了 NTLM exchanges ,一些标志位说明了MIC 的存在(msAvFlags)
- 最后介绍了 Channel Binding 通过 Service binding 和 TLS Binding 来保护认证层(NTLM)和 会话层。