1. 本地密码认证
windows并不保存明文密码,只保存密码的Hash。本地密码认证时,操作系统会使用用户输入的密码作为凭证去与系统中的密码进行验证
,路径为%SystemRoot%\system32\config\sam
。
过程:winlogon.exe -> 接收用户输入 -> lsass.exe -> (认证)
在用户注销、重启、锁屏后,操作系统会让winlogon显示登录界面,待输入过后将密码交给lsass.exe,这个进程的内存中会存一份明文密码,将明文密码加密成NTLM Hash,对SAM数据库比较认证。 mimikatz就是通过抓去lsass.exe的内存获取本地的明文密码的。
1.1 LM Hash
在Windows xp、visa、Server 03 等早期Window系统,使用的是LM Hash(LAN
Manager
Hash),由于其使用了DES加密并且对固定的字符串KGS!@#$%
进行加密,容易遭受攻击,目前已被弃用。

具体的LM Hash的计算算法如下
- 将用户口令明文转换为大写,并转换为OEM编码 (ASCII等于其本身);
- 口令补零或截断到14位,并且分作前后2个部分,各7字节 (口令大于14在win xp上默认不存储LM Hash,但是在NTLM认证时LM Hash是会按口令截断到14位计算);
- 对7字节字符串的每7个比特后面添加1比特0,变成64比特的DES密钥;
- 将上面的2个Key,使用DES算法,分别加密固定字符串
KGS!@#$%
,得到2个8字节的密文; - 2个8字节的密文连成1个16字节的密文,称为LM Hash。
= DES(DOSCHARSET(UPPERCASE(password)), "KGS!@#$%")
LMHash1 = DES(DOSCHARSET(UPPERCASE(password)), "KGS!@#$%")
LMHash2 = LMHash1 + LMHash2 LMHash
注:Win server 2008开始禁用LM Hash
1.2 NT Hash(AKA. NTLM Hash)
目前Windows系统使用的是NT Hash,有些资料也称为NTLM Hash。
= MD4(UTF-16-LE(password))
NT Hash = LM Hash + NT Hash NTLM Hash
mimikatz提取的hash为NTLM Hash = LM Hash + NT Hash
由于目前Windows系统已经禁用了LM Hash,所以一般获取到的LM Hash是一个空密码的Hash,对我们没有利用价值也没有影响。
2. 网络环境下的密码认证——Net-NTLM
Net-NTLM (New Technology LAN
Manager)是telnet
一种验证身份方式
,目的是为了避免使用明文的密码进行认证传输,
旨在为用户提供身份验证,完整性和机密性。 其包括三个版本NTLMv1, NTLMv2 ,
NTLM2 Session 。
Net-NTLM认证采用质询/应答(Challenge/Response)的消息交换模式,流程如下:
- 客户端向服务器发送一个请求,请求中包含明文的登录用户名。服务器会提前存储登录用户名和对应的密码hash;
- 服务器接收到请求后,生成一个随机数(这个随机数被称为Challenge),明文发送回客户端,然后使用存储的登录用户密码hash加密Challenge,获得Challenge1;
- 客户端接收到Challenge后,使用登录用户的密码hash对Challenge加密,获得Challenge2(这个结果被称为response),将response发送给服务器;
- 服务器接收客户端加密后的response,比较Challenge1和Challenge2,如果相同,验证成功。
2.1 Net-NTLMv1
= 8-byte server challenge, random
C = NTLM-Hash + "\x00"*5 # 21 Bytes
K1 , K2 , K3 = K1 + "\x00"
K1 = K2 + "\x00"
K2 = K3 + "\x00"
K3 = DES(K1,C) + DES(K2,C) + DES(K3,C) # 24 Bytes response
2.1 Net-NTLMv2
Net-NTLMv2是Net-NTLMv1的增强版,询问流程相同,其不同之处在于:
- NTLM v1的Challenge有8位,NTLM v2的Challenge为16位。
- NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5
= 8-byte server challenge, random
SC = 8-byte client challenge, random
CC = (Blob_signature, Timestamp, ClientNonce, Domain name, etc)
Blob -Hash = HMAC-MD5(NT-Hash, to_hex_str(user_name+domain name)) # NT-Hash as key
v2= HMAC-MD5(v2-Hash, SC+CC) # v2-Hash as key
LMv2 = HMAC-MD5(v2-Hash, SC+Blob) # v2-Hash as key
NTv2 = LMv2 + CC
response1 = NTv2 + Blob
response2 # HMAC_MD5 is a alia of NTv2 in hashcat
# so we can define response2 as blow:
# response2 = HMAC_MD5 + Blob
其中LMv2
在实际抓包中均为全0
,Blob的结构如图:

Hashcat接收的Net-NTLM v2 Hash结构如下:
username::domain:challenge:HMAC-MD5:blob
其中HMAC-MD5
就是上面的NTv2 = HMAC-MD5(v2-Hash, SC+Blob)
,也是抓包得到的数据包中的NTProofStr
:

3. 再来说说Pass The Hash攻击
可以看到无论是本地密码认证还是网络环境下的密码认证,基本的凭证都是NTLM Hash,这也是Pth攻击能够成功的原因。
我们使用mimikatz、gethashs.exe等工具获取到本地的NT Hash之后,就可以尝试进行远程登录了:
可以碰撞相同密码的远程主机,再在远程主机上继续dumphash,获得更多账户的hash,鸡生蛋蛋又生鸡,然后在战利品里面寻找具有域管理员登陆过的机器;
利用当前账号的权限进行远程操作,扩大战果。如powershell、psexec、wmic、schtasks、at等等。
需要注意的是,SMB协议可以通过NTLM协议来完成认证,也可以通过Kerberos协议完成。
Kerberos协议比较复杂,可以再开一篇文章在单独谈谈,目前我们只需要知道这两种协议都可以利用NTLM Hash来进行认证SMB服务即可。
当然, Kerberos已经是域环境下的默认安全认证协议了,当客户端提供Server的SPN(service principal name)访问时,会使用 Kerberos协议进行认证;而以IP地址访问服务端时,将使用NTLM协议进行身份认证。
# Kerberos
psexec domain.com/administrator@domain.com -hash <NTLM Hash> -c <Command>
# NTLM
psexec administrator@10.200.1.1 -hash <NTLM Hash> -c <Command>
此时无论那种方式,最根本的凭证都是NTLM Hash,即Pass The Hash攻击仍然是奏效的。
参考文章
https://payloads.online/archivers/2018-11-30/1
[http://d1iv3.me/2018/12/08/LM-Hash%E3%80%81NTLM-Hash%E3%80%81Net-NTLMv1%E3%80%81Net-NTLMv2%E8%AF%A6%E8%A7%A3http://d1iv3.me/2018/12/08/LM-Hash、NTLM-Hash、Net-NTLMv1、Net-NTLMv2详解)