ntlm中继及签名

457 阅读6分钟

引言

在通过NTLM验证之后,后续的数据包传输,往往经过了client签名,这里我们就来谈一谈这个签名

签名

在通过 NTLM 认证之后,才正式开始通信,也就是 session 阶段
在支持签名的情况下,在通信阶段所有的数据包都有签名,可以确保数据包不会被篡改(签名使用client密码加密), Attacker无法伪造签名,所以server会验证失败进而拒绝数据包。也就是说,attacker仅仅通过了验证,后面的操作都无法进行,如:执行命令,后门

所以说签名是一个非常有效的防御NTLM-Relay攻击的方法! 由签名牵扯出以下两个问题:
1.是否支持签名。这会在NTLM协商阶段完成
2.开启,可选,禁用签名?在客户端与服务端完成

在不同的上层协议下,对签名的支持情况也不同,这里拿 SMBLDAP 举例

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服务器的时候,步骤如下

  1. 协商SMB版本和签名是否需要
  2. 身份认证
  3. 会话

LDAP

同样有三个选项

  • disable 不签名
  • negotiated signing 可选
  • required 必须签名

组合结果如下:

和SMB不一样的是,所以主机默认设置为Negotiated Signed,域控同样默认为Negotiated Signed
根据上表可知,client和server都为Negotiated Signed组合为必须签名,但是只要有一方为Disable,则不需要签名

域控:

普通机器:

在LDAP中,如果一方需要签名(Required),而另一方不支持签名(Disable),那么会话将无法开始,需要签名的一方将忽略未签名的数据包

如果咱们要在LDAP协议上进行NTLM中继,则需要满足以下条件:

  1. client/server都不能设置为required,因为只要一方设置为required,则必须使用签名。这里条件默认满足
  2. 还需要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中继攻击需要做以下几件事:

  1. 移除MIC
  2. negotiate_sign置为0

绕过MIC签名方法:
NEGOTIATE KEY EXCHANGENEGOTIATE_VERSION位置为0,就不再检验MIC了,这也是CVE2019-1040的要点。
前者置为0则表示移除MIC,后者表示移除版本号(必须的,否则会报错),当然,具体的MIC字段也需要移除

绕过MIC签名之后就是绕过LDAP签名,即将NEGOTIATE_SIGN设置为0。具体为:

  • NTLMSSP_NEGOTIATE_ALWAYS_SIGN
  • NTLMSSP_NEGOTIATE_SIGN

取消上述两个字段的设置即可

防御

主要有两点

  1. 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

  1. 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无法修改

参考

en.hackndo.com/ntlm-relay