Detect Kerberoating via Machine Learning & Anomaly Detection using Splunk

Identifying the odd TGT Kerberos ticket requests in your environment using Splunk’s Anomalydetection command.

Splunk introduced a few handy anomaly focused commands used in their Machine Learning Toolkit app aimed at helping analysts or data deep divers look for anomalies within their datasets. The commands useful for finding anomalies are anomalies, anomalousvalue, anomalydetection. This article is focused on the anomalydetection command.

If you’ve been following any of my other articles you’ve probably picked up on the fact that I’m a fan of anomaly detection as a way to substitute IOC detections. These types of detections are very useful when trying to find TTP rather than IOCs. Crafty and talented attackers follow the path of least resistance and usually find ways to perform actions similar to what the account they took over would. For example, taking over an IT admin allows attackers to login to other systems and not look malicious because IT admins are known to do this normally. However, through detecting and focusing on anomalies we can pick up that IT admin typically doesn’t login to that specific server or run that specific command.

Note — This type of detection can be hard to implement in environments where standardized IT governance and practices are missing.

Let’s focus on a very popular attack technique used by more advanced adversaries — Kerberoasting. To those of you not familiar with the technique I put some references down at the bottom of this article. Basically an attacker will scan an environment looking for accounts with a Service Principal Name associated with the account. The attacker will then use a tool to request the TGT ticket for that account. With the TGT they can then either impersonate the user OR crack the user’s NTLM password offline.

There are some very important parts to this attack — the most important being a TGT being requested for an account DIFFERENT than the source user’s account. This type of behavior is probably normal in your environment as service accounts and certain services will need to do this by default. However, by implementing anomaly detection we can start to see some odd/suspicious activity.

First things first — what logs do we need?

index=”*_win” sourcetype=WinEventLog:Security EventCode=4769 action=success

You’ll likely need to exclude some really common usernames/service names.

NOT Account_Name IN (“*$@*”,”~*”,”srv-*”,”svc*”,”adm*-*”) NOT Service_Name IN (”krbtgt”,”*$”) NOT src_user IN (“~*”)

We’re going to need these detections to occur over a long period of time but we want to put all these events in buckets of time so we can determine if something is outside the norm over that time period.

| bin span=1d _time as span_time

Next, we’ll do some data standardization and evaluation — but the most important thing from the below search is the where statement as its ensuring we’re only looking at requests in which the src user is NOT the same as the dest user.

| eval user = lower(mvindex(split(user,”@”),0))
| eval Service_Name = lower(mvindex(split(Service_Name,”/”),-1))
`comment(“filter instances where the user is requesting a ticket for themselves — assuming attackers are trying to steal someone else’s creds rather than the account they are already running as”)`
| eval dest_user = Service_Name
| eval src_user = user
| where !match(src_user,dest_user)
| stats count as request latest(_time) as ltime values(action) as action values(Ticket_Options) as Ticket_Options values(host) as host by src_user,dest_user,index,sourcetype,Ticket_Encryption_Type,span_time

Here’s where the magic happens…we pipe our stats to the anomalydetection command and tell the command to focus on anomalies between src_user and dest_user. Action=filter will only display the outliers.

| anomalydetection “src_user” “dest_user” action=filter | eval isOutlier = if(probable_cause != “”, “1”, “0”) | table “src_user” “dest_user”, probable_cause, isOutlier *

With that all the processing power of Splunk will go through all your TGT requests and determine if the src_user/dest_user relationship is an outlier.


Cyber Security enthusiast, detection developer and engineer, researcher, consultant.