《域环境渗透》03. Windows 认证 & 相关协议

本系列侧重方法论,各工具只是实现目标的载体。
命令与工具只做简单介绍,其使用另见《软件工具录》。

本专栏文章侧重于对 Windows 工作组与域环境的渗透攻击手法。

1:Windows 认证方式

关于 Windows 的认证方式,分为本地认证和网络认证。

  • 本地认证:用户的账户密码存储在本机电脑中,无论电脑是否联网,都可输入正确的账户密码进行登录
  • 网络认证:当进行网络通信和资源访问时,需要通过网络进行用户身份验证

Windows 操作系统中,用户的密码 Hash 一般有两种:LM-Hash 和 NTLM-Hash。

  • LM-Hash:LAN Manager Hash,基于 DES 对称加密
  • NTLM-Hash:NT LAN Manager Hash,基于 MD4 散列摘要算法

Windows Vista 和 Windows 2008 版本后默认禁用 LM-Hash。
Windows Vista 和 Windows 2003 版本后默认采用 NTLM-Hash。
若 LM-Hash 值为 aad3b435b51404eead3b435b51404ee,则表示为空值或被禁用。

因为 LM-Hash/NTLM-Hash 表述比较复杂,所以后面文章使用 “ 用户密码 Hash ” 来表述。

2:本地认证

本地认证:用户的账户密码存储在本机电脑中,无论电脑是否联网,都可输入正确的账户密码进行登录。

认证流程

  1. 由 winlogon.exe 进程接受用户输入的账号密码
  2. 调用 lsass.exe 进程对用户输入的密码进行加密转换为 LM-Hash/NTLM-Hash
  3. lsass.exe 进程将由密码转换成的结果与 SAM 文件中存储的 LM-Hash/NTLM-Hash 进行比较
    • 如果相同,则将 groupsid 和 usersid 发送给 winlogon.exe 准备登录
    • 如果不同则登录失败

Alt text

组件介绍

  • winlogon.exe:Windows Logon Process,即 Windows NT 用户登录程序,用于管理用户登录和退出
    • 用户注销、重启、锁屏后,操作系统会让 winlogon.exe 显示登陆界面
  • lsass.exe:Local Security Authority Service,即本地安全认证服务,用于管理本地安全策略和认证策略,负责对用户进行身份验证
    • 会将登录的明文账号密码在内存中保留一份备用
  • SAM 文件:位于 C:\windows\system32\config\ 目录,用于存储所有本地用户的凭证信息
    • 普通用户无法对其进行增加、修改、查看、复制等操作
    • 格式简要如下:Username:LM-HASH:NTLM-HASH

3:网络认证

网络认证:当进行网络通信和资源访问时,需要通过网络进行用户身份验证。

认证协议:Windows 有两种认证协议:

  • NTLM 协议:一种早期的网络认证协议,基于 Challenge/Response(挑战/响应)的方式进行身份验证
    • 工作组环境下,一般采用 NTLM 协议进行网络认证
    • 域环境中,在与旧版 Windows 系统或非 Windows 系统进行交互时也可能采用
  • Kerberos 协议:通过使用 TGT(票证授权票据)和 ST(服务票据)来进行用户验证与授权,并生成会话密钥用于加密通信
    • 在域环境中被广泛使用

3.1:NTLM 协议

3.1.1:协议简介

NTLM 协议:一种早期的网络认证协议,基于 Challenge/Response(挑战/响应)的方式进行身份验证。

  • 工作组环境下,一般采用 NTLM 协议进行网络认证
  • 域环境中,在与旧版 Windows 系统或非 Windows 系统进行交互时也可能采用

NTLM 协议版本:分为 NTLMv1 与 NTLMv2:

  • NTLMv1 使用 8 位 Challenge,基于 DES 对 Challenge 进行处理
  • NTLMv2 使用 16 位 Challenge,基于 HMAC-MD5 对 Challenge 进行处理

3.1.2:认证流程

