freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

一文详解Ntlm Relay
2023-11-09 20:09:12

Ntlm Rleay简介

Ntlm Rleay翻译过来就是Ntlm 中继的意思,也肯定是跟Ntlm协议是相关的,既然要中继,那么攻击者扮演的就是一个中间人的角色,类似于ARP欺骗,ARP欺骗就是在一个广播域中发送一些广播,然后大声问这个IP地址的MAC地址是多少啊???如果有不怀好意的人回答了,那么就造成了ARP欺骗,好似一个中间人攻击。

就比如说有一个客户端和一个服务端,客户端请求服务端的某个服务,需要身份验证,客户端提供身份验证,服务端响应,这原本是一次很正常的流程,但是如果加入了攻击者这个角色,那么就变成了攻击者发送同样的消息给服务端,服务端进行响应,然后交给攻击者,攻击者返还给客户端。

那么我们可以想象其实攻击者就是充当了一个代理转发点。

看一下如下图:

攻击者在客户端和服务端的中间,也就是说你客户端发送的无论是质询,响应,认证,我攻击者都是可以收到的,为什么会收到?,因为客户端以为攻击者是服务端,而正好相反,服务端以为攻击者是客户端,这就造成了,客户端将数据给攻击者,攻击者再将数据发送给服务端,同样服务端返回数据给攻击者,攻击者也返回数据给客户端,那么这中间如果攻击者对数据进行了修改,或者说发送给其他人了,并没有发送给原来的客户端,那么就可能造成了安全问题。
image.png

Ntlm Relay测试分析

这里的测试环境:
域:relaysec.com
user-win7 10.211.1.2
dc 10.211.1.210
kali 10.211.1.45
这里我们使用ntlmrelay.py

ntlmrelay.py可以将获取到Ntlm中继到内网的其他机器。

这里表示的意思就是,如果我获取到了其他机器的SMB凭据,我中继给1.2这台机器。
image.png
紧接着我们到DC上面去请求一下攻击者这台机器。

去dir \10.211.1.45\addwadwa 只需要访问到攻击者的SMB服务即可。
image.png我们这里wireshark抓包,我们需要着重注意红框中的6个包。
image.png
他们分别代表着 协商,质询,认证。
image.png
我们先来简单看一下这个包,会发现其实攻击者一直在做一个转发的事情,攻击者就是一个代理转发点,一直转发着客户端和服务端的数据。

我们先来看第二组包,也就是DC给攻击者发送质询包的时候。

image.png

我们直接来看质询值,会发现客户端发送给攻击者的质询值和攻击者发送给DC的质询值是没有改变的。这两个包其实是一样的。
image.png
image.png

也就是说当攻击者收到这个请求的时候,他会原封不动的将包发送给210。

我们可以看到攻击者只是在转发东西,它只是将信息从客户端传递到服务端,只是最后服务端以为攻击者身份验证成功,所以攻击者可以代表DC去WIN7这台机器上操作。

这里中间还有SSPI和NTLM SSP这里当作了解即可,可以看之前的NTLM协议那篇文章。

会话签名

签名其实就是一个校验数据在发送期间有没有被更改的方法,比如说张三给李四发送了一个hello world的文档,并且对这个文档进行了数字签名,那么任何收到该文档并且和他签名(张三)的人都可以验证编辑它的人是张三,并且可以确定他写了这句话。因为签名保证文档没有被修改,只要协议支持,签名原则可以应用于任何协议,例如SMB协议,Ldap协议,HTTP等等,但是在实际情况中,HTTP前面很少实现。
image.png
签名的意义就是当客户端想要访问服务的时候,由于攻击者可以处在中间人的位置并且中继身份信息,因此他可以在于服务器交互的时候冒充客户端。这就是签名发挥作用的时候。

在Ntlm中继中,攻击者想要伪造客户端,但是他不知道的客户端的密钥,因此他就无法替客户端做任何事情。由于攻击者无法对任何数据包进行签名,因此接收到数据包的服务端查看有没有签名或者说这个签名对不对,如果不对或者没有签名的话,服务端直接拒绝攻击者的请求。
image.png
所以说数据包必须在认证后进行签名,那么攻击者就攻击不了了,因为他不知道客户端的密钥。

