A brute-force alert fires 400 times a day and the SOC now auto-closes it. Diagnose it and tune the rule.
You own a SIEM brute-force rule. It fires about 400 times a day and the SOC auto-closes it unread.
Constraints:
- You may not disable, mute or delete the rule.
- Password spraying must still be detectable after your change.
10.20.0.5is the corporate VPN gateway; all remote staff appear behind it.
ALERT brute_force_failed_logons count=63 window=5m src_ip=10.20.0.5
distinct_accounts=54 successful_logon_after=0
sample: user=a.petrov EventID=4625 status=BAD_PASSWORD
sample: user=m.ivanova EventID=4625 status=BAD_PASSWORD
ALERT brute_force_failed_logons count=58 window=5m src_ip=10.20.0.5
distinct_accounts=51 successful_logon_after=0
ALERT brute_force_failed_logons count=12 window=5m src_ip=10.20.0.5
distinct_accounts=1 successful_logon_after=1 user=svc_backup
Explain why the first two alerts are false positives, and rewrite the rule so it stays useful.
Failures are counted per source IP, and the VPN gateway NATs hundreds of users behind one address, so ordinary typos cross the threshold. Key the rule on account instead, and for shared egress alert on distinct accounts failing per IP — that keeps spraying visible.
- ✗Raising the threshold, which silences spraying instead of removing the noise
- ✗Blanket-excluding the gateway IP and losing all visibility behind it
- ✗Reading a shared NAT address as one attacking user
- →How would you prove the tuned rule still catches a slow spraying campaign?
- →What context would you enrich the alert with to speed up triage?
The first two alerts are false positives. The tell is the shape, not the volume: 54 distinct accounts, zero successful logons afterwards, and a steady repeat every five minutes. That is the profile of shared egress — hundreds of staff sit behind 10.20.0.5, and their everyday typos land in one counter. The third alert looks genuine: a single account svc_backup with a success following the failures.
Raising the threshold is the wrong fix — that is exactly how you blind yourself, since slow spraying at three attempts per account never reaches 500. The right move is to change the aggregation entity and add a separate rule for shared egress.
- rule: failed_logons_per_account
group_by: [target_account]
where: "event_id == 4625"
threshold: 8
window: 10m
enrich: [account_owner, is_service_account, src_geo]
- rule: spraying_from_shared_egress
group_by: [src_ip]
where: "event_id == 4625"
metric: distinct(target_account) # not raw failures
threshold: 25
window: 30m
applies_to: shared_egress_assets # 10.20.0.5 tagged as shared egress
The first rule serves normal hosts; the second keeps the gateway monitored but counts distinct accounts rather than aggregated typos. Escalating priority when failures are followed by a success adds a further quality signal.