工作组环境

  1. 协商:双方确定传输协议的版本等相关信息
  2. 质询:挑战/响应机制的核心
    1. Client 向 Server 发送用户信息请求
    2. Server 本地随机生成 Challenge,并将 Challenge 发送给 Client
    3. Client 接收到 Challenge 后,使用对应的用户密码 Hash 对 Challenge 进行加密,添加用户名、域名、机器名等相关信息生成 Response,并将 Response 发送给 Server
  3. 验证:Server 收到 Response 后,使用相同的方式加密 Challenge,并与 Response 中的信息进行对比
    • 如果相同,则返回验证成功信息
    • 否则验证失败

Alt text

域环境

  1. 协商:双方确定传输协议的版本等相关信息
  2. 质询:挑战/响应机制的核心
    1. Client 向 Server 发送用户信息请求
    2. Server 本地随机生成 Challenge,并将 Challenge 发送给 Client
    3. Client 接收到 Challenge 后,使用对应的用户密码 Hash 对 Challenge 进行加密,添加用户名、域名、机器名等相关信息生成 Response,并将 Response 发送给 Server
  3. 验证:Server 收到 Response 后,通过 Netlogon 协议将 Response 转发给 DC
    • DC 使用相同的方式加密 Challenge,并与 Response 中的信息进行对比
    • 如果相同,则返回验证成功信息
    • 否则验证失败

Alt text

3.1.3:Challenge & Response

Challenge 本质是一串随机字符。

Response 由 NTProofStr 和 blob 两部分拼接,即 Response = NTProofStr + blob

  • blob:由时间、目标信息、随机填充字符等生成
  • NTProofStr:由 Net-NTLM HashChallenge + blob 进行摘要计算生成
    • Net-NTLM Hash:由用户名等信息和用户密码 Hash 进行摘要计算生成

Net-NTLM Hash 也分为 Net-NTLMv1 Hash 和 Net-NTLMv2 Hash。
两个版本有时也简称为 NTLMv1 Hash 和 NTLMv2 Hash。

3.1.4:概念梳理

用户密码 Hash

  • 是一段 Hash 值
  • 由 Windows 用户密码进行摘要计算生成
  • 分为 LM-Hash 和 NTLM-Hash

NTLM 协议

  • 是一种认证协议,用于身份验证
  • 分为 NTLMv1 和 NTLMv2 两个版本

Net-NTLM Hash

  • 是 NTLM 协议认证中生成的一段中间数据
  • 由用户名等信息和用户密码 Hash 进行摘要计算生成
  • 分为 Net-NTLMv1 Hash 和 Net-NTLMv2 Hash

3.2:Kerberos 协议

3.2.1:协议简介

Kerberos 协议:通过使用 TGT(票证授予票据)和 ST(服务票据)来进行用户验证与授权,并生成会话密钥用于加密通信。

  • 在域环境中被广泛使用

票证授予票据(Ticket Granting Ticket,TGT)
服务票据(Service Ticket,ST)

Kerberos 通过传统的密码学技术,提供了可信的第三方认证服务,能够在以下条件下工作:

  • 认证过程不依赖于主机操作系统的认证
  • 不需要基于主机地址的信任
  • 不要求网络中所有主机的物理安全
  • 假设网络传输的数据包可能会被任意读取、修改或插入

协议角色组成

  • 客户端(Client):请求服务的一方
  • 服务端(Server):提供服务的一方
  • 密钥分发中心(Key Distribution Center,KDC):进行认证与授权的一方。根据功能又分为 AS 和 TGS
    • 认证服务器(Authentication Server,AS):用来认证客户端的身份,并发放客户端用于访问 TGS 的 TGT
    • 票据授予服务器(Ticket Granting Server,TGS):用来发放客户端访问服务端时所需的 ST

3.2.2:认证流程

  1. 验证用户身份(Client 与 AS 通信)
    1. Client 向 AS 发送请求,提供其身份信息
    2. AS 认证用户身份,并生成 TGT 响应给 Client
  2. 获取服务票据(Client 与 TGS 通信)
    1. Client 向 TGS 发起请求,提供 TGT 和希望访问的服务信息
    2. TGS 验证 TGT 的有效性,生成特定服务的 ST 响应给 Client
  3. 访问相应服务(Client 与 Server 通信)
    1. Client 向 Server 发起请求,提供 ST
    2. Server 验证 ST 的有效性,之后建立安全会话

