Skip to content

Project · Cyber Security: from zero to SOC analyst

Project: catch a password-guessing attack

Projectbeginner· about 3 hours· 6 steps

The brief

An engineering college's lab server is open to SSH from the internet. Its log shows a burst of failed logins. You write a Python detector that parses the log, counts failures per address, flags the attackers, and finds the one login that worked. Then you read the same kind of log on your own Linux VM.

Why it matters

Brute-force and password-spraying attacks on SSH, RDP and web logins never stop. Finding them in authentication logs is one of the first jobs a SOC analyst does, and "many failures, then a success" is a classic SIEM rule. Doing it in Python teaches you what the SIEM is doing for you.

Skills you practise

  • reading Linux authentication logs
  • regular expressions
  • counting with dictionaries
  • thresholds and false positives
  • CIDR checks

You need

  • For the last step: your own Linux VM (Rocky, AlmaLinux, RHEL, Ubuntu or Kali) with SSH running

What you will have at the end

detect.py, a tested brute-force detector that names the attacking addresses and the compromised account, plus real log lines from your own VM and a short list of fixes.

How it is marked (rubric, 100 points)
Detector worksEvery check passes: parsing, counts, suspects, outside addresses and the break-in.45
Analyst judgementYou can explain the threshold you chose and why "failures then success" is the most urgent alert.25
Real log evidenceReal failed-login lines from your own VM are pasted.15
FixesYou name concrete fixes: lock and reset asha, keys-only SSH, fail2ban or firewall rules, and MFA.15

0/6 steps done

Step 1 of 6

Parse one log line

parse_line(line) pulls out the result, the user name and the IP address from an sshd line, and returns None for other lines.

Every sshd login line says "Failed password" or "Accepted password", then "for <user> from <ip> port <n>". Failed logins for accounts that do not exist add "invalid user" before the name. A regular expression with groups captures the three parts.

The pattern is given in the solution style: (Failed|Accepted) password for (?:invalid user )?(\S+) from (\S+) port. \S+ means "one or more characters that are not spaces". Lines from other programs, such as CRON, must return None.

Run shows what your code prints. Check runs the step's tests. Ctrl+Enter checks too.