Write a detection for an SSH brute-force
Read an auth.log, then write a threshold detection rule that flags the brute-force attacker without alerting on a user who just fat-fingered their password. Real detection engineering, graded on whether your rule actually fires correctly.
Scenario
A web server's auth.log shows someone hammering SSH. Your job: write a detection rule that
fires on the attacker, and only the attacker. A legitimate user mistyping their password twice
must not page the on-call.
The log (what you're detecting against)
Jun 8 09:58:12 web1 sshd[2001]: Accepted password for deploy from 10.0.0.5 port 41000 ssh2
Jun 8 10:00:01 web1 sshd[2100]: Failed password for invalid user admin from 203.0.113.66 ...
Jun 8 10:00:01 web1 sshd[2101]: Failed password for invalid user root from 203.0.113.66 ...
... ~18 more failures from 203.0.113.66 across many usernames, all within ~13 seconds ...
Jun 8 10:00:13 web1 sshd[2116]: Failed password for invalid user guest from 203.0.113.66 ...
Jun 8 10:03:40 web1 sshd[2300]: Failed password for alice from 10.0.0.5 port 42000 ssh2
Jun 8 10:03:55 web1 sshd[2301]: Failed password for alice from 10.0.0.5 port 42010 ssh2
Jun 8 10:04:10 web1 sshd[2302]: Accepted password for alice from 10.0.0.5 port 42020 ssh2
Jun 8 10:05:00 web1 sshd[2400]: Accepted password for bob from 10.0.0.9 port 43000 ssh2
The attacker (203.0.113.66) sprays ~20 failed logins, changing the username every time. The
legitimate user alice fails twice from 10.0.0.5, then succeeds.
Your rule
Edit detection.yml:
match: "Failed password" # only count these log lines
group_by: src_ip # aggregate by this field (src_ip or user)
threshold: 5 # alert when a group hits this count...
window_seconds: 60 # ...within this many seconds
How it's graded
We run your rule over the log and check which sources it would alert on:
- it must fire on the attacker
203.0.113.66, and - it must not fire on any legitimate user.
Two ideas decide it: what you group by (the attacker varies the username, so grouping by user hides the burst; group by source IP) and where you set the threshold (above the legitimate noise).
Teaches: threshold/aggregation detection, the core of SIEM alerting and SOC detection engineering.
What gets checked
Your solution is verified against each of these:
- The rule parses (match, group_by, threshold, window_seconds)
- The rule alerts on the brute-forcing source
- No legitimate user is alerted
Solve it in your browser
No setup, no install. Write your solution in the editor and hit Check. The in-house engine renders and grades it instantly, then issues your proof the moment every check passes.
Solve in browser →Prefer your own lab?
- Build the fix locally. New to the tooling? See setting up your lab.
- Push your topology file, device configs, and any playbooks to a public repo (GitHub or GitLab).
- Submit the repo link. We review it by hand, confirm it works, and issue your proof page.