Alt text

3.2.3:认证流程详解

3.2.3.1:Client 与 AS 通信

Client 向 AS 发送的请求数据包称为 AS-REQ(AS-Request)。
AS 向 Client 返回的响应数据包称为 AS-REP(AS-Response)。

  1. Client 向 AS 以明文的方式发起请求。请求中携带了用户名、主机 IP、当前时间戳
  2. AS 查找用户是否存在,若存在,则返回 TGT 和一段验证信息(均包含 CT_SK)
    • TGT 使用 TGS 密码加密
    • 验证信息使用 Client 用户密码 Hash 加密

Alt text

TGS 密码实际上就是 DC 上 krbtgt 用户的密码 Hash。

Client 收到 AS-REP 后,可以使用自己的用户密码 Hash 解密验证信息获取 CT_SK 和时间戳,实现了身份认证的功能(因为伪造的身份无法解密验证信息)。
Client 会根据时间戳计算 AS-REQ 与 AS-REP 时间之间的差值,以此判断 AS 是否是真实或伪造的。

3.2.3.2:Client 与 TGS 通信

Client 向 TGS 发送的请求数据包称为 TGS-REQ(TGS-Request)。
TGS 向 Client 返回的响应数据包称为 TGS-REP(TGS-Response)。

  1. Client 向 TGS 发起请求,请求中携带了以下内容
    • 使用 CT_SK 加密的用户名、主机 IP、当前时间戳
    • AS 返回的 TGT
    • 明文形式的想要访问的 Server 服务
  2. TGS 查看服务是否可被访问
  3. TGS 解密 TGT,获取 CT_SK 和时间戳,并检查时间是否超时
  4. TGS 使用 CT_SK 解密 Client 的加密信息获取用户信息,并与 TGT 中的用户信息进行对比
  5. TGS 返回 ST 和一段验证信息(均包含 CS_SK)
    • ST 使用 Server 密码 Hash 加密
    • 验证信息使用 CT_SK 加密

Alt text

Client 收到 TGS-REP 后,可以使用 CT_SK 解密验证信息获取 CS_SK 和时间戳。
Client 会根据时间戳计算 TGS-REQ 与 TGS-REP 时间之间的差值,以此判断数据是否有效。

3.2.3.3:Client 与 Server 通信

  1. Client 向 Server 发起请求,请求中携带了以下内容
    • 使用 CS_SK 加密的用户名、主机 IP、当前时间戳、ST 有效时间
    • TGS 返回的 ST
  2. Server 解密 ST,获取 CS_SK 和时间戳,并检查时间是否超时
  3. Server 使用 CS_SK 解密 Client 的加密信息获取用户信息,并与 ST 中的用户信息进行对比
  4. Server 返回一段使用 CS_SK 加密的信息,表示准备提供服务
  5. Client 使用 CS_SK 解密 Server 返回的信息,验证了 Server 身份
  6. 之后 Server 与 Client 建立安全会话,进行通信

Alt text

实际上 Server 还会使用数字证书证明自己的身份。

4:补充知识

4.1:LM-Hash 加密步骤

LM-Hash 的明文密码被限定在 14 位以内。如果版本恰当,14 位以上的用户密码会转为使用 NTLM-Hash 加密。

以密码 Admin@123 为例。

  1. 将明文口令字母转换为大写形式
1
2
3
Admin@123
->
ADMIN@123
  1. 转换为 16 进制字符串
1
2
3
ADMIN@123
->
41 44 4d 49 4e 40 31 32 33
  1. 若长度不足 14 字节,则末尾用 0 补全
1
2
3
41 44 4d 49 4e 40 31 32 33
->
41 44 4d 49 4e 40 31 32 33 00 00 00 00 00
  1. 将上述编码分成 2 组,每组 7 字节
