漏洞白皮书:https://www.secura.com/pathtoimg.php?id=2055
1 概述
漏洞信息
漏洞名称:Netlogon特权提升漏洞
漏洞编号:CVE-2020-1472
漏洞描述:Netlogon协议认证的加密模块存在缺陷,当使用Netlogon远程协议建立与域控制器连接的易受攻击的Netlogon安全通道时,存在特权提升漏洞,导致攻击者可以在没有凭证的情况下通过认证。通过调用Netlogon中RPC函数NetrServerPasswordSet2来重置域控的密码,以域控的身份进行Dcsync(域渗透常用技术,可利用Dcsync导出域内所有用户hash,在域内维持权限等),获取域管权限。
2 实验步骤
2.1 了解Netlogon协议及其通信流程,了解漏洞原理
Netlogon组件是Windows上一项重要的功能组件,用于用户和机器在域内网络上的认证,以及复制数据库以进行域控备份,还用于维护域成员与域之间、域与域控之间、域DC与跨域DC之间的关系。
Netlogon远程协议是一个可用的在Windows域控制器上的RPC(remote procedure call protocol,远程过程调用协议,允许像调用本地服务一样调用远程服务)接口,用于对域中的用户和其他服务进行身份验证,最常见的是方便用户使用NTLM(NTLAN Manager,问询/应答身份验证协议,telnet的一种验证身份方式)登录服务器协议,让计算机更新其域内的密码。其他机器与域控的Netlogon通讯使用RPC协议MS-NRPC(指定了Netlogon远程协议,基于域的网络上的用户和计算机进行身份验证)。
Netlogon协议不会使用与其他RPC服务相同的身份验证方案,而是使用自定义的加密协议,让客户端(加入域的计算机)和服务器(域管理员)互相证明它们都知道共享的机密(客户端计算机的哈希值密码)。
Netlogon协议通信流程:
1)客户端调用NetrServerReqChallenge,向服务端发送一个client challenge;
2)服务端向客户端返回一个Server Challenge;
3)双方利用client的hash、client challenge、server challenge计算一个session_key;
4)客户端利用session_key和client challenge计算一个client credential,并发送给服务端进行校验;
5)服务端也利用session_key和client challenge计算一个client credential,如果其值和客户端发送过来的一致,就让客户端通过认证。
这里的client challenge使用ComputeNetlogonCredential函数计算,有两种算法,分别是DES_ECB和AES_CFB,双方可以通过协商flag来选择使用哪种加密方式。
攻击者可控的因素是client challenge,攻击者将其设置为0,server challenge在每一轮认证过程中都会变化,secret则对应用户密码的hash,加密过程采用的是AES-CFB8(一种高级加密标准),运算过程详见https://www.anquanke.com/post/id/217475
这里存在问题的就是AES-CFB8,在AES-CFB8算法中,IV是’\x00’*16,明文密码是client challenge,key是session_key,计算后的密文是client credential。如果IV为零,只要我们能控制明文内容为XYXYXYXY这种格式(X和Y可以一样,即每个字节的值都是一样的),那么一定存在一个key,使得clientcredential为00000000000000。我们就可以向服务端发送一个client challenge为00000000000000(满足XYXYXYXY格式即可),然后循环向服务端发送client credential为00000000000000,直到出现一个session_key,使得服务端生成的client challenge也为00000000000000。
简单来说,Netlogon协议身份认证采用挑战-响应机制,其加密算法是AES-CFB8,并且IV默认全零,导致漏洞产生。而且没有对认证次数进行限制,签名功能客户端默认可选,使得漏洞被成功利用。
2.2 Windows域环境搭建
打开服务器管理器,添加角色,一直到安装完成。
安装完成之后,在运行中输入【dcpromo.exe】进行AD域服务安装:
选择新建域
自定义域名:
设置林功能级别(根据漏洞影响版本)
勾选【DNS服务器】,在弹出的提示框中选择【是】:
文件存放路径(默认即可):
设置还原密码:
点击下一步直至安装完成。
检查Netlogon服务开启情况
2.3 漏洞复现,包括定位域控,漏洞验证和漏洞利用
靶机基本信息
定位域控:扫描389端口
389端口的服务:LDAP(LightweightDirectory Access Protocol,轻型目录访问协议)和ILS(NetMeeting Internet Locator Server,Internet定位服务器),LDAP是基于X.500标准的轻量级目录访问协议,通过IP协议提供访问控制和维护分布式信息的目录信息。由美国密西根大学发明,目前已有多家公司采用,如Netscape将其包含在最新的Communicator套装产品中,也被微软加入Active Directory中。
如果该机器同时开放135(主要用于使用RPC(remote procedure call,远程过程调用)协议并提供DCOM(分布式组件对象模型)服务)、445(共享文件夹或共享打印机)、53(DNS,域名服务器)端口,很大可能就是域控:
接下来可以通过nbtscan(从Windows网络上收集NetBIOS信息,找到PC真实的IP地址和MAC地址)、smb_version(smb扫描模块,获取系统信息,发现内网存活主机)、oxid(定位多网卡主机,无需认证获取网卡信息)、ldap来佐证。
先完成impacket安装
Impacket:一个Python类库,用于对SMB1-3或IPv4/IPv6上的TCP、UDP、ICMP、ARP、NTLM、LDAP等协议进行低级编程访问。
GitHub地址:https://github.com/SecureAuthCorp/impacket
漏洞验证:https://github.com/SecuraBV/CVE-2020-1472
漏洞复现:https://github.com/risksense/zerologon
1)查看域控所在机器账户(test1$)的hash
注:利用CVE-2020-1472重置的是域控所在机器用户的密码。机器用户跟域用户一样,都是域内的成员,机器用户在域内的用户名是机器用户+$,如test1$。
发现无法获取域内用户凭据信息
2)使用zerologon工具将域控所在机器账户的hash置换成空密码的hash
置空后,再次获取域内凭证信息:31d6cfe0d16ae931b73c59d7e0c089c0
通过在线加解密网站 https://www.cmd5.com 查询:发现是空密码
使用administrator的hash横向连接:
这样就拿到了shell
3)还原域控机器账户的hash
在上面的攻击过程中,我们将机器的密码置为空,会导致域控脱域,原因是机器用户在AD中的密码(存储在ntds.dic)与本地注册表里面的不一致。还原域控机器账户的hash,只要将AD中的密码与注册表里面的密
码保持一致即可。
获取计算机账户原始hash:
使用reg save命令将注册表里的信息拿回本地:
再通过secretdump提取出里面的hash:
使用zerologon工具将原始计算机账户哈希还原:
查看test1$账户的hash,已成功还原:密码是靶机密码。