认证之后代表的是这个包: 协商->质询->认证
image.png
但是客户端和服务端如何才能达成一致的呢,就比如说我客户端想要签名,你服务端不知道我客户端想要签名,所以服务端如果不签名的话,又是什么情况呢?

所以来到了NTLM的协商阶段,也就是协商包呗。

NTLM 协商

这个协商包,我们之前已经再NTLM协议中了解过了这里直接来看他的标志位。

这里的有很多的协商标记,这里我在Ntlm协议哪里已经详细解释过了,我们这里主要看NEGOTIATE SIGN

这个协商标记设置的是1,他表示客户端支持签名,但是这并不代表服务端一定会签署客户端的数据包,只是客户端有这个能力。

同样当服务端回复的时候,如果支持签名的话,这个标记位也是1。

所以说,这种协商只是客户端向服务端表示我支持签名,同样服务端向客户端表示我支持签名,但是这并不意味着数据包就会被签名,就比如说HTTP协议,即使客户端和服务端都支持签名,其实实际上也会很少签名。
image.png
微软提供了标记位,用于确定SMB数据包是否基于客户端和服务端的设置来进行签名,而对于SMBV2的版本是必须处理签名的。

我们可以在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters注册表中更改EnableSecuritySignature键和RequireSecuritySignature键,这两个的值需要改成1。

注意:这里你不能只更改一台机器为SMBV2,否则还是不签名。
win7:
image.png
DC:

image.png
紧接着我们使用ntlmrelay.py工具进行攻击。

可以发现已经明显不行了。
image.png

我们来抓包看下:

首先这里我们不用kali来去做这个中继,我们直接访问1.2
image.png
然后进行抓包。

主要查看这两个包。
image.png
可以看到10.211.1.210去访问10.211.1.2的时候,签名状态。

这两个值其实就是我们上面在注册表中设置的值,我这里给10.211.1.210设置为了EnableSecuritySignature为1,RequireSecuritySignature为0。EnableSecuritySignature设置为1表示10.211.1.210支持签名,RequireSecuritySignature设置为0表示我不用签名。说的简单点就是虽然我支持签名,但是协商不签名。但是如果服务端需要签名的话,服务端可以处理我的签名。
我们再来看服务端也就是10.211.1.2。

这里它表示我不仅支持签名,我还需要签名。
image.png

那么在协商阶段的时候,客户端和服务端将NEGOTIATE_SIGN标志设置为1,因为他们都支持签名。完成身份验证之后,会话继续。
image.png
那么我们来测试一下,如果客户端没有设置签名,但是服务端设置了签名并且要求签名,能不能中继成功?(如下测试是对于SMBV1的)

显然是不行的。
image.png
那么如果服务单没有设置签名,客户端设置了签名,能不能中继成功?

我们发现是可以的。
image.png
wireshark如下抓包:
image.png
那么如果服务端支持签名,但是不需要签名,我们发现还是可以中继成功的。

那么也就是说服务端需要既支持签名又需要签名,客户端无论需不需要,都要签名。

如上的测试只需要改注册表的值即可,就是RequireSecuritySignature和EnableSecuritySignature这两个值改为0或1。

Ldap签名

Ldap签名有3个级别。

  1. 禁用: 这意味着不支持数据包签名。
  2. Negotiated Signing:此选项表示协商签名,如果与他通信的机器也协商签名,那么数据包就会被签名。
  3. 必须签名:这代表不仅支持签名,而且必须对数据包进行签名才能使会话继续。

在域控中Ldap签名是在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters/注册表中的ldapserverintegrity选项,他的值可以为0,1,2分别代表着Ldap签名的级别。默认他的值为1。
image.png
那么对于客户端来说,Ldap签名设置是在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ldap注册表中。他的默认值也是1。
image.png
所以说服务端协商签名,客户端也协商签名,所以,所有的Ldap数据包都会被签名。(这里说的是Ldap的级别1)

那么如果一方需要签名,而另一方不支持签名,那么需要签名的一方会忽略未签名的数据包。(这里说的是Ldap级别2)