1
2
3
4
41 44 4d 49 4e 40 31 32 33 00 00 00 00 00
->
第 1 组:41 44 4d 49 4e 40 31
第 2 组:32 33 00 00 00 00 00
  1. 将每一组分别转换为二进制,每 7 bit 一组在末尾加 0,再转换成十六进制,分别得到 2 组 8 字节的编码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
第 1 组:
41 44 4d 49 4e 40 31
->
转换为二进制
01000001 01000100 01001101 01001001 01001110 01000000 00110001
->
每 7 bit 一组
0100000
1010001
0001001
1010100
1001010
0111001
0000000
0110001
->
在末尾加 0
01000000 10100010 00010010 10101000 10010100 01110010 00000000 01100010
->
转换成十六进制
40 a2 12 a8 94 72 00 62

同理对第 2 组进行操作,最终结果:

第 1 组:40 a2 12 a8 94 72 00 62
第 2 组:32 18 c0 00 00 00 00 00
  1. 将上述步骤得到的两组 8 字节编码作为 DES 加密的密钥,分别加密魔术字符串 KGS!@#$%(16 进制为 4b47532140232425)
1
2
3
4
5
6
7
8
9
10
11
12
13
第 1 组:
40 a2 12 a8 94 72 00 62
->
明文:4b47532140232425
密钥:40a212a894720062
->
密文:
6f08d7b306b1dad4

同理,以第 2 组为密钥。最终结果:

第 1 组:6f08d7b306b1dad4
第 2 组:b75e0c8d76954a50
  1. 最终拼接得到 LM-Hash:
1
6F08D7B306B1DAD4B75E0C8D76954A50

4.2:NTLM-Hash 加密步骤

以密码 Admin@123 为例。

  1. 将明文口令转换成十六进制的格式
1
2
3
Admin@123
->
41 64 6d 69 6e 40 31 32 33
  1. 将 16 进制转换成 Unicode 格式(即在每个字节之后添加 0x00,相当于将每个字符扩展为 2 字节表示)
1
2
3
41 64 6d 69 6e 40 31 32 33
->
4100 6400 6d00 6900 6e00 4000 3100 3200 3300
  1. 使用 MD4 摘要算法对编码数据进行 Hash 散列处理得到 NTLM-Hash
1
2
3
410064006d0069006e004000310032003300
->
570a9a65db8fba761c1008a51d4c95ab

4.3:NTLM 协议流量分析

4.3.1:实验环境

采用两台工作组机器:

IP 机器
192.168.8.222 Win 7
192.168.8.155 Win 10

使用 WireShark 工具抓包。

WireShark 中,可以使用以下语句过滤两个机器间的通信过程:
(ip.src == 192.168.8.155 && ip.dst == 192.168.8.222) || (ip.src == 192.168.8.222 && ip.dst == 192.168.8.155)
以上语句可以简化为:
(ip.addr == 192.168.8.155 && ip.addr == 192.168.8.222)

4.3.2:实验步骤

  1. 打开 WireShark 进行抓包
  2. 使用 net use \\<target> /u:<username> <password> 命令进行认证,触发 NTLM 协议

Alt text

抓取认证过程中通信的数据包:

Alt text

4.3.3:数据包分析

前四个数据包,主要进行协商过程。

Alt text

第五个数据包,主要包含用户身份验证启动包和一些 Flag 协商规则。

Alt text

第六个数据包,包含了 Challenge 和一些其他信息。

Alt text

Alt text

这里 Challenge 是 16 位,说明协议版本为 NTLMv2;如果版本为 NTLMv2,Challenge 就是 8 位。

第七个数据包,主要进行 Response,还包含用户相关信息。

Alt text

Alt text

第八个数据包,返回认证结果,用来表示成功还是失败。

Alt text

4.4:Kerberos 协议流量分析

4.4.1:实验环境

采用两台域内机器:

IP 机器 主机名
10.10.10.8 Win 2008(域控) owa
10.10.10.25 Win 10(域成员) Win10-test

使用 WireShark 工具抓包;使用 kekeo 工具获取票据,触发 Kerberos 协议。

