目录

NTLM Relay

NTLM Relay

1 前言

1.1 背景介绍

NTLM Relay,中间人攻击或重放攻击是一个意思。

B 是一个 smb 服务器,A 来进行认证,B 将 A 的认证信息转发到 C 上,如果 A 的凭证在 C 上认证成功就能进行下一步操作,如创建服务执行命令。如果在域中控制了某些常用服务,如:WEB OA 系统、文件共享等服务则可以尝试使用 SMB 中继攻击来引诱域管理员访问达到获取其他机器权限的目的。

2001 年,最早由 Dystic 实现,SMBRelay

2004 年,发展为 HTTP -> SMB,BlackHat,未开源

2007 年,HTTP -> SMB 被集成到 MetaSploit

2008 年,HTTP -> HTTP的 NTLM 攻击被实现(MS08-067)

1.2 认证过程

两端模型:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509090900.png-water_print

三端模型:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207143016.png-water_print

在域环境下的 NTLM Relay 的模型:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207143306.png-water_print

1.3 HTTP -> SMB 攻击实验

1.3.1 nmap 探测 SMB 签名

nmap 扫描:

1
nmap -p445 --script=smb-security-mode.nse IP --open

1.3.2 使用 ntmlrelayx.py 测试

ntmlrelayx.py 脚本在 empire 包中

1
ntlmrelayx.py -tf hosts.txt -socks -smb2support

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509100947.png-water_print

注意
发起攻击时,HTTP -> SMB,开启 80 端口,需要保证端口未被占用

攻击成功后,会在攻击机本地开启 1080 socks 端口,通过 proxychain 等代理工具,即可控制目标机器。

1
2
# mac 下 proxychain-NG
proxychains4 /Users/Geekby/opt/anaconda3/bin/python secretsdump.py pentest.com/Administrator@172.16.147.132

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509104954.png-water_print

注意
进行认证时会提示输入密码,留空即可使用 relay 后的凭据进行认证。

1.4 Hot Potato

Hot Potato 是一个经典的利用 NTLM Relay 获取高权限用户控制权的例子,可以参考「Potato 家族提权分析」这篇文章。

1.5 NTLM Relay 防御

目前有许多针对 NTLM 重放攻击的防御措施,主要包括以下几种:

  • SMB & LDAP 签名
  • EAP (Enhanced Protection Authentication)
  • LDAPS Channels
  • Server target SPN Validation

1.5.1 SMB & LDAP 签名

完成认证后,应用服务器和客户端之间的所有流量都有签名验证保护;用户签名的会话密钥基于客户端的 NTLM 值生成,应用服务器在 NETLOGON 阶段从 DC 服务器获取;客户端采用和 DC 相同的算法,基于自身的 NTLM 值生成会话密钥,因此中间人攻击没有办法获取会话密钥

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207144728.png-water_print

1.5.2 EAP (Enhanced Protection Authentication)

NTLM 认证和一个安全通道进行绑定,在 NTLM 认证过程中,最后的 NTLM 认证数据报文包含一个目标应用服务器的证书摘要,这个摘要使用客户端的 NTLM 值进行签名保护,可以防止伪造证书的攻击。

1.6 关于 NTLM 协议的一些总结

NT Hash = md4(unicode(hex(password)))

NTLMv2 Hash = HMAC-MD5(unicode(hex(upper(username+domain))), NT Hash)

NTProofStr = HMAC-MD5(challenge + 数据, NTLMv2 Hash)

Session Key = HMAC_MD5(HMAC_MD5(NTLMv2 Response + Challenge, NTLMv2 Hash), NTLMv2 Hash)

MIC = HMAC_MD5(NEGOTIATE_MESSAGE + CHALLENGE_MESSAGE + AUTHENTICATE_MESSAGE, Session key)

2 CVE-2015-0005

2.1 原理

应用服务器在收到用户客户端的认证信息后,由于本身没有存储用户的口令信息,所以必须依赖域服务器进行认证,将收到的认证信息发送给域服务器,这个过程基于 NETLOGON 协议。该协议在应用服务器和域服务器之间建立一个安全会话,安全会话共享密钥基于应用服务器主机账号的口令 NTLM 生成。

