ADCS攻擊面挖掘與利用(上) | 高級攻防02
在BlackHat21中,Specterops發布了Active Directory Certificate Services利用白皮書。盡管ADCS并不是默認安裝,但在大型企業域中通常被廣泛部署。
本文分為上下兩篇,結合實戰,講述如何在域環境中利用ADCS手法拿下域控,哪些對象ACL可用于更好的權限維持,并涉及ADCS的基礎架構、攻擊面、后利用等。
1 技術背景
1.證書服務
首先介紹一下PKI公鑰基礎結構。
在PKI(公鑰基礎結構)中,數字證書用于將公密鑰對的公鑰與其所有者的身份相關聯。為了驗證數字證書中公開的身份,所有者需要使用私鑰來響應質詢,只有他才能訪問。

Microsoft提供了一個完全集成到Windows生態系統中的公鑰基礎結構(PKI)解決方案,用于公鑰加密、身份管理、證書分發、證書撤銷和證書管理。
啟用后,會識別注冊證書的用戶,以便以后進行身份驗證或撤銷證書,即Active Directory Certificate Services (ADCS)。
再來看一下ADCS關鍵術語。
- 根證書頒發機構 (Root Certification Authority)
- 證書基于信任鏈,安裝的第一個證書頒發機構將是根CA,它是我們信任鏈中的起始。
- 從屬CA(Subordinate CA)
- 從屬CA是信任鏈中的子節點,通常比根CA低一級。
- 頒發CA(Issuing CA)
- 頒發CA屬于從屬CA,它向端點(例如用戶、服務器和客戶端)頒發證書,并非所有從屬CA都需要頒發CA。
- 獨立CA(Standalone CA)
- 通常定義是在未加入域的服務器上運行的CA。
- 企業CA(Enterprise CA)
- 通常定義是加入域并與Active Directory域服務集成的CA。
- 電子證書(Digital Certificate)
- 用戶身份的電子證明,由Certificate Authority發放(通常遵循X.509標準)。
- AIA(Authority Information Access)
- 權威信息訪問(AIA)應用于CA頒發的證書,用于指向此證書頒發者所在的位置引導檢查該證書的吊銷情況。
- CDP(CRL Distribution Point)
- 包含有關CRL位置的信息,例如URL (Web Server)或 LDAP路徑(Active Directory)。
- CRL(Certificate Revocation List)
- CRL是已被撤銷的證書列表,客戶端使用CRL來驗證提供的證書是否有效。
接下來介紹ADCS服務架構。
微軟官方ADCS服務架構中的兩層PKI環境部署結構示例如下:

ORCA1:首先使用本地管理員部署單機離線的根CA,配置AIA及CRL,導出根CA證書和CRL文件。
由于根CA需要嵌入到所有驗證證書的設備中,所以出于安全考慮,根CA通常與客戶端之間做網絡隔離或關機且不在域內,因為一旦根CA遭到管理員誤操作或黑客攻擊,需要替換所有嵌入設備中的根CA證書,成本極高。
為了驗證由根CA頒發的證書,需要使CRL驗證可用于所有端點,為此將在從屬CA(APP1)上安裝一個Web服務器來托管驗證內容。根CA機器使用頻率很低,僅當需要進行添加另一個從屬/頒發CA、更新CA或更改CRL。
APP1:用于端點注冊的從屬CA,通常完成以下關鍵配置:
將根CA證書放入Active Directory的配置容器中,這樣允許域客戶端計算機自動信任根CA證書,不需要在組策略中分發該證書。
在離線ORCA1上申請APP1的CA證書后,利用傳輸設備將根CA證書和CRL文件放入APP1的本地存儲中,使APP1對根CA證書和根CA CRL的迅速直接信任。
部署Web Server以分發證書和CRL,設置CDP及AIA。
再看一下LDAP屬性。
ADCS在LDAP容器中進行了相關屬性定義:
CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=,

