Basic Brute Force Detection

Description

Uses a simple threshold for Windows Security Logs to alert if there are a large number of failed logins, and at least one successful login from the same source.


Use Case

Security Monitoring

Category

Account Compromise, Scanning

Security Impact

Discovering real credentials is a key component for any attacker. While there are many approaches for doing that, a time honored way is to find weak passwords by just trying hundreds of common passwords. Particularly as most environments use Active Directory as their central storage respository for credentials, looking for brute force activity in Windows Security logs should be a component of any security strategy.

Alert Volume

Low (?)

SPL Difficulty

Basic

Journey

Stage 1

MITRE ATT&CK Tactics

Credential Access

MITRE ATT&CK Techniques

Brute Force

MITRE Threat Groups

APT3
APT33
APT41
Dragonfly 2.0
Lazarus Group
Leafminer
OilRig
Turla

Data Sources

Windows Security
Authentication

   How to Implement

If you have followed the data onboarding guides in this app, this search will work immediately for you. You should generally specify the index where you are storing Windows Security logs (e.g., index=oswinsec), and if you use a mechanism other than the Splunk Universal Forwarder to onboard that data, you should verify the sourcetype and fields that are used. The rest is simple!

   Known False Positives

The only known scenario where this search could generate false positives is if you have a single source (for example, a web app) that centralizes the authentication for many people. In that scenario, you might need to adjust thresholds for that source, or exclude it and build a separate similar search just using the logs from that host.

   How To Respond

When this search fires, the immediate concern is that the brute force search was successful. See if it is coming from a host that typically logs in with that account to make sure it is not just coincidental, and then reset the password for any compromised accounts and look for any other places where that username was used.

   Help

Basic Brute Force Detection Help

This example leverages the Simple Search assistant. Our example dataset is a collection of anonymized Windows Authentication logs, during which someone attempts a brute force against a series of usernames. Our live search looks for Windows Authentication activity across any index in the standard sourcetype.

SPL for Basic Brute Force Detection

Demo Data

First we bring in our basic demo dataset. In this case, Windows logs. We're using a macro called Load_Sample_Log_Data to wrap around | inputlookup, just so it is cleaner for the demo data.
Bucket (aliased to bin) allows us to group events based on _time, effectively flattening the actual _time value to the same hour.
Next we use the magic of stats+eval to count how many events there are where the action is success, or the action is failure
Finally we filter for where there is at least one success, and more than 100 failures.

Live Data

First we bring in our basic dataset. In this case, Windows logs.
Next we use the magic of stats+eval to count how many events there are where the action is success, or the action is failure, by source
Finally we filter for where there is at least one success, and more than 100 failures.

Accelerated Data

First we bring in our dataset of failed authentication logs. We're using tstats here, and specifically in prestats mode. The reason for this is that we will be able to append another tstats question and then answer them both at the same time. Prestats effectively tells the indexer not to provide a nice and polished answer, but to give us a jumble of different partial results that we will be able to sort through later. Specifically, that jumble should include pairs of counts (with the field name "count(Authentication.user)") and src / dest pairs.
Next, we run the same type of query, this time looking for successful logins and using the field name count (thus differentiating the field name from the prior line). We also tell Splunk to make sure to append=t this to the earlier result set.
Now we can join these two together using stats, looking for the two specific field names we mentioned.
Now to make our query nice and readable, we rename these fields to something more sensible.
Finally we filter for where there is at least one success, and more than 100 failures.

Screenshot of Demo Data