返回介绍

4 认证与会话

发布于 2024-09-13 00:14:50 字数 5393 浏览 0 评论 0 收藏 0

上文阐述了 NTLM 中继的基本原理,接下来出现的问题是,在中继 NTLM 身份验证后,如何在目标服务器上执行具体地操作?

要回答这个问题,必须首先澄清一个基本的事实。当客户端向服务器进行身份验证以执行某些操作时,必须区分两件事:

  • 身份验证(Authentication),允许服务器验证客户端是它声称的身份。
  • 会话(Session),在此期间客户端将能够执行操作。

如果客户端通过了正确的身份验证,那么它将能够访问服务器提供的资源,例如网络共享、对 LDAP 目录的访问、HTTP 服务器或 SQL 数据库等等。

为了管理这两个步骤,所使用的协议必须能够封装身份验证,从而交换 NTLM 消息。

如果所有协议都集成 NTLM 技术细节,是不符合软件工程中的解耦思想的。因此,微软提供了一个接口来处理身份验证,并且专门开发了包来处理不同类型的身份验证。

4.1 SSPI & NTLNSSP

SSPI 接口(Security Support Provider Interface) 是 Microsoft 提出的用于标准化身份验证的接口,不同的协议都可以使用这个接口来处理不同类型的身份验证过程。在 NTLM 认证中,使用的是 NTLMSSP (NTLM 安全支持提供程序)。

SSPI 接口提供了几个函数,包括 AcquireCredentialsHandleInitializeSecurityContextAcceptSecurityContext 。在 NTLM 身份验证期间,客户端和服务器都会使用到这些函数。简述这些步骤:

  1. 客户端调用 AcquireCredentialsHandle 获得对用户凭据的间接访问。
  2. 客户端然后调用 InitializeSecurityContext ,该函数在第一次调用时将创建类型为 NEGOTIATE 的 type 1 消息。对于研发来说,这条消息是什么并不重要,重要的是将它发送到服务器。
  3. 服务器在收到消息时调用 AcceptSecurityContext 函数。 这个函数然后将创建类型为 Challange 的 type 2 数据。
  4. 收到此消息时,客户端将再次调用 InitializeSecurityContext ,但这次将 CHALLENGE 作为参数传递。 NTLMSSP 负责通过加密 Challenge 来计算响应的内容,并生成最后的 AUTHENTICATE 消息。
  5. 服务器收到该消息后,也会再次调用 AcceptSecurityContext ,自动进行鉴权验证。

这意味着这 5 个步骤完全独立于客户端的类型或服务器的类型。 无论使用何种协议,只要该协议具有允许这种不透明结构,以一种或另一种方式从客户端交换到服务器的内容,它们就可以工作。

因此,协议通过将 NTLMSSPKerberos 或其他身份验证结构放入特定字段,如果客户端或服务器看到该字段中有数据,它只会将其传递给 InitializeSecurityContextAcceptSecurityContext

应用层(HTTP、SMB、SQL 等)完全独立于身份验证层(NTLM、Kerberos 等)。 因此,认证层和应用层都需要安全措施。

通过 SMB 和 HTTP 的两个示例帮助读者更好地理解。其它协议也十分相似。

4.2 HTTP & NTLM

一个 HTTP 的基本请求:

GET /index.html HTTP/1.1
Host: www.geekby.site
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: zh-cn

此示例中的必需元素是 HTTP 动词 ( GET )、请求页面的路径 ( /index.html )、协议版本 ( HTTP/1.1 ) 或主机标头 ( Host: beta.hackndo.com )。

但是可以还添加其它的 HTTP 头。最好的情况是,服务器知道这些标头会存在,并且知道如何处理。最坏的情况是直接忽略。

正是 HTTP 的此项特性,能够将 NTLM 的相关信息从客户端传输到服务器。即在客户端添加 Authorization 的 HTTP 头,在服务端添加一个 WWW-Authenticate 的头。如果客户端尝试访问需要身份验证的网站,服务器将通过添加 WWW-Authenticate 标头来响应,内容包含其支持的不同身份验证机制。如对于 NTLM,返回: WWW-Authenticate: NTLM

客户端知道需要 NTLM 身份验证,将发送 Authorization 头中的第一条消息,并 base64 编码(因为该消息仅包含不可打印的字符)。 服务器将在 WWW-Authenticate 填充 Challenge ,客户端将计算响应并将其放到 Authorization 头中。如果认证成功,服务器通常会返回 200 返回码。

> GET /index.html HTTP/1.1
> Host: www.geekby.site
> User-Agent: Mozilla/5.0
> Accept: text/html
> Accept-Language: en

  < HTTP/1.1 401 Unauthorized
  < WWW-Authenticate: NTLM
  < Content type: text/html
  < Content-Length: 0

> GET /index.html HTTP/1.1
> Host: www.geekby.site
> User-Agent: Mozilla/5.0
> Accept: text/html
> Accept-Language: zh-ch
=> Authorization: NTLM <NEGOTIATE in base64>

  < HTTP/1.1 401 Unauthorized
  => WWW-Authenticate: NTLM <CHALLENGE in base64>
  < Content type: text/html
  < Content-Length: 0

> GET /index.html HTTP/1.1
> Host: www.geekby.site
> User-Agent: Mozilla/5.0
> Accept: text/html
> Accept-Language: zh-cn
=> Authorization: NTLM <RESPONSE in base64>

  < HTTP/1,200 OKAY.
  < WWW-Authenticate: NTLM
  < Content type: text/html
  < Content-Length: 0
  < Connection: close

只要 TCP 会话处于打开状态,身份验证就会有效。然而,一旦会话关闭,服务器将不再拥有客户端的安全上下文,并且必须进行新的身份验证。由于 Microsoft 的 SSO(单点登录)机制,整个过程对用户是透明的。

4.3 SMB & NTLM

再举一个 SMB 协议的例子。SMB 协议,通常用于访问网络共享。

SMB 协议通过使用命令来工作( Microsoft 定义的相关文档 ),例如,有 SMB_COM_OPENSMB_COM_CLOSESMB_COM_READ ,用于打开、关闭或读取文件的命令。

SMB 还有一个专门用于配置 SMB 会话的命令, SMB_COM_SESSION_SETUP_ANDX 。 此命令中有两个字段专用于 NTLM 认证的字段。

  • LM/LMv2 认证:OEMPassword
  • NTLM/NTLMv2 认证:UnicodePassword

下图是一个 SMB 数据包的样例,其中包含服务器对身份验证的响应。

这两个示例表明 NTLM 的内容与协议无关。它可以包含在任何支持它的协议中。

然后,将 身份验证部分应用程序会话部分 做区分。会话部分是通过客户端身份验证后使用的协议进行的交换的延续,例如通过 HTTP 浏览网站,使用 SMB 访问网络共享上的文件。

由于认证和会话过程彼此的信息是独立的,这意味着中间人很可能会通过 HTTP 接收身份验证,并将其中继到服务器但使用 SMB,称为跨协议中继。

考虑到所有这些因素,下一章节将重点介绍已经各种存在风险的点,以及用于解决这些问题所引入的安全机制。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文