End-to-end cybersecurity pipeline for:
- raw log ingestion and sessionization,
- hybrid anomaly detection (rules + embedding-based ML),
- MITRE ATT&CK retrieval and tactic/technique mapping (RAG style),
- evaluation and analyst-facing outputs.
The pipeline converts raw logs into structured session intelligence and maps suspicious sessions to MITRE ATT&CK techniques.
Core outputs:
data/processed/sessions_scored.parquet(detection output)data/processed/session_attack_mapping.parquet(ATT&CK mapping output)reports/metrics.json+reports/figures/*(evaluation)notebooks/phase9_final_source_ip_tactic_technique_outputs.ipynb(final source IP -> tactic -> technique summaries)
- Phase 1: Ingest raw logs ->
events.parquet - Phase 2: Enrich + sessionize ->
sessions.parquet,session_events/* - Phase 3: Detect suspicious sessions ->
sessions_scored.parquet - Phase 4: Download/build ATT&CK cache ->
attack_stix_cache.json - Phase 5: Index ATT&CK + sessions into Qdrant
- Phase 6: Map suspicious sessions to ATT&CK ->
session_attack_mapping.parquet - Phase 7: Generate manual-label templates (optional)
- Phase 8: Evaluate (proxy or labeled) -> metrics + figures
- Phase 9: Final reporting notebook with source IP to tactic-technique outputs and plots
src/cli/main.py- all CLI commandssrc/ingest/*- parsing + parquet writingsrc/features/*- enrichment + sessionizationsrc/detection/*- rules, embeddings, anomaly scoring, score fusionsrc/mitre/*- ATT&CK STIX download/cache buildsrc/rag/*- embeddings, Qdrant indexing, retrievalsrc/mapping/*- session-to-ATT&CK mappingsrc/eval/*- metrics, plots, evaluation runnernotebooks/phase*.ipynb- phase-wise analysis/visuals
- Python 3.10+
- Docker (recommended for Qdrant)
- Windows PowerShell examples are used below
# from repo root
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -U pip
pip install -e .Optional .env:
QDRANT_URL=http://localhost:6333
RAW_LOG_PATH=./data/raw/cj.log
OUT_DIR=./data/processeddocker compose -f docker/docker-compose.yaml up -d qdrantpython -m src.cli.main --helppython -m src.cli.main ingest `
--raw-path data/raw/cj.log `
--out-dir data/processedOutput: data/processed/events.parquet
python -m src.cli.main sessionize `
--events-path data/processed/events.parquet `
--out-dir data/processed `
--gap-seconds 600 `
--min-events 2Outputs:
data/processed/sessions.parquetdata/processed/session_events/part-*.parquet
python -m src.cli.main detect `
--sessions-path data/processed/sessions.parquet `
--out-path data/processed/sessions_scored.parquet `
--embed-model sentence-transformers/all-mpnet-base-v2 `
--device autoOutput: data/processed/sessions_scored.parquet
Use LOF instead of Isolation Forest:
python -m src.cli.main detect --use-lofpython -m src.cli.main attack-download `
--out-path data/attack/raw/enterprise-attack.jsonpython -m src.cli.main attack-cache `
--stix-path data/attack/raw/enterprise-attack.json `
--out-dir data/attackOutputs:
data/attack/attack_stix_cache.jsondata/attack/indexes/techniques_by_tid.jsondata/attack/indexes/objects_by_stix_id.json
python -m src.cli.main qdrant-index-attack `
--cache-path data/attack/attack_stix_cache.json `
--embed-model sentence-transformers/all-mpnet-base-v2 `
--device autopython -m src.cli.main qdrant-index-sessions `
--scored-sessions-path data/processed/sessions_scored.parquet `
--embed-model sentence-transformers/all-mpnet-base-v2 `
--device autopython -m src.cli.main rag-attack-search `
--q "high-rate command injection behavior with automated tool" `
--top-k 8python -m src.cli.main map-techniques `
--sessions-path data/processed/sessions_scored.parquet `
--out-path data/processed/session_attack_mapping.parquet `
--top-k 20 `
--keep-top-n 3 `
--embed-model sentence-transformers/all-mpnet-base-v2 `
--device autoOutput: data/processed/session_attack_mapping.parquet
python -m src.cli.main eval-templates `
--sessions-scored-path data/processed/sessions_scored.parquet `
--session-mapping-path data/processed/session_attack_mapping.parquet `
--out-dir data/labels `
--sample-rows 1000 `
--stratified trueOutputs:
data/labels/detection_labels.csvdata/labels/mapping_labels.csv
python -m src.cli.main eval `
--mode proxy `
--sessions-scored-path data/processed/sessions_scored.parquet `
--session-mapping-path data/processed/session_attack_mapping.parquet `
--attack-cache-path data/attack/attack_stix_cache.json `
--out-json-path reports/metrics.json `
--figures-dir reports/figurespython -m src.cli.main eval `
--mode labeled `
--sessions-scored-path data/processed/sessions_scored.parquet `
--session-mapping-path data/processed/session_attack_mapping.parquet `
--attack-cache-path data/attack/attack_stix_cache.json `
--detection-labels-path data/labels/detection_labels.csv `
--mapping-labels-path data/labels/mapping_labels.csvOpen and run:
notebooks/phase9_final_source_ip_tactic_technique_outputs.ipynb
This notebook produces final analyst-facing summaries:
source_ip,tactic,technique_name,technique_id,hits,first_seen,last_seen- plots for top tactics, top techniques, strongest source-IP connections, and embedding model comparison.
Run Phase 3 + Phase 8 separately for each embedding model and record weighted F1 from reports/metrics.json.
Examples:
# RoBERTa
python -m src.cli.main detect --embed-model sentence-transformers/all-roberta-large-v1
python -m src.cli.main eval --mode proxy
# BGE
python -m src.cli.main detect --embed-model BAAI/bge-large-en-v1.5
python -m src.cli.main eval --mode proxy
# MPNet
python -m src.cli.main detect --embed-model sentence-transformers/all-mpnet-base-v2
python -m src.cli.main eval --mode proxynotebooks/phase1_ingest_debug.ipynbnotebooks/phase2_enrich_sessionize.ipynbnotebooks/phase3_detection_score.ipynbnotebooks/phase4_stix_dataset_json.ipynbnotebooks/phase5_qdrant_rag_sessions_and_attack.ipynbnotebooks/phase6_session_attack_mapping.ipynbnotebooks/phase7_evaluation.ipynbnotebooks/phase8_detailed_evaluation.ipynbnotebooks/phase9_final_source_ip_tactic_technique_outputs.ipynb
- Keep embedding model dimensions consistent between ATT&CK indexing and mapping queries.
- Start Qdrant before running indexing/retrieval/mapping commands.
- If GPU is unavailable, use
--device cpu. - Do not commit private API/HF tokens in
.env.