Malware triage and incident response planning for Windows PE files.
ThreatSense takes a single suspicious Windows PE file (.exe, .dll, .sys) β a sample you suspect could be malware but haven't confirmed β supplied as a SHA-256 hash or a direct upload. It then answers two questions: what is this, and how should I respond to it?
Reaching that verdict is the system's whole job: a submitted file is treated as a suspect, not assumed guilty β it can legitimately come back Benign, or be classified into one of five malware categories with a threat level and a response plan to match.
It gathers evidence from three places:
- Static analysis of the PE file itself (structure, imports, strings, packing) β and, for hash lookups covered by the local EMBER dataset, EMBER-backed Capa capability and ATT&CK evidence (this enrichment isn't available on the upload-only path).
- A machine-learning model that predicts the malware category.
- VirusTotal for reputation, sandbox behavior, and known indicators.
It then runs that evidence through a rule engine mapped to MITRE ATT&CK techniques and MITRE D3FEND countermeasures, and produces two things:
- π An Incident Response Action Plan (IRAP) β a step-by-step response plan you can export as JSON.
- π A full report β rendered as a PDF you can read in the browser or hand off.
Both come from the same analysis, so they always agree.
Just want to look around? Try the live demo β no install required.
ThreatSense runs on macOS, Linux, and Windows. You'll need Python 3.12. PDF rendering uses WeasyPrint, which needs some system graphics libraries (GTK/Pango) β the setup script installs them for you, including MSYS2/GTK on Windows.
# macOS / Linux
./setup.sh
./run.sh# Windows
./setup.ps1
./run.ps1Or just open app.py in your IDE and run it β on every platform it re-launches itself with the project's virtual environment so the ML dependencies are always available. The app opens in your browser on a local port and drops you on the analyze page.
First time? Walk through it with WALKTHROUGH.md and try the known-working samples in docs/demo-hashes.json.
Most tools stop at a verdict like "malicious: 47/72." The hard part β deciding what to actually do β is left to you. ThreatSense covers that last step, and it follows three rules while doing it:
- It's honest about what it knows. If the evidence is thin, it tells you, instead of guessing.
- It's repeatable. The same PE file always produces the same plan. Nothing is random.
- It shows its work. Every recommendation traces back to a specific rule, technique, and source. No AI is used to invent response steps.
- π¬ Static PE analysis β hashes, sections, imports, strings, packing, and signature data (via
pefile). - π§© EMBER-backed Capa enrichment β for hash lookups covered by the local EMBER dataset, adds Capa-derived capability and ATT&CK evidence (not available on the upload-only path).
- π§ ML category classification β a LightGBM model sorts PE files into six categories (Random Forest as a backup).
- π VirusTotal v3 enrichment β reputation, behavior, ATT&CK techniques, and related indicators.
- βοΈ 35-rule response engine β maps ATT&CK techniques to MITRE D3FEND countermeasures and concrete, grouped response actions.
- π Threat score β a triage score from behavior, category, VT consensus, and evasion signals.
- π IRAP + PDF report β machine-readable plan and human-readable report from one analysis.
- π Local history β every run is saved to a local database you can browse.
- π₯οΈ Web UI β open a browser, paste a hash, done.
ThreatSense runs as an instrumented, staged pipeline. Each stage enriches a single strongly-typed evidence record, is monitored independently (status + timing), and is allowed to drop out without collapsing the run.
flowchart TB
IN["<b>Input</b><br/>SHA-256 hash Β· PE upload (.exe / .dll / .sys)"]
subgraph ACQ["β Evidence acquisition"]
direction LR
S["<b>Static analyzer</b> Β· <i>pefile</i><br/>imports Β· sections Β· strings<br/>packing Β· signing<br/><i>+ EMBER-backed Capa ATT&CK (hash path)</i>"]
M["<b>ML classifier</b> Β· <i>LightGBM</i><br/>6-category prediction<br/>+ confidence"]
V["<b>VirusTotal v3</b><br/>reputation Β· behavior<br/>MITRE trees Β· IOC relationships"]
end
NORM["<b>Normalized evidence record</b> β <code>ThreatSenseAnalysis</code><br/>coverage mode: full / vt_thin / vt_down_capa / static_minimal"]
subgraph DEC["β‘ Decision"]
direction LR
R["<b>Rule engine</b> Β· 35 deterministic rules<br/>evidence β ATT&CK technique + D3FEND countermeasure<br/>β phased response actions"]
T["<b>Threat scorer</b><br/>behavior Β· category Β· VT Β· evasion<br/>β mode-aware triage score"]
end
OUT["<b>IRAP</b> (JSON) Β· <b>Analysis report</b> (PDF)"]
DB[("SQLite history")]
IN --> S & M & V
S & M & V --> NORM
NORM --> R & T
R & T --> OUT
OUT --> DB
- Single source of truth β the IRAP, the PDF report, and the stored history all derive from the same normalized
ThreatSenseAnalysisrecord, so the three can never disagree. - Deterministic decisioning β rules fire only on observed evidence, and identical input yields an identical plan. No model is ever asked to invent response steps.
- Graceful degradation β when a source is missing (an unknown hash, VirusTotal unavailable), the pipeline records the reduced coverage mode and continues instead of failing closed.
- Per-stage instrumentation β every acquisition stage is tracked individually with status and timing, then surfaced in the analysis metadata for full traceability.
More detail: docs/architecture.md and docs/methodology.md.
Sometimes not every source is available β a hash might be unknown locally, or VirusTotal might be down. Instead of hiding that, ThreatSense labels each analysis with the evidence it actually had:
| Mode | What it means |
|---|---|
full |
Static analysis, ML, and rich VirusTotal data β all available. |
vt_thin |
VirusTotal has the file, but behavior or local data is limited. |
vt_down_capa |
VirusTotal is unavailable, but EMBER-backed Capa ATT&CK evidence carries the analysis. |
static_minimal |
Only local static analysis was possible. |
Settings come from environment variables (an .env file works). Copy .env.example to start.
| Variable | What it's for |
|---|---|
VT_API_KEY |
Your VirusTotal API key. Without it, VT enrichment is skipped and the analysis degrades gracefully. |
THREATSENSE_EMBER_DATA_DIR |
Optional local dataset folder (default ./PE). |
THREATSENSE_VT_CACHE_DIR |
Where VirusTotal responses are cached (default ./.cache/vt). |
PORT |
Port to use (0 picks a free one). |
THREATSENSE_AUTO_SHUTDOWN |
Set to 1 for demo auto-shutdown behavior. |
The IRAP is a JSON plan with six parts: metadata & evidence coverage, classification & threat level, detected techniques, indicators of compromise, recommended actions, and references. Actions are grouped by response phase and cited to defensive frameworks.
It gives you guidance, not commands. ThreatSense won't hand you a script to run, because details like file paths and process IDs from a sandbox won't match your live environment. (Schema β)
The report is the same analysis as a polished PDF, previewed right in the browser.
ThreatSense ships with a trained LightGBM classifier (and a Random Forest as a fallback).
| LightGBM | Random Forest | |
|---|---|---|
| Accuracy | 93.25% | 91.5% |
| Macro F1 | 0.78 | 0.75 |
- Six categories: Ransomware, Trojan, Worm, Spyware/Stealer, Backdoor/RAT, Benign.
- Trained on EMBER2024-style features (8,000 train / 2,000 test samples).
The model adds category context; the rule engine does the response planning. Training code is in colab/train_model.py β details in docs/ml-training-summary.md.
app.py # Web app: routes, API, uploads, PDF preview
threatsense/ # The analysis engine
static_analyzer.py # parse the PE file
ember_adapter.py # read dataset records + extract features
ml_classifier.py # predict the category
vt_client.py # VirusTotal client + evidence cleanup
rule_engine.py # ATT&CK β response actions
scorer.py # threat score
irap_generator.py # build the IRAP
report_generator.py # render the PDF
database.py # local history
pipeline.py # ties it all together
rules/rules.json # the 35-rule catalog
models/ # trained model files
website/ # web frontend (Next.js)
docs/ # how everything works
colab/ # model training notebook
Local files like the history database and VT cache are created automatically when you run it. None are needed to analyze an uploaded PE file.
ThreatSense is deliberately focused. Keep these boundaries in mind:
- Windows PE files only (
.exe,.dll,.sys). - Behavior data comes from VirusTotal, not a built-in sandbox.
- Hash-only lookups depend on local data and VT being available.
- The model is a validated prototype β more training would improve it.
- The threat score is a triage signal, not a full enterprise severity rating. It doesn't know your assets, business impact, or recovery cost β that judgment stays with you.
- Recommendations are guidance, not ready-to-run commands.
- It's a tool for analysis and demos, not an EDR, agent, or SOAR platform.
Full notes: docs/limitations.md.
| Doc | Topic |
|---|---|
| architecture.md | Components and data flow |
| methodology.md | Analysis approach and evidence sources |
| rule-engine.md | How the response rules work |
| threat-scoring.md | How the score is built |
| irap-schema.md | Shape of the response plan |
| ml-training-summary.md | Model training |
| evaluation-summary.md | Validation |
| limitations.md | Scope and future work |
ThreatSense works with real, potentially malicious PE files and surfaces real indicators. Treat every submitted sample as live malware until proven otherwise: handle it in a properly isolated environment, and treat the output as decision support β not as an automatic fix.
ThreatSense's classifier is trained on the EMBER2024 dataset and uses its thrember feature extractor, both released by FutureComputing4AI under the Apache-2.0 license. If you build on this project or its model, please also cite the EMBER2024 authors:
Robert J. Joyce, Gideon Miller, Phil Roth, Richard Zak, Elliott Zaresky-Williams, Hyrum Anderson, Edward Raff, and James Holt. EMBER2024 β A Benchmark Dataset for Holistic Evaluation of Malware Classifiers. Proceedings of the 31st ACM SIGKDD Conference on Knowledge Discovery and Data Mining, 2025. arXiv:2506.05074
BibTeX
@inproceedings{joyce2025ember,
title={EMBER2024 - A Benchmark Dataset for Holistic Evaluation of Malware Classifiers},
author={Robert J. Joyce and Gideon Miller and Phil Roth and Richard Zak and Elliott Zaresky-Williams and Hyrum Anderson and Edward Raff and James Holt},
year={2025},
booktitle={Proceedings of the 31st ACM SIGKDD Conference on Knowledge Discovery and Data Mining},
}Released under the MIT License.