Certificate templates
ADCS 的大部分利用面集中在證書模板中,存儲為:
CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC= ,
其objectClass為pKICertificateTemplate,以下為證書的字段:
- 常規設置:證書的有效期;
- 請求處理:證書的目的和導出私鑰要求;
- 加密:要使用的加密服務提供程序 (CSP) 和最小密鑰大小;
- Extensions:要包含在證書中的X509v3擴展列表;
- 主題名稱:來自請求中用戶提供的值,或來自請求證書的域主體身份;
- 發布要求:是否需要“CA證書管理員”批準才能通過證書申請;
- 安全描述符:證書模板的ACL,包括擁有注冊模板所需的擴展權限。
證書模板頒發首先需要在CA的certtmpl.msc進行模板配置,隨后在certsrv.msc進行證書模板的發布。在Extensions中證書模板對象的EKU(pKIExtendedKeyUsage)屬性包含一個數組,其內容為模板中已啟用的OID (Object Identifiers)。

這些自定義應用程序策略(EKU oid)會影響證書的用途,以下 oid的添加才可以讓證書用于Kerberos身份認證。
描述 OID Client Authentication 1.3.6.1.5.5.7.3.2 PKINIT Client Authentication 1.3.6.1.5.2.3.4 Smart Card Logon 1.3.6.1.4.1.311.20.2.2 Any Purpose 2.5.29.37.0 SubCA (no EKUs) |
Enterprise NTAuth store
NtAuthCertificates包含所有CA的證書列表,不在內的CA無法處理用戶身份驗證證書的申請。
向NTAuth發布/添加證書:certutil –dspublish –f IssuingCaFileName.cer NTAuthCA;
要查看NTAuth中的所有證書:certutil –viewstore –enterprise NTAuth;
要刪除 NTAuth中的證書:certutil –viewdelstore –enterprise NTAuth。

域內機器在注冊表中有一份緩存:
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates
當組策略開啟“自動注冊證書”,等組策略更新時才會更新本地緩存。
Certification Authorities & AIA
Certification Authorities容器對應根CA的證書存儲。當有新的頒發CA安裝時,它的證書則會自動放到AIA容器中。

來自他們容器的所有證書同樣會作為組策略處理的一部分傳播到每個網絡連通的客戶端,當同步出現問題的話,KDC認證會拋KDC_ERR_PADATA_TYPE_NOSUPP報錯。
Certificate Revocation List
前面在PKI服務架構中提到了,證書吊銷列表(CRL)是由頒發相應證書的CA發布的已吊銷證書列表,將證書與CRL進行比較是確定證書是否有效的一種方法。
CN=<CA name>,CN=<ADCS server>,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=
通常證書由序列號標識,CRL除了吊銷證書的序列號之外,還包含每個證書的吊銷原因和證書被吊銷的時間。

2. 證書注冊
先來看看證書注冊流程。
ADCS 認證體系中的證書注冊流程大致如下:

- 客戶端創建公鑰/私鑰對;
- 將公鑰與其他信息 (如證書的主題和證書模板名稱) 一起放在證書簽名請求 (CSR) 消息中,并使用私鑰簽署;
- CA首先判斷用戶是否允許進行證書申請,證書模板是否存在以及判斷請求內容是否符合證書模板;
- 通過審核后,CA生成含有客戶端公鑰的證書并使用自己的私鑰來簽署;
- 簽署完的證書可以進行查看并使用。
再來看看證書注冊方式。首先,證書頒發機構Web注冊。
在部署CA時勾選證書頒發機構Web注冊,即可在"http://CA-Computer/certsrv"身份認證后進行證書申請。

然后是客戶端GUI注冊。
域內機器可以使用certmgr.msc (用戶證書)、certlm.msc (計算機證書) 、GUI請求證書。

接下來是命令行注冊。
域內機器可以通過certreq.exe或Powershell:Get-Certificate申請證書,后面有使用示例。
最后是DCOM調用。
基于DCOM的證書注冊遵循MS-WCCE協議進行證書請求,目前大多數C#、python、Powershell的ADCS利用工具都按照 WCCE進行證書請求。
聊聊證書注冊權限。在Active Directory中權限控制是基于訪問控制模型的,其包含兩個基本部分:
- 訪問令牌,其中包含有關登錄用戶的信息;
- 安全描述符,其中包含保護安全對象的安全信息。

