LM-Hash && NTLM-Hash
字数 3406 2025-08-29 08:32:19
Windows 认证机制详解:LM-Hash 与 NTLM-Hash
1. LM-Hash 详解
1.1 LM-Hash 生成原理
LM-Hash (LAN Manager Hash) 是 Windows 早期使用的密码哈希算法,由 IBM 设计,存在多个安全弱点。
生成步骤:
-
密码处理:
- 密码被限制为最多14个字符
- 转换为大写形式
- 转换为16进制字符串,不足14字节用0补全
-
分割处理:
- 16进制字符串分成两个7字节部分
- 每部分转换为56位比特流,不足左边补0
- 分7bit为一组,每组末尾加0,组成新编码(str_to_key函数处理)
-
加密处理:
- 得到的8字节二组分别作为DES密钥
- 对魔术字符串"KGS!@#$%"进行DES加密
- 将两组DES加密结果拼接,得到最终LM-Hash
示例:密码"123456"的LM-Hash生成过程
- 转换为大写:"123456" → "123456"
- 转换为16进制:313233343536
- 补全14字节:3132333435360000000000000000
- 分割为两部分:
- 第一部分:31323334353600
- 第二部分:00000000000000
- 分别处理并加密后得到:44EFCE164AB921CAAAD3B435B51404EE
1.2 LM-Hash 的弱点
- 密码强制转换为大写,降低安全性
- 固定分割为两部分,独立加密
- 使用弱DES密钥和固定魔术字符串
- 最大密码长度限制为14字符
- 第二部分对于短密码总是固定值(AA...)
2. NTLM-Hash 详解
2.1 NTLM-Hash 生成原理
NTLM-Hash 是微软提出的改进算法,解决了LM-Hash的部分安全问题。
生成步骤:
- 将密码字符串转换为ASCII字符串
- ASCII字符串转换为16进制字符串
- 16进制字符串转换为Unicode字符串
- 对Unicode字符串使用MD4消息摘要算法
- 得到16字节的NTLM-Hash值
示例:密码"123456"的NTLM-Hash生成过程
- ASCII表示:49 50 51 52 53 54
- 16进制表示:31 32 33 34 35 36
- Unicode表示:310032003300340035003600
- MD4哈希:32ed87bdb5fdc5e9cba88547376818d4
2.2 NTLM-Hash 的优势
- 保留密码大小写敏感性
- 不使用固定分割和魔术字符串
- 使用更强的MD4算法
- 支持更长密码(最多256字符)
- 生成单一块哈希,而非两部分拼接
3. 挑战/响应认证协议
3.1 LM 挑战/响应流程
- Server → Client: 发送8字节挑战
- Client:
- 计算密码的LM-Hash
- 在LM-Hash后补5个0x00变为21字节
- 分割为三组7字节
- 每组7字节转换为DES密钥(8字节)
- 用三组DES密钥分别加密挑战
- 拼接三个8字节密文得到24字节响应
- Client → Server: 发送24字节响应
- Server: 用相同方法计算并验证响应
3.2 NTLM 响应计算
- 计算密码的NTLM-Hash
- 补全为21字节(加5个0x00)
- 分割为三组7字节
- 每组转换为DES密钥
- 用三组DES密钥分别加密挑战
- 拼接三个8字节密文得到24字节NTLM响应
示例:密码"SecREt01",挑战"0x0123456789abcdef"
- NTLM-Hash: cd06ca7c7e10c99b1d33b7485a2ed808
- 补全21字节: cd06ca7c7e10c99b1d33b7485a2ed8080000000000
- 分割三组:
- cd06ca7c7e10c9
- 9b1d33b7485a2e
- d8080000000000
- 加密挑战得到:
- 25a98c1c31e81847
- 466b29b2df4680f3
- 9958fb8c213a9cc6
- 最终NTLM响应: 25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6
3.3 NTLMv2 响应计算
- 计算NTLM-Hash
- 计算NTLMv2-Hash:
- 用户名转大写与目标(domain/server)拼接
- 计算拼接字符串的Unicode表示
- 用NTLM-Hash作为HMAC-MD5的密钥计算哈希
- 构建"blob"数据块(包含时间戳等)
- 计算响应:
- 将挑战与blob连接
- 用NTLMv2-Hash作为HMAC-MD5密钥计算哈希
- 将此哈希与blob拼接形成NTLMv2响应
示例:用户名"testapp",密码"123456789",domain"DESKTOP-DVIA6R3"
- NTLM-Hash: C22B315C040AE6E0EFEE3518D830362B
- NTLMv2-Hash:
- 拼接字符串: "TESTAPPDESKTOP-DVIA6R3"
- Unicode: 54004500530054004100500050004400450053004B0054004F0050002D004400560049004100360052003300
- HMAC-MD5结果: a92765662d236c31c620d365c89540d1
- 构建blob并计算最终响应
4. NTLM 消息流程
NTLM验证包含三种消息类型:
4.1 类型1 - 协商消息
从客户端发送到服务器,包含:
- 客户端支持的功能列表
- 服务器请求的功能列表
4.2 类型2 - 质询消息
从服务器发送到客户端,包含:
- 服务器支持的功能列表
- 服务器生成的挑战(8字节随机数)
- 可选的目标信息
4.3 类型3 - 身份验证消息
从客户端发送到服务器,包含:
- 客户端域和用户名
- 对挑战的响应(LM/NTLM/NTLMv2)
- 客户端工作站名称
5. 实际应用与安全
5.1 Hashcat 破解示例
使用Hashcat破解NTLMv2响应的命令:
hashcat64.exe -m 5600 testapp::DESKTOP-DVIA6R3:4e783a49fe733dce:03b4e9129fbe586e457d55412b39f324:010100... pwd.txt -o found.txt --force
5.2 安全建议
- 禁用LM-Hash(在组策略中设置)
- 强制使用NTLMv2
- 使用长复杂密码
- 考虑使用Kerberos替代NTLM
- 在网络层面限制NTLM流量
6. 实现代码示例
6.1 Python LM-Hash 计算
import base64
import binascii
from pyDes import *
def DesEncrypt(str, Des_Key):
k = des(Des_Key, ECB, pad=None)
EncryptStr = k.encrypt(str)
return binascii.b2a_hex(EncryptStr)
def Zero_padding(str):
b = []
l = len(str)
num = 0
for n in range(l):
if (num < 8) and n % 7 == 0:
b.append(str[n:n+7] + '0')
num = num + 1
return ''.join(b)
if __name__ == "__main__":
test_str = "123456"
# 转换为大写和16进制
test_str = test_str.upper().encode('hex')
# 补全14字节
str_len = len(test_str)
if str_len < 28:
test_str = test_str.ljust(28, '0')
# 分割两部分
t_1 = test_str[0:len(test_str)/2]
t_2 = test_str[len(test_str)/2:]
# 转换为比特流并处理
t_1 = bin(int(t_1, 16)).lstrip('0b').rjust(56, '0')
t_2 = bin(int(t_2, 16)).lstrip('0b').rjust(56, '0')
t_1 = Zero_padding(t_1)
t_2 = Zero_padding(t_2)
t_1 = hex(int(t_1, 2))[2:].rstrip('L')
t_2 = hex(int(t_2, 2))[2:].rstrip('L')
if '0' == t_2:
t_2 = "0000000000000000"
t_1 = binascii.a2b_hex(t_1)
t_2 = binascii.a2b_hex(t_2)
# DES加密
LM_1 = DesEncrypt("KGS!@#$%", t_1)
LM_2 = DesEncrypt("KGS!@#$%", t_2)
# 拼接结果
LM = LM_1 + LM_2
print LM
7. 总结对比
| 特性 | LM-Hash | NTLM-Hash | NTLMv2 |
|---|---|---|---|
| 算法 | DES(两次) | MD4 | HMAC-MD5 |
| 密码处理 | 转大写,分割两部分 | 保留大小写 | 保留大小写,加入用户名/目标 |
| 最大长度 | 14字符 | 256字符 | 256字符 |
| 安全性 | 非常弱 | 较弱 | 较强 |
| 响应类型 | LM响应 | NTLM响应 | NTLMv2响应 |
| 兼容性 | 最广泛 | NT系统以上 | NT SP4以上 |
现代Windows系统应禁用LM-Hash,优先使用NTLMv2或更安全的Kerberos认证协议。