2.1.1 NETLOGON 步骤

均为 RPC 远程向认证服务器调用

  1. NetrLogonSamLoginEx
  2. NetrLogonSamLogonWithFlags
  3. NetrLogonSamLogon
  4. NetrLogonSamLogoff

2.1.2 攻击场景

win10x64en$ 上的用户 eviluser ,访问内服务器 win2008R2$SMB 服务,采用 NTLM 认证方式,域服务器为 Win2016-dc01$ ,认证过程概括如下:

  1. win10x64en$ 首先向 win2008R2$ 的 SMB 445 端口发起一个连接 NTLM_NEGOTIATE,协商使用 NTLM 认证方式;
  2. win2008R2$ 收到后,发送 NTLM CHALLENGE 返回给 win10x64en$
  3. win10x64en$ 收到 NTLM CHALLENGE 后,向 win2008R2$ 发送一个 NTLM 认证报文;
  4. Win2008R2$ 和域控服务器之间共享了 Win2008R2$ 的口令 NTLM,以此生成会话密钥,创建一个 NETLOGON 安全会话。Win2008R2$ 通过 RPC 调用域服务器的 NetrLogonSamLogonWithFlags 函数,并将 win10x64en$ 发送过来的认证信息加上此前的挑战信息全部填装进入作为参数;
  5. 域服务器收到信息后,验证认证信息,如果认证合法则返回 STATUS_SUCCESS
  6. 如果 NetrLogonSamLogonWithFlags 调用成功,则应用服务器会返回 NETLOGON_VALIDATION 数据结构,该结构的结尾可能是以下结构中的一种: NETLOGON_VALIDATIN_SA_FONETLOGON_VALIDATION_SAM_INFO2NETLOGON_VALIDATION_SAM_INFO4。在这个结构中有一个重要的数据,就是 SessionKey ,用于用户客户端和应用服务器之间的签名、加密等;

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207151317.png-water_print

  1. SessionKey 基于客户端用户的口令 NTLM 生成,应用服务器从 DC 获取,客户端用户自己采用相同的算法生成,因此应用服务器和客户端不需要交互 SessionKey;

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207151646.png-water_print

  1. 第二个参数为主机名(微软的解释 「Computer Name: The Unicode string that contains the NetBIOS name of the client computer calling this method」),主机名为调用该函数的客户端主机名,也就是应用服务器通过 RPC 远程调用的该函数,因此该主机名理论上应该与应用服务器和域服务器之间安全会话密钥的主机账号应该一致。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200207152025.png-water_print

所以任何一台域内主机,只要能拿到此前用户和应用服务器的认证信息,就可以向域服务器发起 NETLOGON,从而获取 SessionKey,这样后面可以伪造应用服务器和客户端用户之间的数据签名,满足中间人攻击。

2.2 实战

利用 impacket 中的 smbrelayx 进行中间人攻击,如果目标机器强制使用 SMB 签名,该模块会使用 NETLOGON 直接获取签名用的 sessionKey

环境:

攻击机(非域内主机):192.168.68.24

客户端服务器(被中间人攻击的服务器): SERVER-2008

目标主机、应用服务器: Windows Server 2012 - 172.16.147.130

信息
如果是非域主机,需要指定当前域内任意一台主机的 hash,且指定域控的 IP。
1
python2 smbrelayx.py -h 172.16.147.130 -machine-account pentest-ad/SERVER-2008$ -machine-hashes bab7079288e58b875c46601f274001e6:bab7079288e58b875c46601f274001e6 -domain 172.16.147.130

可以使用 -e 参数指定目标机器要执行的文件,不指定的话,默认 dump 下目标机器的 Hash,-c 可以指定要执行的命令。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509154315.png-water_print

2.3 防御

影响 Windows Server 2012 及以下,对个人 PC 无影响

微软发布了补丁 MS15-027,针对这个漏洞进行了修补,对 ComputerNameNetBIOS 这 2 个字段进行了校验,并且对这个消息认证块进行了签名校验