在ADCS中使用兩種安全性定義注冊權限 (主體可以請求證書) ,一個在證書模板AD對象上,另一個在企業CA本身上。在頒發CA機器上使用certtmpl.msc可查看所有證書模板,通過安全擴展可以對證書模板的用戶訪問權限查看。

可以在頒發CA機器上使用certsrv.msc,查看CA對于用戶的訪問權限設置。

2 證書使用
1. 證書認證
Kerberos認證:
Kerberos是域環境中主要的認證協議,其認證流程大致如下:

AS_REQ:client用client_hash、時間戳向KDC進行身份驗證;
AS_REP:KDC檢查client_hash與時間戳,如果正確則返回client由krbtgt哈希加密的TGT票據和PAC等相關信息;
TGS_REQ:client向KDC請求TGS票據,出示其TGT 票據和請求的SPN;
TGS_REP:KDC如果識別出SPN ,則將該服務賬戶的 NTLM哈希加密生成的ST票據返回給client;
AP_REQ:client使用ST請求對應服務,將PAC傳遞給服務進行檢查。服務通過PAC查看用戶的SID和用戶組等并與自身的ACL進行對比,如果不滿足則作為適當的RPC狀態代碼返回;
AP_REP:服務器驗證AP-REQ,如果驗證成功則發送 AP-REP,客戶端和服務端通過中途生成的Session key等信息通過加解密轉換驗證對方身份。
PKINIT認證:
在RFC 4556中定義了PKINIT為Kerberos的擴展協議,可通過X.509證書用來獲取Kerberos票據(TGT)。

PKINIT與Kerberos差別主要在AS階段:
PKINIT AS_REQ:發d送內容包含證書,私鑰進行簽名。KDC使用公鑰對數字簽名進行校驗,確認后返回使用證書公鑰加密的TGT并且消息是使用KDC私鑰簽名;
PKINIT AS_REP:客戶端使用KDC公鑰進行簽名校驗,隨后使用證書私鑰解密成功拿到TGT。
詳細的協議流程規范
"http://pike.lysator.liu.se/docs/ietf/rfc/45/rfc4556.xml"
NTLM憑據:
在2016年,通過證書獲取NTLM的功能就被集成在kekeo和mimikatz中,核心在于當使用證書進行PKCA擴展協議認證的時候,返回的PAC中包含了NTLM票據

即使用戶密碼改了,通過證書隨時可以拿到NTLM。獲取能用來進行Kerberos身份認證的證書需要滿足以下幾個條件。
首先是證書模板OID:
前面我們提到了,目前已知應用程序策略(oid)只有包含了Client Authentication、PKINIT Client Authentication、Smart Card Logon、Any Purpose、SubCA時,對應的證書才能充當PKINIT身份認證憑據。
然后是證書請求權限:
- 用戶擁有向CA申請證書的權限;
- 用戶擁有證書模板申請證書的權限。
2. 證書獲取
導出機器證書:
通過certlm.msc圖形化或certutil.exe進行證書導出。

當私鑰設置為不允許導出的時候,利用Mimikatz的crypto::capi命令可以patch當前進程中的capi,從而利用Crypto APIs導出含有私鑰的證書。

導出用戶證書:
通過certmgr.msc圖形化或certutil.exe進行用戶證書導出。

遇到私鑰限制同樣可嘗試crypto::capi導出證書。

本地檢索證書:
在實戰中會遇到證書、私鑰文件就在文件夾內并不需要導出的情況,其后綴文件主要有以下幾種:
后綴 描述 .pfx\ .p12\ .pkcs12 含公私鑰,通常有密碼保護 .pem 含有base64證書及私鑰,可利用openssl格式轉化 .key 只包含私鑰 .crt\ .cer 只包含證書 .csr 證書簽名請求文件,不含有公私鑰 .jks\ .keystore\ .keys 可能含有java應用程序使用的證書和私鑰 |
可結合自身需求通過開源工具或自研武器,來滿足檢索文件后綴的需求。
