引言
在通过NTLM验证之后,后续的数据包传输,往往经过了client签名,这里我们就来谈一谈这个签名
签名
在通过 NTLM 认证之后,才正式开始通信,也就是 session 阶段
在支持签名的情况下,在通信阶段所有的数据包都有签名,可以确保数据包不会被篡改(签名使用client密码加密), Attacker无法伪造签名,所以server会验证失败进而拒绝数据包。也就是说,attacker仅仅通过了验证,后面的操作都无法进行,如:执行命令,后门
所以说签名是一个非常有效的防御NTLM-Relay攻击的方法!
由签名牵扯出以下两个问题:
1.是否支持签名。这会在NTLM协商阶段完成
2.开启,可选,禁用签名?在客户端与服务端完成
在不同的上层协议下,对签名的支持情况也不同,这里拿 SMB 和 LDAP 举例
SMB
如图,上述第一个问题:
当字段
Negotiate Sign被客户端设置为1,表示client支持签名。但是,这并不意味着必须就数据包签名,只是说支持签名!
如果双方都支持签名,接下来会决定是否开启签名,一般有两个或三个选项:
Disabled不使用签名Enable如果有需要可以使用Mandatory(Required) 强制的,强制使用签名,即使不支持签名
下表表示client/server选择不同时最终结果
注意:在SMBv2之后已经没有Disable选项,必须处理签名
从上表及下面的文字可以看出,域控默认开启签名,域内其他机器默认不开启
设置
在普通机器上:
注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
可以看到都为0(关闭)
域控上则都为1,这里就不展示了
当设置支持签名后:
可以看到在身份认证之前,这个参数已经设置了,当client连接server服务器的时候,步骤如下
- 协商SMB版本和签名是否需要
- 身份认证
- 会话
LDAP
同样有三个选项
disable不签名negotiated signing可选required必须签名
组合结果如下:
和SMB不一样的是,所以主机默认设置为Negotiated Signed,域控同样默认为Negotiated Signed
根据上表可知,client和server都为Negotiated Signed组合为必须签名,但是只要有一方为Disable,则不需要签名
域控:
普通机器:
在LDAP中,如果一方需要签名(Required),而另一方不支持签名(Disable),那么会话将无法开始,需要签名的一方将忽略未签名的数据包
如果咱们要在LDAP协议上进行NTLM中继,则需要满足以下条件:
- client/server都不能设置为
required,因为只要一方设置为required,则必须使用签名。这里条件默认满足 - 还需要server/client其中一方设置为
disable
所以,在LDAP基础上默认情况下是不可以进行中继攻击的。这时候有人问:直接把negotiate_flag设置为0呢?(即disable) 那不就可以了?但是不幸的是,在LDAP里面,NTLM消息同样被签名了,接下来会讲到
这里先提一嘴LDAPS,没错这个S是TLS。TLS将会接手处理签名和加密。所以,LDAPS客户端没有任何能力对数据包进行签名。因此,如果LDAPS服务端接受到negotiate_sign设置为1的,它将拒绝身份认证!
如图:将SMB中继到LDAPS:
client发来SMB并请求认证,并且negotiate_sign为1,如果咱们什么都不改变,通过LDAPS请求DC,根据上述,会终止身份认证!又回到了上面那个问题,咱们能更改negotiate_sign吗?
接下来又引出下一个角色:MIC(Message Integrity Code)
它也是一个在NTLM等级的签名。
MIC是仅在身份验证的最后一条消息中发送的签名,使用HMAC_MD5加密,需要client密码,所以攻击者无法伪造MIC。并且MIC关联了NTLM身份验证中的三条消息,如果任意一条被改动,MIC将失效。所以这里咱们不能直接修改negotiate_sign
那是否能移除MIC呢?很遗憾不行。因为还有一个字段表示MIC是否存在,msAvFlags,如果它为0x00000002表示MIC是必须的
那能否将这个msAvFlags改为0,然后再移除MIC呢?
答案是可以的!
还记得身份认证中的Response吗,即客户端加密的challenge,它不仅仅包含challenge,还包含了所有的响应标志。没错,msAvFlags也在里面。但是问题又来了,如果修改这个值的话,会使得response不合法(它参与response的计算),验证也无法通过!所以msAvFlags也不能修改
如图,他们之间的关系:
MIC保护三条信息的完整性,AvFlags保护MIC,responser保护MIC,环环相扣啊!
这里再引出 CVE-2019-1040 ,它就是绕过了签名
根据上述信息,如果要LDAP中继攻击需要做以下几件事:
- 移除MIC
negotiate_sign置为0
绕过MIC签名方法:
将NEGOTIATE KEY EXCHANGE和NEGOTIATE_VERSION位置为0,就不再检验MIC了,这也是CVE2019-1040的要点。
前者置为0则表示移除MIC,后者表示移除版本号(必须的,否则会报错),当然,具体的MIC字段也需要移除
绕过MIC签名之后就是绕过LDAP签名,即将NEGOTIATE_SIGN设置为0。具体为:
- NTLMSSP_NEGOTIATE_ALWAYS_SIGN
- NTLMSSP_NEGOTIATE_SIGN
取消上述两个字段的设置即可
防御
主要有两点
- SPN信息绑定
在client请求server的时候,会把请求的SPN加到ntlm response中,被NtProofStr Response保护。NtProofStr Response包含很多信息,如:HMAC_MD5信息,Challenge,其他信息如msAvFlags等等,由client密码加密,因此attackter无法修改SPN信息。
server收到最后的消息之后,会对比NTLM message里面的SPN信息和client请求的服务进行对比,不匹配则拒绝连接
如图为NTLM里面的SPN信息:
大致如下图:
这里看起来像是协议检测,并不是,比如client ---> attacker 走的http协议,再到server,走的SMB协议,SPN一般为cifs
- TLS绑定
如果client想使用封装在TLS里面的协议,如:https,ldaps。它将与server建立TLS会话,并且会计算server证书hash。这个hash被称为Channel Binding Token(CBT)。计算完成后client会将它放入NTLM message中。当合法server最后收到NTLM message时候,会和真实的证书进行验证。
同样该hash也是在NTLM message中,也受到NtProofStr Response保护,attacker无法修改