Files
mukul975 8cae0648ec Add 55 new skills across 3 new domains + 6 undercovered areas (762 -> 817)
Demand-driven expansion targeting the fastest-growing 2025-2026 threat and
skills categories (ISC2/WEF/CrowdStrike/Mandiant signals):

- AI Security (NEW domain, 12 skills): LLM red-teaming with garak/PyRIT,
  prompt injection (direct/indirect/RAG), MCP tool-poisoning, agentic tool
  invocation, guardrails, model/data poisoning, system-prompt leakage,
  embedding/vector weaknesses, model extraction, continuous red-teaming
- Supply Chain Security (NEW domain, 5 skills): SBOMs, dependency confusion,
  malicious-npm triage, typosquatting, SLSA/Sigstore provenance
- Hardware & Firmware Security (NEW domain, 4 skills): CHIPSEC/UEFI audit,
  Secure Boot bypass, TPM measured-boot attestation, ESP bootkit hunting
- Identity (10): Entra ID/ROADtools, GraphRunner, AADInternals, ADCS/Certipy,
  shadow credentials, coercion, BloodHound CE, device-code phishing, SSO abuse
- Cloud-native (8): Stratus, Pacu, CloudFox, container escape, K8s RBAC,
  Falco, Trivy, kube-bench
- Offensive C2 (6): Sliver, Havoc, NetExec, DPAPI, NTLM relay ESC8, redirectors
- DFIR (6): Hayabusa, Chainsaw, KAPE, Velociraptor, EZ Tools, Plaso
- Backfill (4): OpenCTI, MISP, honeytokens, post-quantum crypto migration

Each skill follows the repo taxonomy (SKILL.md + references/{standards,api-reference}.md
+ scripts/agent.py + LICENSE), with researched real tool commands (no placeholders),
complete frontmatter, and ATT&CK/ATLAS + NIST CSF mappings. Updates README domain
table, skill count, and index.json.
2026-06-22 19:08:16 +02:00

131 lines
4.5 KiB
Python

#!/usr/bin/env python3
"""Hayabusa timeline helper.
Drives the Hayabusa binary to update rules and generate a CSV (and optionally
JSONL) forensic timeline from a directory of .evtx files, then summarizes the
detections by severity and top rule titles for fast triage.
"""
import argparse
import csv
import json
import os
import shutil
import subprocess
import sys
from collections import Counter
from datetime import datetime, timezone
def find_binary(explicit):
"""Locate the hayabusa binary."""
if explicit:
if os.path.isfile(explicit):
return explicit
sys.exit(f"[!] Binary not found: {explicit}")
for name in ("hayabusa", "hayabusa.exe"):
path = shutil.which(name)
if path:
return path
sys.exit("[!] hayabusa not found on PATH; pass --bin /path/to/hayabusa")
def run(cmd):
"""Run a subprocess and stream a short status line."""
print(f"[*] {' '.join(cmd)}")
proc = subprocess.run(cmd, capture_output=True, text=True)
if proc.returncode != 0:
print(proc.stderr[-1000:], file=sys.stderr)
return proc
def update_rules(binary):
run([binary, "update-rules"])
def csv_timeline(binary, src, out, profile, min_level, live):
cmd = [binary, "csv-timeline", "-o", out, "-p", profile,
"-m", min_level, "-w", "-U"]
cmd += ["-l"] if live else ["-d", src]
proc = run(cmd)
if not os.path.isfile(out):
sys.exit(f"[!] Timeline not produced. {proc.stderr[-500:]}")
return out
def json_timeline(binary, src, out, profile, min_level, live):
cmd = [binary, "json-timeline", "-L", "-o", out, "-p", profile,
"-m", min_level, "-w"]
cmd += ["-l"] if live else ["-d", src]
run(cmd)
return out
def summarize_csv(path):
"""Summarize a Hayabusa CSV timeline by level and rule title."""
levels, titles = Counter(), Counter()
total = 0
with open(path, newline="", encoding="utf-8", errors="replace") as f:
reader = csv.DictReader(f)
# Hayabusa columns include "Level" and "RuleTitle"
lvl_key = next((k for k in (reader.fieldnames or []) if k.lower() == "level"), None)
title_key = next((k for k in (reader.fieldnames or [])
if k.lower().replace(" ", "") == "ruletitle"), None)
for row in reader:
total += 1
if lvl_key:
levels[row.get(lvl_key, "")] += 1
if title_key:
titles[row.get(title_key, "")] += 1
return {"total_detections": total,
"by_level": dict(levels),
"top_rules": titles.most_common(15)}
def main():
p = argparse.ArgumentParser(description="Hayabusa timeline helper")
p.add_argument("-d", "--directory", help="Directory of .evtx files")
p.add_argument("--live", action="store_true", help="Live-analyze local logs")
p.add_argument("--bin", help="Path to hayabusa binary")
p.add_argument("-o", "--output", default="timeline.csv", help="CSV output path")
p.add_argument("--jsonl", help="Also write a JSONL timeline to this path")
p.add_argument("-p", "--profile", default="verbose",
help="Output profile (minimal/standard/verbose/...)")
p.add_argument("-m", "--min-level", default="medium",
choices=["informational", "low", "medium", "high", "critical"])
p.add_argument("--no-update", action="store_true", help="Skip update-rules")
p.add_argument("--report", help="Write JSON summary to this path")
args = p.parse_args()
if not args.live and not args.directory:
p.error("provide -d/--directory or --live")
binary = find_binary(args.bin)
if not args.no_update:
update_rules(binary)
csv_path = csv_timeline(binary, args.directory, args.output,
args.profile, args.min_level, args.live)
if args.jsonl:
json_timeline(binary, args.directory, args.jsonl,
args.profile, args.min_level, args.live)
summary = summarize_csv(csv_path)
summary["generated"] = datetime.now(timezone.utc).isoformat()
summary["timeline"] = csv_path
print(f"\n[+] {summary['total_detections']} detections")
print(f"[+] By level: {summary['by_level']}")
print("[+] Top rules:")
for title, count in summary["top_rules"]:
print(f" {count:5d} {title}")
if args.report:
with open(args.report, "w") as f:
json.dump(summary, f, indent=2)
print(f"[+] Summary written to {args.report}")
if __name__ == "__main__":
main()