一文详解Ntlm Relay

Ntlm Rleay简介

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

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

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

看一下如下图:

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

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这台机器。

紧接着我们到DC上面去请求一下攻击者这台机器。

去dir \10.211.1.45\addwadwa 只需要访问到攻击者的SMB服务即可。

我们这里wireshark抓包,我们需要着重注意红框中的6个包。

他们分别代表着 协商,质询,认证。

我们先来简单看一下这个包,会发现其实攻击者一直在做一个转发的事情,攻击者就是一个代理转发点,一直转发着客户端和服务端的数据。

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

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

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

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

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

会话签名

签名其实就是一个校验数据在发送期间有没有被更改的方法,比如说张三给李四发送了一个hello world的文档,并且对这个文档进行了数字签名,那么任何收到该文档并且和他签名(张三)的人都可以验证编辑它的人是张三 ,并且可以确定他写了这句话。因为签名保证文档没有被修改,只要协议支持,签名原则可以应用于任何协议,例如SMB协议,Ldap协议,HTTP等等,但是在实际情况中,HTTP前面很少实现。

签名的意义就是当客户端想要访问服务的时候,由于攻击者可以处在中间人的位置并且中继身份信息,因此他可以在于服务器交互的时候冒充客户端。这就是签名发挥作用的时候。

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

所以说数据包必须在认证后进行签名,那么攻击者就攻击不了了,因为他不知道客户端的密钥。

认证之后代表的是这个包: 协商->质询->认证

但是客户端和服务端如何才能达成一致的呢,就比如说我客户端想要签名,你服务端不知道我客户端想要签名,所以服务端如果不签名的话,又是什么情况呢?

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

NTLM 协商

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

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

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

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

所以说,这种协商只是客户端向服务端表示我支持签名,同样服务端向客户端表示我支持签名,但是这并不意味着数据包就会被签名,就比如说HTTP协议,即使客户端和服务端都支持签名,其实实际上也会很少签名。

微软提供了标记位,用于确定SMB数据包是否基于客户端和服务端的设置来进行签名,而对于SMBV2的版本是必须处理签名的。

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

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

win7:

DC:

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

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

我们来抓包看下:

首先这里我们不用kali来去做这个中继,我们直接访问1.2

然后进行抓包。

主要查看这两个包。

可以看到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。

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

那么在协商阶段的时候,客户端和服务端将NEGOTIATE_SIGN标志设置为1,因为他们都支持签名。完成身份验证之后,会话继续。

那么我们来测试一下,如果客户端没有设置签名,但是服务端设置了签名并且要求签名,能不能中继成功?(如下测试是对于SMBV1的)

显然是不行的。

那么如果服务单没有设置签名,客户端设置了签名,能不能中继成功?

我们发现是可以的。

wireshark如下抓包:

那么如果服务端支持签名,但是不需要签名,我们发现还是可以中继成功的。

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

如上的测试只需要改注册表的值即可,就是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。

那么对于客户端来说,Ldap签名设置是在HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ldap注册表中。他的默认值也是1。

所以说服务端协商签名,客户端也协商签名,所以,所有的Ldap数据包都会被签名。(这里说的是Ldap的级别1)

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

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

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

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

MIC签名

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

如下图:

我们使用ntlmrelay.py进行中继。可以看到是无法中继的。

所以我们在想,既然不能中继到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值。

所以说啊,如果把将NTLM消息这部分改了,那么MIC就不会生效了,所以我们无法更改NEGOTIATE_SIGN标记。

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

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

它是通过msAvFlags 值来进行可选的,如果他的值为0x00000002 那么它就会告诉服务器必须存在MIC,如果不存在的话,就会直接终止身份验证。

那么如果我们将msAvFlags的值设置为0,然后移除MIC,是不是可以呢?

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

也就是说更改或者删除MIC标记会使NTLMV2Hash无效。因为数据被修改之后它是这样子的。

MIC保护了协商,质询,认证这三条消息的完整性,而msAvFlags保护的是MIC的存在,NTLMv2 哈希保护标志的存在,因为攻击者不知道客户端的密钥,所以不能计算这个Hash值。

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

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

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

我们来使用一下:

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

如下图可以看到user4已经是企业管理组的成员了。

CVE-2019-1040的漏洞范围是:

Windows 7 sp1 至Windows 10 1903

Windows Server 2008 至Windows Server 2019

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

这是因为你没有安装证书服务导致的,所以在AD控制面板哪里添加功能,选择证书服务。

如下图: 可以百度搜索安装ADCS证书服务。 这里可以参考:https://lework.github.io/2019/07/24/ad-install/#启用ldaps

之后我们使用LDP.exe连接Ldaps服务。

记得勾选上SSL即可。

紧接着我们再来Ldaps中继,可以发现成功了。

通道绑定

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

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

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

如下图,客户端在NTLM响应中加了要访问的服务,攻击者如果中继给服务端是其他服务的话,那么服务端就会直接拒绝连接。

具体来说所谓服务其实就是SPN,之前的文档里面讲过。

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

那么怎么设置呢???

默认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。

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响应中,从而和服务端的服务进行对比。

相关推荐
面朝大海,春不暖,花不开13 分钟前
Java网络编程:TCP/UDP套接字通信详解
java·网络·tcp/ip
ChicagoTypewriter19 分钟前
计算机网络中的常用表项梳理
网络·计算机网络·智能路由器
A5rZ1 小时前
Puppeteer 相关漏洞-- Google 2025 Sourceless
网络安全
IC 见路不走1 小时前
LeetCode 第91题:解码方法
linux·运维·服务器
TDengine (老段)1 小时前
TDengine STMT2 API 使用指南
java·大数据·物联网·时序数据库·iot·tdengine·涛思数据
翻滚吧键盘1 小时前
查看linux中steam游戏的兼容性
linux·运维·游戏
小能喵1 小时前
Kali Linux Wifi 伪造热点
linux·安全·kali·kali linux
汀沿河2 小时前
8.1 prefix Tunning与Prompt Tunning模型微调方法
linux·运维·服务器·人工智能
zly35002 小时前
centos7 ping127.0.0.1不通
linux·运维·服务器
小哥山水之间3 小时前
基于dropbear实现嵌入式系统ssh服务端与客户端完整交互
linux