5 会话签名
5.1 原理
签名是一种验证真实性的方法,它确保数据在发送和接收之间没有被篡改。例如,如果用户 jdoe
发送文本 Hello World
,并对该文档进行数字签名,那么任何收到此文档并签名的人都可以验证是 jdoe
编辑它,并且可以确定这句话是他写的,因为签名保证文档没有被修改。
签名原理可以应用于信息交换。例如, SMB
、 LDAP
甚至 HTTP
协议。但是,在实践中,很少实现 HTTP 消息的签名。
但是,对包签名有什么意义呢?如前所述,会话和身份验证是两个独立的步骤,由于攻击者可以处于中间人位置并中继身份验证消息,因此它可以冒充客户端。
这就是签名发挥作用的地方。即使攻击者已设法以客户端身份向服务器进行身份验证,但无论身份验证的结果如何,由于没有用户的密钥,都无法对数据包进行签名。因此接收数据包的服务器将看到签名失效在或不存在,会拒绝攻击者的请求。
所以签名值防止 NTLM 中继攻击非常有效的措施。但是客户端和服务器如何就是否签署数据包达成一致呢?
有两件事在这里起作用:
- 一是标识是否 支持签名 。这是在 NTLM 协商期间完成的。
- 二是允许指示签名是 必需的 、 可选的 还是 禁用的 。这是在客户端和服务器级别完成的设置。
5.2 NTLM 协商过程
NTLM Negotiation 阶段使得客户端或服务器了解是否支持签名,并在 NTLM 交换期间完成。事实上,在 NTLM 消息中,除了要交换的质询和响应之外,还有 Negotiate Flags 。
当 Negotiate Sign flag 为 1 时,表明客户端支持签名。但是并不意味着签名是必要的,只是说明客户端有签名的能力。同理,服务端也是类似的。
因此,协商过程允许客户端和服务器两方中的每一方向另一方表明它是否能够对数据包进行签名。对于某些协议,即使客户端和服务器都支持签名,这并不一定意味着数据包会被签名。
5.3 实现
根据协议的不同,通常可以设置 2 个甚至 3 个选项来决定是否强制执行签名。 3 个选项是:
- Disabled :禁用签名
- Enabled :可以在需要时处理签名,但不强制签名。
- Mandatory :表明不仅支持签名,而且必须对数据包进行签名才能继续会话。
下文将以 SMB 和 LDAP 两个协议为例。
5.3.1 SMB
5.3.1.1 签名矩阵
微软的 相关文档 中提供了一个矩阵,以确定是否基于客户端和服务器端设置对 SMB 数据包进行签名。但是,对于 SMBv2 及更高版本,必须处理签名,Disabled 参数不再存在。
当客户端和服务器具有 Enabled
设置时会有所不同。 在 SMBv1
中,服务器的默认设置为 Disabled
。防止服务器在每次发送 SMB 数据包时计算签名来避免服务器过载,因此,客户端和服务器之间的所有 SMB 流量都未签名。由于 SMBv2
不再存在禁用状态,并且服务器现在默认启用,为了保持这种负载节省,在这种情况下也是不需要签名。只有客户端或服务器启用 Require 参数才对 SMB 数据包进行签名。
5.3.1.2 设置
为了更改服务器上的默认签名设置,必须在注册表项 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
中更改 EnableSecuritySignature
和 RequireSecuritySignature
项。
在域控制器上, 默认情况下,当客户端对其进行身份验证时,域控制器需要 SMB 签名。 下图为应用于域控制器的组策略配置:
另外,在上图中可以看到, Microsoft network client
选项未设置 Enable 参数。因此,当域控制器充当 SMB 服务器时,需要 SMB 签名,但如果连接来自域控制器到其它服务器,则不需要 SMB 签名。
5.3.1.3 流程
在了解 SMB 签名的配置位置之后,可以看到在 NTLM 协议通信期间应用的这个选项,它是在身份验证之前完成的。当客户端连接到 SMB 服务器时,步骤如下:
- 协商 SMB 版本和签名要求
- 验证
- 具有协商参数的 SMB 会话
上图中可以看到,来自服务器的响应表明它具有 Enable
参数,但不需要签名。
总而言之,协商 / 身份验证 / 会话的流程如下:
- 在协商阶段,双方提出要求:其中之一是否需要签名?
- 在认证阶段,双方表明他们支持什么。它们有能力签名么?
- 在会话阶段,如果能力和要求兼容,则按照协商的内容进行会话。
例如,如果 DESKTOP01
客户端要与 DC01
域控制器通信,则 DESKTOP01
表示它不需要签名,但是可以处理带签名的数据包。
DC01
表示不仅支持签名,而且需要签名:
在协商阶段,客户端和服务器将 NEGOTIATE_SIGN
标志设置为 1,表示它们都支持签名。
身份验证完成后,会话将继续,SMB 数据包将被签名。
5.3.2 LDAP
5.3.2.1 签名矩阵
对于 LDAP 协议来说,有三个等级:
- Disabled:不支持数据包签名。
- Negotiated:表示可以处理签名,如果与之通信的机器也可以处理签名的话,那么后续的数据将被签名。
- Required:表示不仅支持签名,而且必须对数据包进行签名才能继续会话。
在中间层, Negotiated Signing
与 SMBv2
的情况不同。如果客户端和服务器能够对数据包进行签名,那么它们就会签名。 而对于 SMBv2,只有在至少一个实体开启 Require
时才对数据包进行签名。
所以对于 LDAP,有一个类似于 SMBv1 的矩阵:
另外,与 SMB 不同的是,在 Active Directory 域中,所有主机都能自行配置 Negotiated Signing
。域控制器不强制签名。
5.3.2.2 设置
对于域控制器, ldapserverintegrity
注册表项位于 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters hive
中,并且可以是 0、1 或 2,具体取决于级别。默认情况下,它在域控制器上设置为 1。
对于客户端,此注册表项位于 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ldap
对于客户端,它也设置为 1。由于所有客户端和域控制器都默认配置了 Negotiated
,因此默认情况下所有 LDAP 数据包都进行签名。
5.3.2.3 流程
与 SMB 不同,LDAP 中没有指示是否对数据包进行签名的标志。但是,LDAP 使用与 NTLM 协商中相同的 flag 标志位。在客户端和服务器都支持 LDAP 签名的情况下,将设置 NEGOTIATE_SIGN
标志并对数据包进行签名。
如果一方要求签名,而另一方不支持,则会话根本不会开始。需要签名的一方将忽略未签名的数据包。
所以与 SMB 相反,如果攻击者在客户端和服务器之间,并且想使用 LDAP 将身份验证中继到服务器,需要满足两个条件:
- 服务器必须不需要数据包签名,默认情况下所有机器都是这种情况
- 客户端不得将 NEGOTIATE_SIGN 标志设置为 1。如果他这样做了,那么服务器将需要签名,并且由于我们不知道用户的密钥,就无法对伪造的 LDAP 数据包进行签名。
关于要求 2,有时客户端不设置此标志,但是,Windows SMB 客户端设置了该参数,默认情况下,无法将 SMB 身份验证中继到 LDAP。
那么为什么不直接更改 NEGOTIATE_FLAG
标志并将其设置为 0?这就是我们将在下一节中要阐述的内容。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论