WireShark 中,可以使用以下语句过滤两个机器间的通信过程:
(ip.src == 10.10.10.8 && ip.dst == 10.10.10.25) || (ip.src == 10.10.10.25 && ip.dst == 10.10.10.8)
以上语句可以简化为:
(ip.addr == 10.10.10.8 && ip.addr == 10.10.10.25)

4.4.2:实验步骤

实验前可以使用 klist 命令查看当前内存缓存的票据,使用 klist purge 命令清空内存票据。

  1. 打开 WireShark 进行抓包
  2. 使用 kekeo,执行 tgt::ask /domain:<domain> /user:<username> /password:<password> 申请 TGT,触发 Client 与 AS 通信

Alt text

Alt text

抓取 AS-REQ 与 AS-REP 数据包:

Alt text

  1. 使用 kekeo,执行 tgs::ask /service:<service>/<server> /tgt:<TGT> 申请 ST,触发 Client 与 TGS 通信

Alt text

Alt text

抓取 TGS-REQ 与 TGS-REP 数据包:

Alt text

  1. 使用 kekeo,执行 kerberos::ptt <ticket> 将票据注入内存
  2. 使用 dir <target> 命令触发 Client 与 Server 通信

Alt text

Alt text

抓取 Client 与 Server 通信的数据包:

Alt text

4.4.3:AS-REQ & AS-REP 分析

Alt text

AS-REQ 主要包含用户的一些信息,部分信息如下:

  • PA-DATA pA-ENC-TIMESTAMP:使用用户密码 Hash 或 AES key 加密时间戳生成的 Value
  • kdc-options:一些协商字段
  • cname:发起请求的用户名
  • realm:域名
  • sname:请求的服务

Alt text

AS-REP 包含的信息:

  • ticket.enc-part:由 TGS 密码加密(即使用 krbtgt 用户的密码 Hash 加密)
  • as-rep.enc-part:由用户密码 Hash 加密的内容

Alt text

4.4.4:TGS-REQ & TGS-REP 分析

Alt text

TGS-REQ 包含的信息:

  • ticket:原始的 TGT
  • authenticator:使用 CT_SK 加密的内容
  • cname:发起请求的用户名
  • sname:请求的服务

Alt text

TGS-REP 包含的信息:

  • ticket.enc-part:由 Server 密码 Hash 加密的内容
  • tgs-rep.enc-part:由 CT_SK 加密的内容

Alt text

4.4.5:Client & Server 通信分析

Alt text

Client 与 Server 初始请求通信包含的信息:

  • ticket:原始的 ST
  • authenticator:使用 CS_SK 加密的内容

Alt text

Server 向 Client 初始响应通信,包含了一些验证信息:

Alt text

5:其他

5.1:相关工具

WireShark 官网:
https://www.wireshark.org/

kekeo 工具:
https://github.com/gentilkiwi/kekeo

5.2:参考资料

《The NTLM Authentication Protocol and Security Support Provider》:
https://davenport.sourceforge.net/ntlm.html

《Windows协议之NTLM》:
https://www.cnblogs.com/yuy0ung/articles/18223233

《NTLM协议原理分析》:
https://blog.csdn.net/qq_44159028/article/details/129396092

《Windows认证方式》:
https://songshare.cn/index.php/archives/61/

《快速入门Kerberos认证》:
https://developer.aliyun.com/article/1381205

《详解kerberos认证原理》:
https://seevae.github.io/2020/09/12/%E8%AF%A6%E8%A7%A3kerberos%E8%AE%A4%E8%AF%81%E6%B5%81%E7%A8%8B/

《域渗透学习(一)Windows认证机制》:
https://ares-x.com/2020/03/16/%E5%9F%9F%E6%B8%97%E9%80%8F%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%B8%80%EF%BC%89Windows%E8%AE%A4%E8%AF%81%E6%9C%BA%E5%88%B6/

《windows 认证(总结篇)》:
https://r0fus0d.blog.ffffffff0x.com/post/windows-authenticate/

《Wireshark使用教程(界面说明、捕获过滤器表达式、显示过滤器表达式)》:
https://www.cnblogs.com/lsdb/p/9254544.html




远书归梦两悠悠,只有空床敌素秋。

——《端居》(唐)李商隐