那么如果我们需要使用Ldap将身份验证中继到服务器,那么必须满足两个要求。

  1. 服务端不能设置为需要签名,也就是Ldap的级别为2,默认情况下所有的机器都是协商签名,而不是必须签名。
  2. 客户端不能设置NEGOTIATE_SIGN(SMB签名)为1,如果设置了那么客户端就希望签名,因为攻击者不知道客户端的密钥,所以就无法签署数据包。

关于第二点,那么客户端如果不设置此标记的话,那么是不是就可以中继了呢?Windows SMB客户端设置了它,默认情况下,我们无法将SMB身份验证中继到LDAP。

MIC签名

这里目前有一个环境,就是说我这台1.2机器上也就是服务端不仅支持签名而且需要签名,那么攻击者就无法通过SMB进行中继。

如下图:
image.png
我们使用ntlmrelay.py进行中继。可以看到是无法中继的。
image.png
所以我们在想,既然不能中继到SMB协议上,那么能不能中继到其他协议?比如Ldaps协议。

Ldaps对应的端口是636。

我们都知道NEGOTIATE_SIGN标记是用于客户端和服务端是否支持签名的,但是在某些情况下,LDAP/LDAPS会考虑这个标记。

对于LDAPS来说,服务端也会考虑这个标志,如果服务端看到客户端的NEGOTIATE_SIGN标记设置为1,那么服务端直接拒绝身份验证,这是因为LDAPS也是基于TLS的LDAP,他是会处理数据包签名的TLS层。

那么现在来说我们中继的客户端需要通过SMB进行身份验证,但是它支持数据包签名,它将NEGOTIATE_SIGN标志设置为了1,但是如果我们通过LDAPS来中继身份验证,但是LDAPS服务端也会看到这个标记,并且终止身份验证。

也就是说无论是SMB还是LDAP/LDAPS,看到这个NEGOTIATE_SIGN标记位设置为了1,那么就会终止会话,因为攻击者无法对数据包签名,攻击者不知道客户端的密钥。

那么我们能不能将这个标记给它干掉呢?就比如说给他删掉,这鸟标记太烦人了。

但是这个标记我们干不掉,因为在它的上面还有一个NTLM级别的签名,那么就是MIC签名。

MIC签名是如下计算的。
HMAC_MD5(Session key, NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE)
最重要的是会话密钥是用客户端的密钥进行加密的,所以攻击者无法计算MIC值。
image.png
所以说啊,如果把将NTLM消息这部分改了,那么MIC就不会生效了,所以我们无法更改NEGOTIATE_SIGN标记。

那么我们能不能将MIC给它干掉呢?这是可以的,因为MIC是可选的。

那么它通过什么来可选的呢?

它是通过msAvFlags值来进行可选的,如果他的值为0x00000002那么它就会告诉服务器必须存在MIC,如果不存在的话,就会直接终止身份验证。
image.png那么如果我们将msAvFlags的值设置为0,然后移除MIC,是不是可以呢?

这样是不行的,因为当客户端请求服务端质询的时候,服务端返回NTLMV2 Hash,这个Hash它不仅仅考虑了质询,而且还考虑了所有标志的HASH,所以说MIC存在的标志也是响应的一部分。

也就是说更改或者删除MIC标记会使NTLMV2Hash无效。因为数据被修改之后它是这样子的。
image.png
MIC保护了协商,质询,认证这三条消息的完整性,而msAvFlags保护的是MIC的存在,NTLMv2 哈希保护标志的存在,因为攻击者不知道客户端的密钥,所以不能计算这个Hash值。

所以这种情况下我们是不能攻击的。

但是老外发现了一个相关的漏洞,CVE-2019-1040,它可以绕过NTLM MIC(消息完整性检查)保护。

已经集成到了ntlmrelayx.py --remove-mic

我们来使用一下:

可以看到这里成功将user4用户添加到企业管理组里面了,这里是通过SMB协议进行触发的,中继到了Ldap协议。这里中继的是ldap,ldaps也是可以的,这里的ip是210,因为只有域控有Ldap服务。
image.png
如下图可以看到user4已经是企业管理组的成员了。

