96 أسطر
4.3 KiB
Markdown
96 أسطر
4.3 KiB
Markdown
# 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.
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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.
|