3 CVE-2019-1019

在 CVE-2015-0005 漏洞被修补后,域服务器会校验 ComputerName 和 NetBIOS 这 2 个字段是否一致。但是如果 ComputerName 字段缺失,则域服务器会接受,而且不会对认证消息进行完整性校验(MIC) 。

3.1 原理

由于 NTLM_AUTHENTICATION 报文中的很多信息,包括 ComputerName 字段信息,是从 NTLM-CHALLENGE 中拷贝获取,因此在攻击者可以截获由应用服务器发送给客户端的挑战信息,并将 ComputerName 字段进行删除,客户端收到挑战信息后,由于找不到 ComputerName 字段,会导致随后的 NTLM_AUTHENTICATION 也不包含该字段。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200208103534.png-water_print

通过配置,可以让 NTLM 启用完整性校验,即在认证消息中添加一个字段 MIC(Message Integrity Code),在新版本中这是默认开启的功能。MIC 是用来保护 NTLM 认证报文的完整性,即 NTLM_CHALLENGE

MIC 通过基于 SessionKey 会话秘钥的 HMAC_MD5 算法实现完整性保护,而此前的分析中,我们有能力方法获取这个 SessionKey,因此修改后重新计算 MIC 即可。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200208103900.png-water_print

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200208104134.png-water_print

  1. 客户端发起到应用服务器的 NTLM_NEGOTIATE,被重放攻击者捕获

  2. 攻击者将 NTLM_NEGOTIATE 转发给真正的应用服务器,也即我们的攻击目标

  3. 应用服务器返回一个 NTLM_CHALLENGE 给攻击者

  4. 重放攻击者将 NTLM_CHALLENGE 中的 ComputerName 字段去掉,然后转发给客户端

  5. 客户端收到修改后的 NTLM_CHALLENGE ,基于这些信息构造 NTLM_AUTHENTICATE ,将认证信息发送给重放攻击者,此时认证消息已经包含 MIC

  6. 重放攻击者向域服务器发起一个 NETLOGON 会话请求,由于认证消息中 ComputerName 字段缺失,域服务器不进行完整性校验,认可该认证消息,并返回一个 Sessionkey

  7. 重放攻击者重新计算 MIC ,并将新的 NTLM_AUTHENTICATE 发送给应用服务器

  8. 应用服务器收到 NTLM_AUTHENTICATE 后,校验 MIC,然后向域服务器发起 NETLOGON 会话请求,域服务器返回认证成功的响应,其中包含会话密钥,这个会话密钥和第 6 步中的会话密钥相同

  9. 重放攻击者成功地与应用服务器建立了一个带签名的会话,获取了客户端用户在应用服务器上的访问权限,如果客户端用户是管理员,而应用服务器是域服务器,则重放攻击者具备了在域服务器(应用服务器)上的管理员权限(客户端)。

3.2 实战

利用 impacket 中的 ntlmrelayx.py 进行中间人攻击,使用 -remove-target 参数。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509095846.png-water_print

1
python3 ntlmrelayx.py -h 172.16.147.130 -remove-target --enum-local-admins -smb2support -machine-account pentest-ad/SERVER-2008$ -machine-hashes bab7079288e58b875c46601f274001e6:bab7079288e58b875c46601f274001e6 -domain 172.16.147.130

4 CVE-2019-1040

4.1 原理

在安装了 CVE-2015-0005 的补丁后,系统会校验 NetBIOS 的名称和 NetrLogonSamLogonWithFlags 函数的 ComputeName 参数是否相同。因此,此前通过修改 ComputerName 来获取 SessionKey 的方法失效。

但是如果认证信息中的 NetBIOS 被删除或者消失后,认证服务器不会再进行前面的名字校验,也就是说我们再修改 ComputerName 参数,能达成 CVE-2015-0005 漏洞的效果,从而获取会话密钥。

针对这种情况,可以通过配置“服务器拒绝任何没有 NetBIOS 的请求”来阻止此类攻击。但是在 NTLMv1 中,NTLM 消息块结构体中,本来就没有这个字段,因此这种攻击在 NTLMv1 场景中难以通过策略或者补丁来杜绝,仍然存在很大的脆弱性。

