الملفات
ghaymah-exam-Mohamed-Ashraf…/q4-SIEM-build/README.md

4.3 KiB

Simple SIEM — Log Analyzer + Threat Dashboard

A small SIEM built for a 3-endpoint environment: a web server, a firewall/router, and an SSH authentication log source. A Python script parses and correlates suspicious activity across all three; a static HTML/CSS/JS dashboard visualizes the resulting alerts and malicious IPs.

siem_project/
├── logs/
│   ├── endpoint1_web_access.log     # sample nginx-style access log
│   ├── endpoint2_firewall.log       # sample SRC/DST/PORT/ACTION firewall log
│   └── endpoint3_auth.log           # sample sshd auth log
├── siem_analyzer.py                 # Part 1 — the analyzer
├── dashboard/
│   ├── index.html                   # Part 2 — the dashboard
│   ├── style.css
│   ├── script.js
│   ├── siem_report.json             # generated by siem_analyzer.py
│   └── data.js                      # generated by siem_analyzer.py (offline fallback)
├── README.md                        # this file
└── PUBLISH_TO_GHAYMAH.md            # Part 3 — publishing guide

Part 1 — siem_analyzer.py

Pure standard library, no pip install needed.

python3 siem_analyzer.py
# or point it at different files:
python3 siem_analyzer.py --logs-dir ./logs --out-dir ./dashboard

It parses all three log formats, runs the detection rules below, prints a console summary, and writes siem_report.json + data.js into dashboard/.

Detection rules

Rule Source Logic Severity
SQL_INJECTION / XSS / PATH_TRAVERSAL / COMMAND_INJECTION web Regex signatures against the (URL-decoded) request path critical/high
RECON_SCANNER web ≥3 requests with a known scanner user-agent (sqlmap, nikto, nmap…) medium
HIGH_REQUEST_RATE web ≥15 requests from one IP within 60s medium/high
PORT_SCAN firewall ≥8 distinct destination ports from one IP within 120s high
BRUTE_FORCE_SSH auth ≥5 failed logins from one IP within 300s high
ACCOUNT_COMPROMISE_SUSPECTED auth A successful login from an IP right after it triggered a brute-force alert critical
BLACKLISTED_IP_ACTIVITY any IP matches a seeded threat-intel list critical
MULTI_VECTOR_ATTACK correlation Same source IP triggered alerts on ≥2 different endpoints critical

That last rule is the actual point of a SIEM: no single log tells the whole story, but seeing the same IP port-scan the firewall, brute-force SSH, and throw SQLi at the web app is what turns three noisy logs into one clear "this IP is attacking us" signal. All thresholds live in the THRESHOLDS dict at the top of the script if you want to tune them.

Part 2 — the dashboard

Open dashboard/index.html directly in a browser — it works out of the box because it falls back to the embedded data.js snapshot. For the "live" experience (auto re-fetching siem_report.json when you click Refresh), serve the folder instead:

cd dashboard
python3 -m http.server 8000
# open http://localhost:8000

What's on it:

  • Stat cards — total alerts and the severity breakdown.
  • Threat Radar — the top malicious IPs plotted by score (closer to center = more dangerous); a critical IP gets a pulsing ring.
  • Severity Mix — a proportional bar of critical/high/medium/low.
  • Top Malicious IPs — ranked list with a relative-score bar.
  • Alerts table — searchable, filterable by severity/endpoint; click a row to expand the raw log line(s) behind that alert.

Re-running siem_analyzer.py regenerates both output files — refresh the page (or click the in-app Refresh button if you're on a local server) to see updated results.

A note on why the table doesn't use innerHTML

Alert descriptions and evidence are literally attacker-supplied log text — some of the sample data contains a real <script> payload. script.js builds every row with createElement/textContent, never string-built HTML, so the console can't be XSS'd by the very payloads it's reporting on.

Regenerating with your own logs

Swap the three files in logs/ for real exports (keep the same filenames, or pass --logs-dir) and adjust the regexes in siem_analyzer.py if your log format differs from the nginx / iptables-style / sshd formats assumed here.