cybersecurity · intermediate · ~15 min · safe pentest lab

Detect brute-force IPs in auth.log

Group log lines by source IP, count occurrences, threshold the result.

Challenge

Your job

Implement:

int detect_brute_force(const char *log, int threshold);

Walk the buffer line by line. Each Failed password ... from <ip> line counts as one failure for that IP. Return the number of distinct IPs whose failure count is at least threshold.

Examples

log threshold returns
"" 1 0
Three Failed from 192.0.2.7 3 1
Same 4 0
Mix of Failed and Accepted 1 (count distinct IPs that failed)

Rules

  • The IP is whatever follows from and precedes port.
  • Skip Accepted lines entirely.
  • Pure string parsing on the static buffer.

Hints

  1. (concept) Two passes: collect IPs+counts into a small fixed table, then threshold.
  2. (direction) strstr(line, "Failed password") filters. strstr(line, "from ") locates the IP start.
  3. (common bug) Counting the same IP twice in the table because you skipped the lookup before insert.

Security note

This exercise is for defensive learning in a local lab only. Do not use it on systems you do not own or have explicit permission to test.

Why this matters

The simplest brute-force detector you'll ever write — and the heart of every SOC routine.

Input format

A NUL-terminated multi-line log buffer + an integer threshold.

Output format

Non-negative int — count of IPs over threshold.

Constraints

No allocation. Small fixed-size table is fine (≤128 entries).

Starter code

#include <stddef.h>
#include <string.h>

int detect_brute_force(const char *log, int threshold) {
    /* TODO */
    (void)log; (void)threshold;
    return 0;
}

Common mistakes

Counting Accepted lines. Adding the same IP twice. Missing the from → IP → port parsing pattern.

Edge cases to handle

Empty log. Threshold higher than any IP's count. Same IP across many lines.

Complexity

O(n × m) worst-case where m is the number of distinct IPs (small in practice).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.