Windows的NTLM认证和hash攻击
一、Windows 的 Hash
Windows系统将用户的密码保存在安全帐户管理器(SAM,Security Accounts Manager)中,存储的是用户密码的哈希值,而不是明文密码。默认情况下,密码哈希值使用NTLM(NT LAN Manager)哈希算法,早期版本的Windows使用LM(LAN Manager)哈希,但现在几乎所有版本的Windows都使用NTLM。
- NTLM哈希:它是一个固定长度(16字节)的散列值,Windows在验证用户密码时并不会直接存储密码,而是存储密码的哈希值。当用户登录时,输入的密码经过哈希后与存储在SAM中的哈希值进行比较。
在 Windows 中,最常见的两种认证体系便是 **NTLM **认证和 **Kerberos **认证。
本机用户的密码哈希是放在 本地的 SAM 文件 里面,域内用户的密码哈希是存在域控的 NTDS.dit 文件 里面。在渗透测试中,通常可从 Windows 系统中的 SAM 文件和域控的 NTDS.dit 文件中导出所有用户的Hash。导出来的哈希经常会看到这样的格式:
1 |
|
其中的AAD3B435B51404EEAAD3B435B51404EE是LM Hash,31D6CFE0D16AE931B73C59D7E0C089C0是NTLM Hash。
1.1 LM Hash
LM Hash 的全称为 LAN Manager Hash,这是 Windows 中最早用的加密算法。
LM Hash的计算方式如下:
- 用户的密码转换为大写,密码转换为 16 进制字符串,不足 14 字节将会用 0 来在后面补全
- 密码的 16 进制字符串被分成两个 7byte 部分。每个部分转换成比特流,并且长度为 56bit,长度不足使用 0 在左边补齐长度
- 再分 7bit 为一组,每组末尾加 0,再组成一组;
- 上述不走得到的两组,分别作为 key 为“KGS!@#$%”进行 DES 加密
- 将加密后的两组拼接在一起,得到最终的 LM Hash 值;
1.2 NTLM Hash
为了解决 LM Hash 加密和身份验证方案中固有的安全弱点,Microsoft 于1993年在Windows NT 3.1中引入了NTLM协议。下面是各个版本对LM和NTLM的支持。
也就是说从Windows Vista 和 Windows Server 2008开始,默认情况下只存储 NTLM Hash,LM Hash 将不再存在。(因此后面我们将不再介绍LM Hash)如果空密码或者不储蓄 LM Hash 的话,我们抓到的LM Hash是AAD3B435B51404EEAAD3B435B51404EE。所以在 Windows 7 中我们看到抓到 LM Hash 都是AAD3B435B51404EEAAD3B435B51404EE,这里的 LM Hash 已经没有任何价值了。
NTLM Hash 的计算方法如下:
- 先将用户密码转换为十六进制格式;
- 将十六进制格式的密码进行 Unicode 编码;
- 使用 MD4 摘要算法对 Unicoe 编码数据进行 Hash 计算;
二、NTLM 身份认证
Windows 的 NTLM 认证就是利用 NTLM Hash 进行的认证,可以分为 本地认证 和 网络认证 两种方式。NTLM 的网络认证,既可用于域内的认证服务,又可用于工作组环境。NTLM 有 NTLMv1 、NTLMv2 、NTLMsession v2 三个版本,目前使用最多的是NTLMv2版本。
2.1 NTLM 本地认证
用户在 Windows 本地登录时,用户输入的密码会经过 NTLM Hash 编码后与 SAM 文件中的 NTLM Hash 进行比较。用户的密码会以 NTLM Hash 的形式存储在本地计算机的 SAM 文件中,SAM 文件路径为 %SystemRoot%\system32\config\SAM
。
当用户注销、重启、锁屏后,操作系统会让 winlogon.exe 显示登录界面(输入框)。当 winlogon.exe 接收输入后,会将密码交给lsass进程。lsass.exe 是一个系统进程,用于微软Windows系统的安全机制。它用于本地安全和登陆策略,这个进程中会存一份明文密码,将明文密码加密成 NTLM Hash,对SAM数据库比较认证。
2.2 NTLM 在工作组环境中的认证
NTLM 在网络环境中的认证采用的是一种 Challenge/Response 验证机制,由三种消息组成:
- type 1:协商
- type 2:质询
- type 3:身份验证
下面详细介绍一下 NTLM 在工作组环境中的工作机制。
- 首先,如果客户端需要访问服务器的某个服务是需要进行身份认证的。于是,客户端要输入服务器的用户名和密码进行验证,此时客户端本地会缓存一份服务器密码的 NTLM Hash 值。客户端发送 Type1 Negotiate 协商消息去协商需要认证的主体、用户(服务器端的用户名)、机器以及需要使用的安全服务等信息。
- 服务端接收到客户端发送过来的 Type1 消息后,会读取其中的内容,并从中选择出自己所能接受的服务内容、加密等级、安全服务等。然后传入 NTLM SSP,得到 Type2 Challenge 消息(被称为 Challenge 挑战消息),并将此 Type2 消息发回给客户端。这个 Type2 消息中包含了一个由服务端生成的16位随机值,此随机值被称为 Challenge,服务器也会将该 Challenge 保存起来。
- SSPI
SSPI(Security Support Provider Interface),即 安全服务提供接口,这是 Windows 定义的一套接口,该接口定义了与安全有关的功能函数,包含但不限于:
- 身份验证机制
- 信息完整性
- 为其他协议提供的会话安全机制
- SSP
SSP(Security Service Provider),即 安全服务提供,它是 SSPI 的实现者,是对 SSPI 相关功能函数的具体实现。微软自己实现了如下的 SSP,用于提供安全功能:
NTLM SSP
Kerberos
Digest SSP
Cred SSP
……
在系统层面,SSP 就是一个 dll,来实现身份验证等安全功能,实现的身份验证机制是不一样的。比如 NTLM SSP 实现的就是一种 Challenge/Response 验证机制。而 Kerberos SSP 实现的就是基于 ticket 的身份验证机制。我们可以编写自己的 SSP,然后注册到操作系统中,让操作系统支持更多的自定义的身份验证方法。
- 客户端收到服务端返回的 Type2 消息后, 会读取出服务端所支持的内容,并取出其中的随机值 Challenge,用缓存的服务器端密码的 NTLM-Hash 对其进行加密,并与用户名、Challenge 等一起组合得到 Net-NTLMHash,最后将 Net NTLM-Hash 封装到 Type 3 Authenticate 消息中(被称为 Authenticate 认证消息),发往服务端。
- 服务器在收到 Type 3 的消息之后,用自己的密码的 NTLM-Hash 对 Challenge 进行加密,并比较自己计算出的 Net NTLM-Hash 认证消息和客户端发送的认证消息是否匹配。如果匹配,则证明客户端掌握了正确的密码,认证成功,否则认证失败。
2.3 NTLM 在域环境中的认证
NTLM 在域环境中的认证的前三步与NTLM 在工作组环境中的认证是一样的,不同的地方开始出现在第四步:
- 服务器接收到客户端发送来的 Type3 消息后,取出其中的 Net NTLM-Hash 值,并向域控制器发送针对客户端的验证请求。该请求主要包含以下三方面的内容:用户名(服务器端的用户名)、原始的 Challenge 和 加密后的 Challenge(即Net NTLM-Hash)。
- 然后域控制器会根据用户名获取该帐号的密码哈希值 NTLM Hash,用哈希值对原始的 Challenge 进行加密得到 Net NTLM-Hash 。如果加密后的 Challenge 和服务器发送的一致,则意味着用户拥有正确的密码,验证通过,否则验证失败。并将验证结果发给服务器。
- 服务器根据域控制器返回的结果,对客户端进行回复。
三、 Net-NTLM Hash
Net-NTLM Hash 与 NTLM Hash 不一样。NTLM 认证的第三步中,客户端收到服务端返回的 Type2 消息后, 会读取出服务端所支持的内容,并取出其中的随机值 Challenge,用缓存的服务器端密码的 NTLM-Hash 对其进行加密,并与用户名、Challenge 等一起组合得到 Net-NTLM Hash,最后将 Net NTLM Hash 封装到 Type3 Authenticate 消息中,发往服务端。也就是说 Net-NTLM Hash 是网络环境下 NTLM 认证的散列值。NTLM v1 响应和 NTLM v2 响应对应的就是 Net-NTLM Hash 分为 Net-NTLM Hash v1 和 Net-NTLM Hash v2。
- Net-NTLM Hash v1的格式为:
1 |
|
- Net-NTLM Hash v2的格式为:
1 |
|
Net-NTLM Hash 不能像 NTLM Hash 一样被攻击者用来进行哈希传递,但是攻击者可以使用各种方法截获客户端与 Server 认证过程中的 Net-NTLM Hash,然后对其进行明文爆破,或者直接用来进行 NTLM 中继攻击。
四、 NTLM 认证的相关安全问题
NTLM 认证固然存在不少安全问题,大体有以下几种:
- 哈希传递攻击
- 利用 NTLM 进行内网信息收集
- NTLM Relay
4.1 哈希传递攻击(PTH)
哈希传递(Pass The Hash)攻击简称 PTH,该方法通过找到与账户相关的密码散列值(NTLM Hash)来进行攻击。
由于在 Windows 系统 NTLM 认证的 Type3 消息计算 Response 的时候,客户端是使用用户的 NTLM Hash 进行计算的,而不是用户密码进行计算的。因此在模拟用户登录或对访问资源的用户进行身份认证的时候,是不需要用户明文密码的,只需要用户 Hash。攻击者可以利用 NTLM Hash 直接远程登录目标主机或反弹 Shell。
在域环境中,用户登录计算机时一般使用域账号,大量计算机在安装时会使用相同的本地管理员账号和密码,因此,如果计算机的本地管理员账号和密码也相同,攻击者就能使用哈希传递攻击的方法来登录内网中的其他主机。使用该方法,攻击者不需要花费时间来对Hash进行爆破,在内网渗透里非常经典。常常适用于域环境或工作组环境。
4.2 利用 NTLM 进行内网信息收集
在NTLM认证中 Type2 消息返回 Challenge 的过程中,同时返回了操作系统类型,主机名,NetBIOS 名称等。这也就意味着如果我们在能跟服务器进行 NTLM 交流中,给服务器发送一个 Type1 的请求,服务器返回 Type2 消息的响应,这一步,我们就可以得到很多信息。
4.3 NTLM Relay
NTLM hash 分为 NTLMv1 NTLMv2 NTLM session v2 三种,NTLMv2 的强度比 NTLMv1 强了不少 ,我们在实战中,如果获得的是NTLMv1的话直接对其进行爆破就行了,而现实情况中我们遇到的是 NTLMv2,NTLMv2的密码强度高了不少,因此如果你没有一个超级强大的字典,你很难得到明文密码。那么,如果爆破行不通的话我们不妨试一下NTLM Relay攻击。
在这个NTLM Relay中,我们就是要将截获的Net-NTLM Hash重放来进行攻击,从而实现对其他机器的控制,所以严格意义上应该叫作Net-NTLM Relay。