作者:n1nty @ 360 A-TEAM
公众号:https://mp.weixin.qq.com/s/hACLQ4UgdFXDdlB4CKKhXg

近期,因各种相关的漏洞与攻击方案,大家又开始关注了 Credential Relay 这种攻击手法。 在我有限的认知内,我没看到过有人详细地讲解过微软为这种攻击手法而推出的防御机制,所以我整理了一下以前看过的资料,希望这是第一篇(当然讲的比较浅且这其中还有不少我没解决的问题甚至错误,欢迎交流)。

为什么写的是 "Credential Relay" 而不是 "NTLM-Relay",因为 NTLM 只是Windows 下身份认证的其中一种方法。

Credential Relay

大体可以分为两类:

  1. Credential Forwarding

    攻击者通过一定的方法使得 Client 与自己进行认证,然后将 Client 发送过来的 Credential 转发至 Server,从而使攻击者获得 Client 在 Server 上的权限。后续的利用则要看 Server 提供了哪些功能以及 Client 能在 Server 上面做什么。

  2. Credential Reflection

    攻击者通过一定的方法使得 Client 与自己进行认证,然后将 Client 发送过来的 Credential 转发回 Client 自身,从而攻击 Client(你也可以认为此时的 Client 也相当于是一台 Server)。早年出现的 SMBRelay 攻击方案就是这种方法。

在我有限的认知内,微软推出的所有的防御方案,防御的都是 Server 端。

(除非是在 NTLM 的场景下,你可以通过组策略来配置不允许 Client 发起NTLM 认证)

防御方案 1:Server 端的 Signing/Encryption

估计安全圈的各位最熟悉的例子就是 SMB Signing 功能了。

Windows 下的 SSP 除了提供身份认证功能以外,还提供会话安全功能。

比如 Client 与 Server 建立了一个 Socket 连接后,可以使用 SSP 与 Server 进行身份认证,身份认证完以后,Client 与 Server 还可以利用 SSP 提供的会话安全功能为后续的数据包进行签名与加密,以防止数据包被中间人篡改、窃听。

SSP 提供的会话安全功能,是基于 session key 的。在 Client 与 Server 端进行了身份认证以后,Client 与 Server 端都能够同时得到一个用于会话安全功能的 session key。攻击者要想知道这个 session key,就必须要知道 Client 的原始密码,而对于 Credential Relay 的攻击场景,攻击者只是站在一个中间人的位置对 Credential 进行转发,是不可能知道客户端的原始密码的。这一点我在以下这篇文章里面也说过:

360 A-TEAM 带你走进 NTLM-Relay

这里用一张图来解释一下 Signing 机制防止 Credential Relay 的方法:

如上图所示:

Attacker 在攻击一个开启了 Signing/Encryption 的服务器的时候,出现的情况就是认证会成功,但是后续的操作会失败。因为 Server 要求后续数据包是被 session key 签名、加密过的,而 Attacker 没有 Client 的原始密码无法计算出那个 session key,所以自然也就无法对攻击数据包进行签名、加密。操作失败的具体表现依 Server 的不同而不同,你有可能会看到一个报错说操作失败,也有可能看到的是服务端无响应之类的。

Server 必须要支持并且强制使用 SSPI session key 来对数据包进行签名或加密,才能够使用这种方法来防御 Credential Relay。

防御方案 2:EPA

EPA = Extended Protection for Authentication,增强的身份认证保护

这个机制是从什么时候引入的我没有严肃去考证,好像是从 Win7 以及 Windows 2008 R2 开始引入的。其他版本的操作系统可以通过安装补丁的方式来获取此机制。

看这里吧:

https://docs.microsoft.com/en-US/security-updates/SecurityAdvisories/2009/973811

EPA 机制主要引入了以下两个方案用于防止 Credential Relay

  1. Channel Binding
  2. Service Binding

在网络中传输的身份认证数据有的时候也被称为 authentication token。比如 NTLM 的三条消息以及 Kerberos 发送的 AS-REQ/AS-REQ 之类的都可以被称为 authentication token。

Channel binding 与 Service binding 这两个方案就是在原有的 authentication token 中加入一些其他的额外信息,这些额外的信息使得 Server 端可以免受 Credential Relay 的攻击。

Channel Binding

Channel Binding 方案会在原有 Windows SSPI 生成的 authentication token 中加入一段额外信息,这段额外的信息被称为 Channel Binding Token(CBT)。

