Skip to content

About

Shared Rust IOC and malware detection engine for the MarlinSpike & Fathom suites, evaluating observed network events against rule packs and emitting structured findings for MarlinSpike and Fathom.`

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

marlinspike-malware

Shared Rust crate for malware and IOC detection across the MarlinSpike suite.

marlinspike-malware is one of the Rust engines in the MarlinSpike repo family, alongside marlinspike-dpi. It loads YAML rule packs, evaluates generic observed events against them, and emits structured findings. The engine is intentionally product-neutral so both MarlinSpike and Fathom can adapt their own telemetry into the same rule surface.

Runtime operation is fully local. Appliances remain functional when air-gapped. Public feeds (ThreatFox, URLhaus, MalwareBazaar) can be normalized into the YAML schema offline via the sibling marlinspike-malware-rules repo.

Architecture

                       marlinspike-dpi
                            |
                       Bronze events
                            |
                    marlinspike-malware
                       /          \
              YAML rule packs    ObservedEvent stream
                       \          /
                    MalwareFinding[]
                            |
                   MarlinSpike report
                     (analysis block)

Scan Flow

marlinspike-malware scan
  --rules-dir → load + compile YAML packs
  --events    → ObservedEvent[] JSON (from _ms_engine.py)
  --output    → MalwareFinding[] JSON (back to _ms_engine.py)

The engine sits in the MarlinSpike pipeline between DPI event emission and report assembly. It consumes Bronze-style observed events (DNS queries, HTTP hosts/URIs, TLS SNI, artifact hashes, IP addresses, protocol metadata) and evaluates them against compiled rule packs to produce MalwareFinding records.

Integration Contracts

This engine follows the Extensibility Contracts defined for the MarlinSpike suite:

Surface Role
Rust engine Packet/event-facing, high-throughput IOC matching
YAML rule packs Declarative IOC and signature content
Python plugin Report-facing enrichment (handled by other modules)

The engine accepts a rules directory, compiles it into a normalized bundle, and processes batches of ObservedEvent structs. It does not own topology scoring, ATT&CK mapping, or UI behavior.

Bronze Consumer Contract

marlinspike-malware consumes the same Bronze event surface as the core MarlinSpike engine. It can evaluate events from:

  • protocol_transaction — network conversations with extracted observables
  • extracted_artifact — file hashes, binary signatures, artifact keys
  • asset_observation — host-level indicators

See bronze-consumer-contract.md for the full consumer rules.

Rule Engine

Observable Fields

Rules match against these observable fields extracted from Bronze events:

Field Description Example
dns_query DNS query domain evil.example.com
dns_answer DNS response data 185.215.113.x
http_host HTTP Host header c2.badactor.invalid
http_uri HTTP request URI /api/v1/beacon
tls_sni TLS Server Name Indication update.malware.invalid
artifact_sha256 SHA-256 hash of extracted artifact a1b2c3d4...
artifact_key Named artifact identifier (mutex, registry key, file path) HKLM\Software\Malware
src_ip Source IP address 10.0.0.50
dst_ip Destination IP address 45.33.32.156
src_mac Source MAC address aa:bb:cc:dd:ee:ff
dst_mac Destination MAC address ff:ee:dd:cc:bb:aa
hostname Device hostname ENG-WS-014
protocol Protocol identifier modbus, s7comm
any_text Matches against all text fields Catch-all for protocol artifacts

Match Operators

Operator Behavior
equals Exact string match (default)
contains Substring match
prefix String starts with value
suffix String ends with value

All operators support case_sensitive: true/false (default: false).

Match Modes

Mode Behavior
any Fire if any condition matches (default, OR logic)
all Fire only if all conditions match (AND logic)

Finding Severities

info | low | medium | high | critical

Finding Output Schema

Each MalwareFinding emitted by the scan command has the following fields:

Field Type Description
finding_id string Unique identifier for this finding
rule_id string ID of the rule that matched
rule_name string Human-readable rule name
family string Malware family (e.g. cobaltstrike, emotet)
severity string info | low | medium | high | critical
confidence float Confidence score (0.0–1.0)
summary string Human-readable description of the match
observable_field string The field that matched (e.g. dns_query, tls_sni)
observable_value string The value that triggered the match
event_id string ID of the source event
capture_id string Capture session ID
timestamp string ISO 8601 UTC timestamp of the event
src_ip string? Source IP address, if present
dst_ip string? Destination IP address, if present
src_mac string? Source MAC address, if present
dst_mac string? Destination MAC address, if present
references string[] URLs to advisories, ATT&CK techniques, etc.
tags string[] Classification tags (e.g. apt, c2, dns)
source_feed string? Attribution feed name, if applicable
metadata object Arbitrary key-value metadata from the rule or event

Rule Pack Schema

version: v1
name: "Pack Name"
source:
  name: "attribution source"
  url: "https://..."
  license: "Apache-2.0"
  description: "Source description"
rules:
  - id: unique-rule-id
    name: "Human-readable rule name"
    family: "malware-family"
    severity: critical
    confidence: 0.90
    description: "What this rule detects and why"
    tags: [apt, c2, dns]
    references:
      - "https://attack.mitre.org/techniques/T1071/"
      - "https://www.cisa.gov/..."
    match_mode: any
    conditions:
      - field: dns_query
        op: suffix
        value: ".malware.invalid"
        case_sensitive: false
      - field: tls_sni
        op: contains
        value: "beacon"

Bundled Rule Packs

The rules/ directory ships 29 curated packs with 919 detection rules across the full threat landscape.

Threat Coverage

Pack Rules Coverage
Malware Loaders 24 BazarLoader, Emotet, QakBot, IcedID, Bumblebee, SocGholish, Gootloader, Raspberry Robin, Pikabot, GuLoader
C2 Frameworks 18 Cobalt Strike, Metasploit, Sliver, Havoc, Brute Ratel, Mythic, PoshC2, Covenant, Empire, Nighthawk
RATs 32 AsyncRAT, DarkComet, njRAT, Remcos, QuasarRAT, Agent Tesla, NanoCore, Warzone, DcRAT, XWorm, NetWire, Gh0st RAT
Ransomware 34 LockBit, BlackCat/ALPHV, Royal/BlackSuit, Cl0p, Black Basta, Akira, Play, Rhysida, Medusa, BianLian, Hive, Conti
Infostealers 24 RedLine, Raccoon, Vidar, LummaC2, Rhadamanthys, StealC, META, Aurora, Mystic, Titan, FormBook/XLoader
ICS/OT Threats 32 TRITON, Industroyer 1+2, PIPEDREAM, BlackEnergy, Havex, Stuxnet-derived, FrostyGoop, CosmicEnergy, IRONGATE
Suspicious Patterns 38 DNS tunneling, DGA, dynamic DNS abuse, encoded payloads, cryptomining, Tor, phishing lookalikes, exfiltration
APT Tooling 40 APT28, APT29, APT41, Lazarus, Turla, Kimsuky, Sandworm, MuddyWater (SUNBURST, ShadowPad, PlugX, Snake, etc.)
Wipers 27 WhisperGate, HermeticWiper, CaddyWiper, AcidRain, Shamoon, ZeroCleare, Dustman, Meteor, Agrius
Botnets 31 Mirai variants, TrickBot, Dridex, ZLoader, Qakbot, Androxgh0st, Volt Typhoon, Emotet, Phorpiex, Amadey
Webshells 36 China Chopper, Godzilla, Behinder, AntSword, ASPXSpy, HAFNIUM/ProxyShell drops, IIS backdoors, generic patterns
Backdoors & Implants 31 ShadowPad, PlugX, MATA, Daxin, BPFDoor, Symbiote, BlackLotus, CosmicStrand, Derusbi, GoldMax
Exploit Delivery 35 Log4Shell, ProxyShell/Logon/NotShell, MOVEit, Confluence, Citrix Bleed, FortiGate, Ivanti, Spring4Shell, exploit kits
Proxy & Tunneling 31 Chisel, frp, ngrok, Cloudflare Tunnel, reGeorg, Ligolo, Plink, GOST, residential proxies, Shadowsocks
Credential Theft 30 Mimikatz, LSASS dumps, Kerberoasting, Rubeus, Impacket, Responder, BloodHound, Evilginx, CrackMapExec
Data Exfiltration 31 Cloud storage, Rclone, DNS exfil, ICMP tunneling, Telegram/Discord/Slack webhooks, paste sites, file hosting
Mobile & Spyware 34 Pegasus, Predator, FinFisher, Hermit, Candiru, stalkerware, FluBot, SharkBot, Xenomorph, Cerberus, TeaBot
Cryptocurrency Threats 33 Wallet drainers, clipbankers, fake exchanges, cryptojacking, DPRK crypto theft, mixers, fake wallet apps
Lateral Movement 34 PsExec, WMI, WinRM, DCOM, RDP tunneling, EternalBlue, PrintNightmare, SCShell, CobaltStrike lateral
Supply Chain 37 3CX, SolarWinds, Kaseya, Codecov, Polyfill.io, npm/PyPI typosquatting, dependency confusion, CDN compromise
Recon & Scanning 41 Nmap, Masscan, Nuclei, Shodan, ADFind, BloodHound, Gobuster, SQLMap, WPScan, cloud enumeration
Defense Evasion 41 Certutil, mshta, bitsadmin, AMSI bypass, ETW patching, LOLBins, PowerShell cradles, reflective injection
Phishing-as-a-Service 39 Tycoon 2FA, EvilProxy, Greatness, W3LL Panel, Rockstar 2FA, FlowerStorm, OAuth phishing, quishing
Cloud & SaaS Threats 35 TeamTNT, Kinsing, Denonia, SCARLETEEL, SCATTERED SPIDER, container escapes, K8s exploitation, cloud C2
DNS Abuse 35 DoH C2, DNS rebinding, subdomain takeover, IDN homograph, sinkholes, malicious nameservers, fast-flux
Email Threats 35 BEC infrastructure, malspam, HTML smuggling, callback phishing, OneNote/ISO abuse, OAuth consent phishing
IoT Threats 34 Camera/router exploitation, Moobot, Fodcha, RapperBot, Zerobot, AVrecon, UPnP/SSDP/MQTT/CWMP abuse
Ransomware Ecosystem 35 IAB marketplaces, OFAC-sanctioned exchanges, SystemBC, affiliate tools, loader handoffs, payment infra
Adware & PUPs 32 Fireball, DealPly, Conduit, Superfish, BADBOX, tech support scams, SocGholish distribution, click fraud

Severity Distribution

Severity Rules
Critical ~380
High ~380
Medium ~110
Low ~30
Info ~19
Total 919

IOC Sources

All rules are sourced from published threat intelligence:

  • Government advisories: CISA, NSA, FBI, NCSC-UK, CERT-UA
  • MITRE: ATT&CK Enterprise + ICS frameworks
  • Vendor research: Mandiant, CrowdStrike, ESET, Kaspersky, Unit 42, SentinelOne, Sophos, ThreatFabric, Cleafy
  • Civil society: Amnesty International, Citizen Lab
  • Community: MalwareBazaar, abuse.ch, stalkerware-indicators
  • Standards bodies: OFAC sanctions designations

CLI

The crate includes a CLI for rule-pack validation and compilation:

# Validate all rule packs
cargo run -- validate --rules-dir rules/

# Validate with JSON output
cargo run -- validate --rules-dir rules/ --json

# Compile to a normalized JSON bundle
cargo run -- compile --rules-dir rules/ --output build/bundle.json --pretty

# Scan observed events against rules
cargo run -- scan --rules-dir rules/ --events events.json --output findings.json

The scan subcommand reads an ObservedEvent[] JSON array, evaluates every event against all loaded rules, and writes the resulting MalwareFinding[] JSON to the output path.

Validation checks:

  • Pack and rule field completeness
  • Confidence range (0.0-1.0)
  • At least one condition per rule
  • No duplicate rule IDs across all packs
  • Valid field names and operators

MarlinSpike Integration

The engine is invoked as a subprocess by MarlinSpike's Python engine (_ms_engine.py) during Stage 4b of the analysis pipeline.

Binary Auto-Discovery

MarlinSpike locates the marlinspike-malware binary by checking, in order:

  1. MARLINSPIKE_MALWARE_BIN environment variable
  2. PATH
  3. ~/marlinspike-malware/target/release/
  4. ~/marlinspike-malware/target/debug/

Rules Auto-Discovery

Rule packs are located by checking, in order:

  1. MARLINSPIKE_MALWARE_RULES environment variable
  2. ~/marlinspike-malware/rules/
  3. ~/marlinspike-malware-rules/packs/

Event Conversion

_ms_engine.py converts MarlinSpike conversation objects into ObservedEvent JSON before passing them to the engine. The following observables are extracted:

  • DNS queries and answers
  • IP addresses (source and destination)
  • MAC addresses
  • Protocol identifiers
  • Bronze passthrough attributes (HTTP hosts/URIs, TLS SNI, artifact hashes, etc.)

Finding Conversion

The engine's MalwareFinding[] output is converted back into MarlinSpike report structures:

  • c2_indicators with type MALWARE_IOC_MATCH
  • risk_findings attached to the analysis report

Optional Stage

Stage 4b is optional. If the binary or rules directory cannot be found, analysis continues without malware matching. When --fast is passed to MarlinSpike, malware matching is skipped entirely.

Library API

use marlinspike_malware::{MalwareEngine, ObservedEvent, ObservedValue, MatchField};

// Load rules from a directory
let engine = MalwareEngine::from_rule_dir("rules/")?;
println!("Loaded {} rules", engine.rule_count());

// Process observed events
let findings = engine.process_observed_batch("bronze-dpi", &events);
for finding in &findings {
    println!(
        "[{}] {} — {} (confidence: {:.0}%)",
        finding.severity.as_str(),
        finding.rule_name,
        finding.summary,
        finding.confidence * 100.0,
    );
}

Key Types

Type Description
MalwareEngine Compiled rule set, processes event batches
ObservedEvent Single network event with metadata and observables
ObservedValue One observable field+value pair within an event
MalwareFinding Detection result with rule metadata, severity, evidence
RulePack Deserialized YAML rule pack
CompiledRuleBundle Serializable compiled bundle (for JSON export)

Sibling Repositories

Repo Purpose
marlinspike Suite repo — engine, workbench, plugins
marlinspike-dpi Rust DPI engine — packet parsing, Bronze event emission
marlinspike-malware-rules Published rule content — manual packs + public feed imports
marlinspike-mitre Python plugin — ATT&CK mapping from report findings

Relationship to marlinspike-malware-rules

This repo (marlinspike-malware) is the engine. The sibling marlinspike-malware-rules repo is the published content:

marlinspike-malware          marlinspike-malware-rules
├── src/                     ├── packs/
│   ├── engine.rs            │   ├── manual/         ← curated rules
│   ├── rules.rs             │   └── public/         ← ThreatFox, URLhaus, MalwareBazaar
│   ├── finding.rs           ├── manifests/
│   └── observed.rs          │   └── index.yaml
├── rules/                   └── scripts/
│   └── (dev/bundled rules)      ├── build_index.py
└── Cargo.toml                   └── update_public_feeds.py

The rules/ directory in this repo ships bundled detection content for development and standalone use. For production deployments, rule content is managed in marlinspike-malware-rules and compiled into bundles via the CLI.

Development

# Build
cargo build

# Test
cargo test

# Validate bundled rules
cargo run -- validate --rules-dir rules/

# Compile a production bundle
cargo run -- compile --rules-dir rules/ --output build/marlinspike-malware-bundle.json --pretty

Adding Rules

  1. Choose the appropriate pack under rules/ (or create a new directory)
  2. Add rules following the YAML schema above
  3. Run cargo run -- validate --rules-dir rules/ to check for errors
  4. Ensure rule IDs are globally unique across all packs

Rule ID Convention

Rule IDs follow the pattern {category}-{family}-{description}:

c2-cobaltstrike-default-beacon-uri
rat-asyncrat-default-mutex
ics-triton-triconex-udp
loader-emotet-epoch4-c2
ransomware-lockbit-leak-site

License

marlinspike-malware is licensed under the GNU Affero General Public License v3.0 only. See LICENSE.

About

Shared Rust IOC and malware detection engine for the MarlinSpike & Fathom suites, evaluating observed network events against rule packs and emitting structured findings for MarlinSpike and Fathom.`

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages