DEV Community

Jude Hilgendorf
Jude Hilgendorf

Posted on

I Built an Offline Threat-Hunting CLI in Python — Here's How ThreatLens Catches Real Attacks

If you've ever stared down thousands of EVTX, Syslog, or JSON log events after a suspected incident, you already know the pain: the signal-to-noise ratio is brutal, and most "SIEM-lite" tools either want a cloud subscription or a 20-step install.

I wanted something different — a single CLI I could drop on an air-gapped workstation, point at a folder of logs, and get a ranked list of attack patterns mapped to MITRE ATT&CK within seconds.

That's ThreatLens — an offline log analysis and threat hunting CLI written in Python. No agents, no cloud, no license server. Just pip install, scan, read the report.

What it actually does

ThreatLens parses security logs and runs them through a detection engine that covers 12 attack categories mapped to MITRE ATT&CK tactics:

  • Brute-force and password spray attacks (T1110)
  • Lateral movement via rapid multi-host authentication (T1021)
  • Privilege escalation through sensitive permission assignments (T1134)
  • Suspicious process execution including LOLBins and encoded PowerShell (T1059)
  • Defense evasion patterns like log clearing and audit policy changes (T1070, T1562)
  • Persistence mechanisms via services, scheduled tasks, and registry modifications (T1543, T1053, T1547)

It ingests JSON/NDJSON, native EVTX, RFC 3164/5424 Syslog, and CEF — with auto-detection, so you don't have to flag formats manually.

Exports: color-coded terminal, JSON, CSV, self-contained HTML reports with SVG charts and an interactive attack timeline, or direct Elasticsearch ingestion if you already have a stack.

Why I built it

I'm a cybersecurity student who spends a lot of lab time on blue-team exercises. Every time I finished a scenario, I'd end up with a mountain of Windows Event Logs and no fast way to confirm what actually happened. Commercial tools were overkill for a lab, and open-source options usually needed a full ELK stack before they'd tell me anything useful.

I wanted a tool that answered one question fast: "Is there anything interesting in this pile of logs?" — without spinning up infrastructure.

Code walkthrough: the detection engine

The core idea is a three-layer detection model:

  1. Built-in detections tuned via rules/default_rules.yaml
  2. Custom YAML rules — 12 operators (equals, contains, regex, gt/lt, etc.) with grouping and time windows
  3. Sigma rules — natively compatible with community Sigma repos, with field modifiers and compound conditions

Here's a custom rule that detects 5+ failed logons from the same source in under 60 seconds — classic brute-force:

name: brute_force_failed_logons
description: Multiple failed logon attempts from single source
severity: high
mitre: T1110
match:
  all:
    - field: event_id
      op: equals
      value: 4625
  group_by: source_ip
  window: 60s
  threshold:
    op: gt
    count: 5
Enter fullscreen mode Exit fullscreen mode

The rule engine normalizes incoming events (EVTX → dict, Syslog → dict, etc.), pipes them through each loaded rule, and any match pushes an alert into a correlation stage that links multi-stage kill chains. So a brute-force hit followed by a privileged logon from the same IP a minute later gets stitched into one chain, not two disconnected alerts.

That correlation step is what makes the output usable — instead of 400 alerts you get 8 attack chains ranked by severity.

Using it

Quick install from source:

git clone https://github.com/TiltedLunar123/ThreatLens.git
cd ThreatLens
python -m venv .venv
pip install -e ".[dev]"
Enter fullscreen mode Exit fullscreen mode

Or Docker if you want zero local install:

docker build -t threatlens .
docker run --rm -v $(pwd)/logs:/data threatlens scan /data/
Enter fullscreen mode Exit fullscreen mode

Then scan:

threatlens scan sample_data/sample_security_log.json
threatlens scan logs/ --min-severity high -o report.json -f json
threatlens scan logs/ --custom-rules my_rules/ --sigma-rules sigma/rules/
threatlens follow /var/log/events.json --buffer-size 50
Enter fullscreen mode Exit fullscreen mode

That last one is a tail -f-style live monitor with a ring buffer for in-memory correlation — handy if you're hunting during an active incident instead of after the fact.

Results so far

Against sample datasets I baked in: zero false positives on benign activity and 100% detection across the embedded techniques. Worth the asterisk that this is my test corpus — I'd love more folks running it against real logs and opening issues.

What's next

On the roadmap: a built-in rule marketplace, richer EVTX field extraction, and a lightweight Windows service wrapper for continuous monitoring.

Try it

If you're a SOC analyst, student, or homelabber who wants a dead-simple offline triage tool, give it a run. If it helps, a ⭐ on the repo means a lot.

Repo: github.com/TiltedLunar123/ThreatLens

PRs, issues, and detection rule contributions welcome.

Top comments (0)