Brute-Force Attack Detection & Investigation
Detect and investigate brute-force attacks through security log analysis.
Project objective
Build a repeatable investigation process that turns a single suspicious alert into a confident verdict: given a spike of failed authentication attempts, determine whether it's a genuine brute-force attempt, a misconfigured script hammering the wrong host, or background internet noise — and decide what action follows.
Core work
The investigation moves from raw log correlation, to alert confirmation in Wazuh, to source enrichment, to a documented decision.
# 1. Correlate raw failures by source IP directly from the log
grep "Failed password" /var/log/auth.log \
| awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head
# 2. Cross-check against the Wazuh alert stream for the same window
sudo tail -n 500 /var/ossec/logs/alerts/alerts.json \
| jq -c 'select(.rule.groups[]=="authentication_failed")' \
| jq -s 'group_by(.data.srcip) | map({ip: .[0].data.srcip, count: length}) | sort_by(-.count)'
# 3. Confirm whether the source was already auto-banned
sudo fail2ban-client status sshd
# 4. Enrich the source IP before deciding severity
whois 203.0.113.44 | grep -iE "country|orgname|netname"
geoiplookup 203.0.113.44
# 5. Check whether any attempt actually succeeded (the real question that matters)
grep "Accepted password" /var/log/auth.log | grep "203.0.113.44"In the reference case used for this write-up, one source IP accounted for 214 failed attempts against three different usernames inside an 18-minute window with no successful login — a textbook credential-stuffing pattern rather than a single mistyped password, and enough to justify escalating and permanently blocking the source rather than treating it as noise.
Failed SSH auth attempts by source IP over the investigated window — one source dominates the volume, the rest is background scanning noise.
What to document
The write-up includes the raw grep/jq output that established the pattern, the WHOIS enrichment for the top offending IP, confirmation that no login succeeded, and the final decision path (block at the firewall, keep the Wazuh rule active, no further escalation needed since no compromise occurred).