image.png
CVE-2019-1040的漏洞范围是:

Windows 7 sp1 至Windows 10 1903

Windows Server 2008 至Windows Server 2019

那么你如果使用Ldaps去中继的时候会出现这样的问题。

这是因为你没有安装证书服务导致的,所以在AD控制面板哪里添加功能,选择证书服务。
image.png
如下图: 可以百度搜索安装ADCS证书服务。 这里可以参考:https://lework.github.io/2019/07/24/ad-install/#%E5%90%AF%E7%94%A8ldaps
image.png
之后我们使用LDP.exe连接Ldaps服务。

记得勾选上SSL即可。
image.png
紧接着我们再来Ldaps中继,可以发现成功了。
image.png

通道绑定

那么通道绑定是干什么的呢?就如我们上面看到的,我们可以通过跨协议中继,通道绑定就是为了解决这个问题。

其实就是将身份验证和正在使用的协议绑定在一起,攻击者就无法修改,如果客户端希望对服务器进行身份验证以及使用特定的服务,例如cifs等等,则将该标识性的信息添加到NTLM响应中,由于服务名称在NTLM响应中,所以因此它受到NtProofStr响应的保护,该响应是此信息以及其实和MIC计算的那个msAvFlags值是差不多的,都是使用客户端的密钥进行计算的。

就比如说客户端去请求服务端,客户端已经在他的NTLM响应中指明了他要访问的服务,并且由于攻击者无法修改它,当攻击者将请求中继给服务端的时候,将攻击者请求的SMB服务,和 NTLM响应中的HTTP服务进行对比,发现是不同的服务,所以直接拒绝连接。

如下图,客户端在NTLM响应中加了要访问的服务,攻击者如果中继给服务端是其他服务的话,那么服务端就会直接拒绝连接。
image.png
具体来说所谓服务其实就是SPN,之前的文档里面讲过。

可以看到它使用的是CIFS服务,也就是SMB协议,,不仅有服务名称 (CIFS),还有目标名称或 IP 地址。这意味着如果攻击者将此消息中继到服务器,服务器也会检查目标部分,并会拒绝连接,因为在 SPN 中找到的 IP 地址与他的 IP 地址不匹配。因此,如果所有客户端和所有服务器都支持这种保护,并且每台服务器都需要这种保护,那么它可以减少所有中继尝试。
image.png
那么怎么设置呢???

默认win2012是没有这个东西,网上资料显示是win10才新加的策略。

参考:https://learn.microsoft.com/zh-cn/windows/security/threat-protection/security-policy-settings/domain-controller-ldap-server-channel-binding-token-requirements

那些协议可以中继

NEGOTIATE_SIGN如果不需要签名,则任何未设置标记的客户端都可以中继到Ldap。
image.png

NTLMV1的危害

在NTLMV2中,NTLMV2哈希考虑了msAvFlags标记位,MIC字段,还有NetBios名称的字段等等,但是NTLMV2的哈希是没有任何附加信息的,例如没有MIC,目标名称,SPN等等。因此如果服务端允许NTLMV1身份验证的话,攻击者可以直接移除MIC字段,从而将身份验证中继到Ldap或Ldaps。

但更重要的是,他可以发出 NetLogon 请求以检索会话密钥。确实,域控制器没有办法检查他是否有权这样做。而且由于它不会阻止不是完全最新的生产网络,它会出于“复古兼容性原因”将其提供给攻击者。

这一点可以在ZeroLogon这个漏洞中进行体现。

总结

SMB V1中继到SMBV1 服务端如果没有设置签名,也就是RequireSecuritySignature和EnableSecuritySignature这两个值。那么就可以中继成功,无论客户端是否支持签名还是需要签名,是可以中继成功的。

SMBV2默认需要签名。

跨协议中继,SMBV2中继到Ldap服务,这是利用了CVE-2019-1040这个漏洞,这个漏洞可以绕过MIC签名。

SMBV2中继到Ldaps服务,需要安装ADCS证书服务。

通道绑定可以解决跨协议中继的问题,将服务的标识放在了NTLM响应中,从而和服务端的服务进行对比。

# 内网渗透 # 域渗透
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录