客户端和服务器在 NTLM 协商时,通过下图中 NegotiatFlags (即 msvAvFlags 字段)来标识是否需要 MIC 来保护会话的完整性,见下图中红色框标识。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200208114101.png-water_print

SMB 客户端在 NTLM 认证时,默认设置需要 MIC 进行完整性校验保护。直观而言,一般会有几种方式对抗 MIC,一是修改 MIC,前提条件是获取会话密钥,在前面我们看到:如果配置了防护策略,通过删除 NetBIOS 不能获取会话密钥;二是直接丢弃 MIC,这时需要将 msVAvFlags 字段中的标志位同样进行修改,以及版本信息,因为有些版本默认是必须要有 MIC。

msvAvFlags 字段的定义,查看微软知识库,如果为 0x00000002 表示客户端通过 MIC 来保护数据报文的完整性

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200208114702.png-water_print

msvAVFlags 字段由用户的 NTLM 散列值进行签名保护,因此不能修改 msvAVFlag 字段。实际中非常神奇,域服务器并不真正在乎 MIC 和 Version 信息是否存在,如果存在,则校验,如果不存在则不校验。

上述的攻击方式,可以通过配置进行阻止,即如果 msvAVFlags 字段表明有 MIC 完整性校验,就必须要有 MIC 的存在,而且进行校验。但是在实际应用场景中,仍然存在一些隐患,例如 MacOSLinux 系统中的 FireFox 默认情况下,不添加 MIC。

4.2 实战

利用 impacket 中的 ntlmrelayx.py 进行中间人攻击,使用 --remove-mic 参数。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200509095534.png-water_print

1
python3 ntlmrelayx.py -h ldap://172.16.147.130 --remove-mic --escalate-user commonuser -smb2support -machine-account pentest-ad/SERVER-2008$ -machine-hashes bab7079288e58b875c46601f274001e6:bab7079288e58b875c46601f274001e6 -domain 172.16.147.130

5 EPA-Bypass

5.1 原理

EPA (Enhanced Protection for Authentication),将认证报文绑定到一个安全通道中,主要用于保护 Windows 集成认证的服务,例如OWA、ADFS、 LDAPS。

具体的做法是,在认证报文中添加一个字段 Channel Bindings,根据微软的说明,Channel Bindings 为一段 MD5 Hash 值,表示结构体 gss_channel_bindings_structMD5Hash 值。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200209104650.png-water_print

如果启用了 EPA,在客户端发送的认证报文中,会添加一个字段 NTProofStr,这是一段签名,用来保护 Channel Bindings。微软给出 NTProofStr 的计算算法如下:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200209105337.png-water_print

可以得知, NTProofStr 基于用户的 NTLM 值计算得来,因此,在此种攻击场景中不可能计算得出。可以使用 EPA 来保护 ADFSOWALDAPS 等基于 NTLM 认证的场景。比较悲剧的是,在默认情况下,上述这些服务器都没有强制使用了 EPANTProofStrChannel Bindings 在实际的报文中见下图,这是一个客户端发送的认证报文。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200209110550.png-water_print

如果我们在服务器发送挑战信息到客户端时,在挑战报文主动中添加一个 Channel Bindings 到消息块中,类似于下图所示,注意下图是服务器发送的挑战报文,由于 Channel Bindings 是一段 MD5Hash 值,是比较好添加的。

客户端收到挑战信息后,会将我们事先添加的 Channel Bindings ,并且再次计算一个新的 Channel Bindings 添加到认证报文后面,导致认证报文包含 2 个 Channel Bindings,见下图,注意这是一个客户端发送的认证报文。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200209111242.png-water_print

在这种情况下,域服务器会选择第一个 ChannelBindings 进行校验,忽略第二个 Channel Bindings,这样我们就可以规避 EPA 的保护,实现攻击目的。

如果客户端开启了MIC保护,则和前面一样,直接丢弃 MIC

参考: