一、漏洞概述
二、漏洞浅析
2.1 Netlogon
Netlogon是一个远程过程调用(RPC)接口,在域环境中对域用户和计算机进行身份验证,其有诸多功能,例如维护域成员与域控制器(DC)之间的关系;维护跨域的多域控制器之间的关系以及复制域控制器数据库,具体通信过程如下:
1、客户端向NetLogon服务器发送八个随机字节(Client Challenge)
2、服务端用自己的八个随机字节(Server Challenge)作为回复
3、双方将两个随机字符串合在一起使用用户的hash(secret),生成一个一次性的加密密钥,称为SessionKey
4、客户端使用Session Key作为密钥生成客户端凭证,并发送给服务端进行验证
5、服务端同样使用Session Key作为密钥生成服务端凭证,回复给客户端进行验证
6、在双方正常通信,客户端可以进行远程过程调用(PRC),通信过程使用Session Key进行签名封装
2.2 原理概述
漏洞发生在前面所描述的NetLogon认证的Client credential加密阶段,8字节的Client credential使用的是AES-CFB的加密模式计算生成,安全地使用AES-CFB需要将初始向量IV设置为随机,但微软将其设置了全0,此时虽然Session Key依然是个随机数,但当输入的8字节明文(Client Challenge)也全为0时,由于AES-CFB的强随机特性会导致每一字节结果为0的概率都是1/2,最终结果全部为0的概率就是1/256,所以只要不断将client challenge和client credertial设置为全0就有1/256的概率通过认证
Client credential的加密方式是AES-CFB,AES-CFB对明文的每个字节进行加密
首先由16个字节的初始化向量(IV)作为输入进行AES运算得到一个输出,取输出的第一个字节,与明文的第一个字节进行异或,得到第一个字节的密文
而后,由后15个字节的IV加1个字节的密文作为输入进行AES运算得到一个输出,取输出的第一个字节与明文的第二个字节进行异或,得到第二个字节的密文,以此类推,可得到8个字节的密文作为Client credential
正常AES-CBF算法运算过程
Netlogon认证漏洞中的AES-CBF算法运算过程
黄色部分为16字节的初始化向量IV,理论上为了保证AES算法的可靠性,该部分内容应该随机生成,而微软却错误的将其全部设置为00;蓝色部分为明文,对应client challenge,该部分内容攻击者可控,设置为全00,那么在某个特殊时刻(1/256的概率)就会像上面一样,使得明文密文全为0
而Netlogon允许计算机对域控制器进行身份验证并更新他们在Active Ddirectory中的密码,于是攻击者可以冒充任何计算机到域控制器并更改其密码,包括域控制器本身的密码
三、漏洞复现
3.1 实验环境
域:woniuxy.com
DC:Windows2008 R2
攻击机:kali
漏洞检测工具:zerologon_tester.py(https://github.com/SecuraBV/CVE-2020-1472)
漏洞利用和密码还原工具:set_empty_pw.py(https://github.com/risksense/zerologon)
3.2 实验过程
在Kali中使用zerologon_tester.py进行漏洞检测:
python3 zerologon_tester.py dcadmin 192.168.112.100
执行成功之后,出现success那一串话,说明目标主机存在这个漏洞
然后EXP将域控的机器密码设置为空进行利用,但可能导致脱域影响到目标使用,因此实战环境下慎用
python3 set_empty_pw.py dcadmin 192.168.112.100
然后可以使用impacket中的secretsdump.py,获取域控上所有的Hash,获取Hash后就可以进行PTH了
python3 secretsdump.py '域名/域控机器名$@域控IP' -no-pass
python3 secretsdump.py 'woniuxy/DCADMIN$@192.168.112.100' -no-pass
用impacket的wmiexec.py进行利用,这里使用administrator(域管理员)的ntlm hash登录
接下来该干嘛呢
能做的有很多
先创建一个账户,再整一个定时任务,然后将木马上线一波,然后再把黄金票据和白银票据弄出来
由于这个修改域控密码只是修改了内存中的密码,所以可以从SAM文件中恢复原来的密码,远控目标机器后通过reg导出SAM和SYSTEM文件,下载到kali
下载到本地后使用impacket中的secretsdump.py来加载,获取DC机器账户密钥(HEX)
使用密钥还原工具进行还原
再次使用secretsdump.py脚本,指定DCADMIN$的密码为空进行加载,发现认证失败说明还原成功