Channel Binding 方案只能用于保护那些只接受 TLS 连接的 Server 端。即,它可以使 Server 端有能力知道其接收到的凭据到底是不是发给自己的(也就是有能力知道收到的凭据是不是被 Relay 过来的)。如果发现凭据不是发给自己的(也就是凭据是被 Relay 过来的),则拒收,则 Attacker 尝试与 Server 进行身份认证的请求将会失败。

用一张图演示一下 Channel Binding 防御 Credential Relay 的原理:

上图分为以下几个步骤:

  1. Attacker 通过某种方式使得 Client 与自己建立 TLS 连接,并且 Client 将 Credential(authentication token) 发送给 Attacker。authentication token 中带有 CBT。 CBT 是基于 client 到 server 的这个 TLS 连接的一些属性所计算出来的(我没有去研究具体的计算过程)。且这个 CBT 受到了完整性保护,使得攻击者无法删除、修改 CBT。具体的完整性保护的方式依认证协议的不同而不同。

  2. Attacker 与 一台开启了 Channel Binding 机制的 Server 建立 TLS 连接,将 authentication token 转发至 Server

  3. Server 接收到 authentication token 后,会基于attacker 到 server 的这个 TLS 连接的一些属性计算出来一个 CBT,同时取出 attacker 转发过来的由 client 计算出来的 CBT进行对比。

  4. 对比将会失败,因为 client 计算出来的 CBT 是基于 client --> attacker 这个 TLS 连接的一些属性,而 server 计算出来的 CBT是基于 attacker --> server 这个 TLS 连接的一些属性。 通过这个对比,Server 就会知道 attacker 转发过来的 authentication token 并不是发给自己的,所以认定这个凭据是被 relay 过来的,所以 attacker 与 server 的认证将会失败 。

Service Binding

Channel Binding 只能用于保护使用 TLS 连接的 Server。而 Service Binding 可用于保护那些使用非加密连接的 Server。

Service binding 防御 Credential Relay 的原理与 Channel Binding 基本类似,只不过是将 CBT 替换成了目标服务的 SPN。

下面用一张图来表示 Service Binding 是如何防御 Credential Relay 的:

  1. Attacker 通过某种方式触发 Client 与自己认证,Client 发送给 Attacker 的凭据中带有 Attacker 的 SPN(因为 Client 是在访问 Attacker),并且这个 SPN 受到了完整性保护(具体的完整性保护的方式依认证协议不同而不同),使得 attacker 无法删除、修改这个 SPN。(需要知道的一点是, NTLM 中也是会涉及到 SPN 的概念的)

  2. Attacker 将凭据转发至 Server

  3. Server 收到凭据后,检查凭据中的 SPN,发现 SPN 不是自己的而是 attacker 的,说明这个凭据并不是发给自己的(而是发给 attacker 的),所以认为遇到了 Credential Relay 攻击,认证将会失败。

需要注意的是,如果你的服务端程序想要受到 EPA 的保护,则要求:

  1. 运行服务端的操作系统必须支持 EPA(Win7 及 Win 2018 R2 后自动支持,或者可以通过安装补丁的方式来添加支持)

  2. 你的服务端自身需要做修改,来接入 EPA

  3. 连接服务端的客户端所在的操作系统要支持 EPA 并且客户端需要做相应修改来发送 CBT 或 SPN

即,EPA 是操作系统提供的一些基础框架,它并不会自动保护服务器上的所有程序,只有那些使用了 EPA 的程序才会受到保护。

有不少服务端程序虽然支持 EPA,但是考虑到兼容性问题(比如客户端不支持 EPA),所以没有强制开启 EPA,LDAPS 就是这么一个例子。

微软针对 CVE-2017-8563 的修复方式就是使 LDAP Server 支持 EPA,但是却没有默认强制 LDAP Server 必须要使用 EPA,所以造成了最近那些 Relay 到 LDAPS 的各种攻击手法。

防御方案 3:Type3 in Flight Checking

这是一个操作系统层面针对 NTLM-Relay 的防御方案,主要防御的是 Credential Reflection。

我没找到官方对这种防御方案的命名,所以我把它称为 'Type3 in Flight Checking'

要想受到此机制的保护,要求 Client 与 Server 必须使用 Windows SSPI 来生成与验证 NTLM 消息,而不能用其他第三方 API。

我在先前那篇 Exchange SSRF 中讲到了这个机制的原理,看这里:

Exchange CVE-2018-8581 补丁有用?没用?

除了上述的一些相对通用的 Credential Relay 防御方案以外,微软还为一些与 Relay 相关的 CVE 单独做了一些修补,我花了不少时间在网上进行搜索最后得出一个结论:

目前没人明确知道这些针对 CVE 的修补方案是怎么做的。


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/844/