LOKI / signature-base Pull Florian Roth's IOC + YARA corpus — the rule set that powers LOKI, Loki-RS, and THOR Lite — into digger's existing detector pipeline.
What it brings
The Neo23x0/signature-base repository is the open-source community IOC + YARA corpus that powers Florian Roth's LOKI scanner family. It contains:
- ~3000 YARA rules covering malware families, hack tools, ransomware, exploits, anomalies, and threat-actor toolkits
- Filename IOCs — regex patterns matching disk paths associated with known tradecraft
- Hash IOCs — MD5 / SHA-1 / SHA-256 of known-bad files
- C2 IOCs — IPs, domains, and URLs
- False-positive lists to suppress noise
digger consumes signature-base in three ways:
- YARA detector
- The existing
yaradetector automatically loads everysignature-base/yara/*.yarfile when signature-base is present, in addition to its bundled baseline rules. - LokiStyleDetector
- A dedicated detector (
digger.loki.LokiStyleDetector) consumes the IOC files directly: filename regex matches against process exes and recent files, hash matches against process exe hashes, C2 matches against network connections and browser history. - Loki binary bridge
- If you have an installed LOKI / Loki-RS binary,
digger.loki.run_loki_binary()can call it for parity with existing LOKI workflows.
Getting signature-base
# Clone (or fast-forward update) signature-base
digger loki update
# Check what was loaded
digger loki status
# signature-base at /Users/you/.cache/digger/signature-base
# filename_iocs 84
# hash_iocs 2104
# c2_iocs 1320
# false_positive_hashes 97
# yara_rule_files 2876
Default path is ~/.cache/digger/signature-base/. Override with
--target or with the DIGGER_SIGNATURE_BASE_DIR
environment variable.
The updater uses git when available (shallow clone, then
fast-forward pull on subsequent runs) and falls back to an HTTPS tarball
download otherwise.
Running the detector
Once signature-base is present, every digger scan picks it
up automatically. To run just the LOKI-style checks against an existing
case:
digger loki scan --case-dir ./case-1
# loki: 7 findings
Or programmatically:
from digger.loki import LokiStyleDetector
from digger.core import EvidenceStore
store = EvidenceStore("./case-1")
n = LokiStyleDetector().run(store)
print(f"{n} loki findings")
store.close()
What gets matched
| signature-base file | Matched against | Detector outputs |
|---|---|---|
iocs/hash-iocs.txt | processes.data.exe_sha256 (computed by the process collector). On demand we also hash with MD5 / SHA-1 if those kinds appear in the IOC set. | Severity scaled from the LOKI 0-100 score (≥80 critical, ≥60 high, ≥40 medium, ≥20 low). MITRE T1204.002. |
iocs/filename-iocs.txt | Process exe paths and every path in recent_files entries. | Severity from LOKI score. MITRE T1036. |
iocs/c2-iocs.txt | Established network connections (IP), browser history (domains, URLs). | Severity from LOKI score. MITRE T1071. |
iocs/falsepositive-iocs.txt | Used to suppress hash matches that would otherwise fire. | — |
yara/*.yar | Compiled and merged into the existing yara detector. Matches against process exes and recent files. | Native YARA findings. |
Filename anomaly checks (LOKI-style)
Even without signature-base, the Loki detector contributes two filename anomaly checks LOKI is known for:
- Double extensions — files matching
*.pdf.exe,*.doc.scr,*.jpg.com, and friends. Classic dropper masquerade (MITRE T1036.007). - Right-to-Left override trickery — filenames containing
U+202E (or related directional-override codepoints) that make
resume[U+202E]fdp.exerender asresumeexe.pdf(MITRE T1036.002).
These fire regardless of whether signature-base is installed.
Severity mapping
signature-base rules carry a 0-100 "score" that LOKI uses as a threshold. digger maps that to its five-level severity:
| LOKI score | digger severity |
|---|---|
| ≥ 80 | critical |
| ≥ 60 | high |
| ≥ 40 | medium |
| ≥ 20 | low |
| < 20 | info |
Calling an installed LOKI binary
If you have loki, loki-rs, or Loki.py
on PATH, you can invoke it directly:
from digger.loki import run_loki_binary
result = run_loki_binary("/etc")
print(result.stdout[:1000])
print("return code:", result.return_code)
Useful when you want full LOKI features (auto-update of signatures via their own upgrader, scanning of process memory on supported platforms, ARCHIVE-FILE matching) without re-implementing them in digger.
Post-quantum integrity of the corpus
The threat-intel rule corpus is itself a target. An attacker who can
write to your signature-base/ on disk (supply-chain attack,
malicious co-tenant, compromised account) can corrupt the corpus —
rewriting rules to miss the malware they care about, or
poisoning rules to fire false positives on your tooling. HTTPS pull
covers transport, but says nothing about the integrity of bytes already
on disk.
digger ships a defense-in-depth layer: after a successful
digger loki update, you can compute a dual SHA-256 +
SHA3-256 tree-hash of the corpus and PQC-sign it with your operator
key. Every subsequent use of the corpus verifies the signature first.
# One-time: generate an operator signing key (or reuse the one you
# already created for `digger pqc sign`)
python -c "
from digger.crypto import PQCBackend
b = PQCBackend(sig_alg='ML-DSA-65')
pk, sk = b.generate_signing_key()
open('operator.sk', 'wb').write(sk)
open('operator.sk.pub', 'wb').write(pk)
"
# Update + sign in one step
digger loki update --sign-key ./operator.sk
# …or sign retroactively after an existing update
digger loki sign --key ./operator.sk
# Verify any time
digger loki verify
# [VERIFIED] /Users/you/.cache/digger/signature-base
# algorithm: ML-DSA-65
# current sha256_root: 4b3f9d…
# current sha3_256_root: e1c0a2…
# Schedule auto-signing on every cron pull
DIGGER_LOKI_SIGN_KEY=/secrets/operator.sk \
digger --no-banner loki update
The LokiStyleDetector verifies the signature on every run. Tampered
corpora emit a critical finding
("signature-base corpus integrity violation", MITRE T1554) and the
detector refuses to use the rules until the corpus is re-pulled and
re-signed. Unsigned corpora log a warning by default; set
DIGGER_LOKI_STRICT=1 to refuse unsigned corpora entirely.
Does PQC actually matter here?
For the IOC hashes themselves in signature-base (SHA-256, SHA-1, MD5) — no. Grover's quantum search halves preimage resistance, so SHA-256 still provides 128-bit security against quantum attack; SHA-1 and MD5 are already broken classically and you should treat them accordingly anyway.
For the integrity of the corpus itself — yes. "Harvest now, decrypt later" doesn't apply to public rule data (confidentiality isn't the concern), but "harvest now, forge later" applies to any classical signature over data you're going to trust years from now. By signing with ML-DSA-65 (FIPS 204) today, the corpus snapshot's integrity is durable across that horizon. Same reasoning as the dual SHA-256 + SHA3-256 evidence chain.
Keeping it fresh
signature-base receives near-daily commits. Schedule:
# crontab — every 6 hours, auto-sign with the operator key
0 */6 * * * DIGGER_LOKI_SIGN_KEY=/secrets/operator.sk \
digger --no-banner loki update >/var/log/digger-loki-update.log 2>&1
Credit
signature-base is the work of Florian Roth and many contributors. If your organization gets defensive value out of LOKI / Loki-RS via this integration, support Nextron Systems and the signature-base maintainers.