Kerberos AD Attacks - More Roasting with AS-REP
This post continues with the series of tutorials looking at Kerberos and Active Directory attacks. If you have not had chance to review any of the previous posts in this series, I’d recommend checking them out:
- Kerberos AD Attacks - Kerberoasting
- Using machine account credentials during an engagement
- Setting Service Principal Names To Roast Accounts
In this post we will be exploring another “roasting” method which involves exploiting a weak account configuration setting in Active Directory.. AS-REP Roasting.
LAB Setup
For this tutorial, our lab will be set up to consist of the several virtual machines, which can be provisioned with the following commands:
- Windows Server 2016 - Domain Controller
- Windows Server 2016 - Attacking host
- Kali Linux - Offline bruteforcing
Windows Server 2016 - Domain Controller
# Add our static IP address for this domain controller
New-NetIPAddress -InterfaceIndex 9 -IPAddress 172.16.14.1 -PrefixLength 24
# Add the domain controller role
Install-WindowsFeature AD-Domain-Services
Install-ADDSForest -DomainName lab.local -InstallDNS
# Restart our machine
Restart-Computer
# Update our Administrator account to not require pre-auth
Get-ADuser Administrator | Set-ADAccountControl -doesnotrequirepreauth $true
Windows Server 2016 - Attacking host
# Add our static IP address for this domain controller
New-NetIPAddress -InterfaceIndex 9 -IPAddress 172.16.14.3 -PrefixLength 24
# Point our DNS resolver to the DC
Set-DnsClientServerAddress -InterfaceIndex 2 -ServerAddresses 172.16.14.1
# Add our machine to the domain
Add-Computer -DomainName lab.local
# Restart to join the domain
Restart-Computer
Kali Linux - Offline bruteforcing
# Download JTR Jumbo which supports ASREP
git clone https://github.com/magnumripper/JohnTheRipper /opt/
cd /opt/JohnTheRipper/
# Needed to build JTR
sudo apt-get install -y build-essential libssl-dev git
# Build JTR
cd src; ./configure && make
AP-REP Roasting
This is a technique I came across in a blog post from Harmj0y here, and exploits a weakness in the Kerberos protocol during initial authentication with a key distribution centre (KDC).
During the initial authentication stage, a user requests a Ticket Granting Ticket (TGT) from the KDC in the form of a AS-REQ packet. If the account exists, the KDC will return a TGT encrypted with the account’s credentials, meaning that only a valid user or machine possessing the valid credentials is able to decrypt the ticket.
This should immediately set off some alarm bells as it introduces a vulnerability very similar to our previous Kerberoasting example, in that any user who is able to make a request to the KDC can also request for any arbitrary user’s TGT. This allows an attacker to receive an encrypted ticket which can then be bruteforced offline to reveal the password.
Thankfully (or unfortunately, depending on the team you are on), this vulnerability is patched on all Active Directory deployments by default, requiring the requesting account to encrypt a timestamp with valid credentials before sending this over to the KDC. This means that only an account in possession of the password can request a TGT from the KDC.
Let’s see how this works in practice by reviewing a Wireshark capture:
As we can see the first request is for an AS-REQ, which contains the username of the account we require a TGT for. In the response we see a ERR_PREAUTH_REQUIRED
error is returned, which is the KDC rejecting the request and asking for the client to provide pre-authentication in the form of an encrypted timestamp. Following this, we see a second request issued as an AS-REQ, this time containing the encrypted timestamp. Finally the AS-REP is returned with an encrypted TGT.
Now, you may have come across this option on your travels when creating an account on a domain controller:
By default this option is disabled, however if the domain contains any accounts with this option enabled, we find that the above protection method is disabled and an attacker has the option to bruteforce credentials offline, similar to our previously explored “Kerberoasting” technique.
Let’s look at how the authentication performs when this option is enabled for an account:
This time, the TGT is provided upon request with no requirement to pre-auth. This means that any user who can communicate with the KDC has all that they need to bruteforce the credentials offline.
So how do we find accounts on the network with this option enabled? Well this option is stored within the userAccountControl
attribute in LDAP for an account:
We can therefore use the following Powershell script to identify these accounts by performing a bitwise search for 0x400000 - DONT_REQUIRE_PREAUTH
:
$strFilter = “(&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=4194304))”
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = “Subtree”
$colProplist = “name”
foreach ($I in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
$colResults | Format-Table
But how do we go about generating the correct format for John The Ripper. This is where Harmj0y’s awesome skills come into play again once again. Originally releasing support for JTR, this functionality has now been added into JTR to support AS-REP cracking with the following format:
$krb5asrep$<PRINCIPAL_NAME>:<FIRST_16_BYTES>$<REMAINING_BYTES>
Behind the scenes
As with the previous post and in-keeping with our intention to understand these attacks behind the scenes, let’s look at how we can extract this data from a Wireshark capture manually. The section we are interested in can be found within “enc-part” of a “AS-REP” packet as shown below:
Extracting the raw contents of this field, we can recreate the hash format as follows:
$krb5asrep$Administrator@lab.local:f905ba3e642c598850458561ca16b8d7$ecd777db9af336c835e4f2fc17f3e31754836ab3ce07946c211611c4ca641cef0ff4a43f3b3108cd8d9f56569665a81ad42bb536d43145829fedf8b3469ea4b9d71158fb60f789f31a4ff8c1cc2834a95711f18ebf2ae715bfa21f973600865b7158242538ecefed0cd0d306b562152cdfa362c4bb2f1877f68b999d5087a8b6310d00b4a72589b23fd16d06e7cdbf2895b2adbf2db5a8d5d17a72532b648e753cb239b26277e6ab7f11a2ae9b19c56d25c5f30c5e6c7141dabc486754514776f983e5ff7317aa07878e19289c5366aafb8e15398d0c9abb8889b3a63a9774ca6f08deba42d4
Passing this to John the Ripper will allow a dictionary or bruteforce attack to hopefully reveal credentials:
Alternatively if you have a PCAP file saved, John the Ripper Jumbo has a script which supports the extraction of AS-REP hashes from a PCAP (thanks for Dhiru Kholia for pointing this out). To use this script, simply convert your pcap to a PDML file format with:
tshark -r <pcap> -T pdml > output.pdml
Then use the “krbpa2john.py“ script provided by JTR to extract the encrypted contents needed:
OK, now we have seen how this is done manually with a packet capture, how do we apply this on a redteam engagement…. with Harmj0y’s Invoke-ASREPRoast of course :)
The Powershell cmdlet is available in a repo here, and is invoked with the following syntax:
Invoke-ASREPRoast -Domain lab.local -Server 172.16.14.1
I’ll leave you with a quick demonstration of just how easy it is to use this tool:
As always, if you have any feedback or suggestions, feel free to contact me in the usual places.