npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
Overview
Chainsaw is a fast, Rust-based forensic artifact search and hunting tool from WithSecure Labs. It provides first-response capability to rapidly identify threats within Windows Event Logs (.evtx) and other artifacts. Chainsaw can hunt with the full SigmaHQ rule corpus (translating Sigma to its internal Tau engine), run its own built-in detection rules, perform high-speed keyword/regex search across logs, and analyse specialized artifacts such as the AppCompatCache (shimcache), SRUM database, and event-log gaps. Output can be a colorized table, CSV, or JSON for downstream tooling.
Chainsaw's strength is speed and flexibility during initial triage: an analyst can drop a folder of collected EVTX onto the tool and get back a prioritized set of detections in seconds, then pivot with targeted search queries to confirm a hypothesis. Unlike a SIEM, it needs no ingestion pipeline, runs as a single binary, and works fully offline against acquired evidence — ideal for the field or an air-gapped analysis VM. The --mapping file tells Chainsaw how Sigma fields translate to Windows event fields, which is what enables broad Sigma coverage over EVTX.
A common hunt outcome is detecting suspicious PowerShell — MITRE ATT&CK T1059.001 (Command and Scripting Interpreter: PowerShell) — by running Sigma rules against PowerShell operational logs (Event ID 4104 script-block logging) or searching for encoded-command patterns. This skill maps to NIST CSF DE.AE-02 (potentially adverse events are analyzed to better understand associated activities).
When to Use
- During first-response triage to rapidly hunt threats across collected Windows event logs.
- When you need offline Sigma-based detection over
.evtxwithout standing up a SIEM. - To run fast keyword/regex searches confirming or refuting a hunt hypothesis.
- To analyse shimcache, SRUM, or event-log time gaps for execution evidence and tampering.
- To produce CSV/JSON detection output for reporting or pipeline ingestion.
Prerequisites
- Chainsaw binary. Download a release from GitHub or build from source:
# Build from source (Rust toolchain required) git clone https://github.com/WithSecureLabs/chainsaw.git cd chainsaw && cargo build --release ./target/release/chainsaw --version # or: nix profile install github:WithSecureLabs/chainsaw - The Chainsaw repo ships
mappings/(Sigma field mappings) andrules/(Chainsaw rules). - A copy of the SigmaHQ rules for full Sigma coverage:
git clone https://github.com/SigmaHQ/sigma.git - Collected Windows
.evtxfiles (and registry hives likeSYSTEM/Amcache.hvefor shimcache analysis).
Objectives
- Hunt collected EVTX with Sigma rules using the correct mapping file.
- Filter detections by rule level, status, and kind to reduce noise.
- Search logs by keyword, regex, and Tau expression for targeted confirmation.
- Output detections as table, CSV, and JSON.
- Analyse shimcache (with Amcache timestamp pairing), SRUM, and event-log gaps.
MITRE ATT&CK Mapping
| Technique ID | Official Name | Why Chainsaw Detects It |
|---|---|---|
| T1059.001 | Command and Scripting Interpreter: PowerShell | Sigma rules over EID 4104/4103 and search flag malicious PowerShell |
| T1059.003 | Command and Scripting Interpreter: Windows Command Shell | Process-creation Sigma rules surface suspicious cmd usage |
| T1547.001 | Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder | Sigma rules over registry events flag persistence |
| T1053.005 | Scheduled Task/Job: Scheduled Task | Rules over EID 4698/106 detect task creation |
| T1070.006 | Indicator Removal: Timestomp | analyse gaps and shimcache analysis reveal tampering/time gaps |
| T1204.002 | User Execution: Malicious File | Shimcache analysis shows executed binaries |
Workflow
1. Hunt EVTX with Sigma rules
Run the SigmaHQ corpus against collected logs using the bundled mapping file. The mapping translates Sigma fields to EVTX fields.
chainsaw hunt ./collected_evtx \
-s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml2. Hunt with Chainsaw built-in rules plus Sigma
Combine Chainsaw's own rules (-r) with Sigma (-s) for broader coverage.
chainsaw hunt ./collected_evtx \
-r ./rules \
-s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml3. Filter to reduce noise
Limit results by Sigma rule level, status, and detection kind.
chainsaw hunt ./collected_evtx -s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml \
--level high --status stable --kind evtx4. Output to CSV and JSON
Write structured output for reporting and pipelines.
# JSON to stdout/file
chainsaw hunt ./collected_evtx -s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml --json > detections.json
# CSV into a directory (one file per detection group)
chainsaw hunt ./collected_evtx -s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml --csv --output ./csv_out5. Targeted keyword and regex search
Confirm a hypothesis by searching raw events independent of rules.
# Case-insensitive keyword search
chainsaw search "mimikatz" -i ./collected_evtx
# Regex for base64-encoded PowerShell commands, as JSON
chainsaw search -e "-[Ee]nc(odedCommand)?\s+[A-Za-z0-9+/=]{20,}" ./collected_evtx --json
# Time-bounded search using a Tau expression
chainsaw search ./collected_evtx -t 'Event.System.EventID: =4624' \
--from "2026-06-01T00:00:00" --to "2026-06-20T00:00:00"6. Analyse shimcache for execution evidence
Parse the AppCompatCache from the SYSTEM hive, pair it with Amcache timestamps, and pattern-match suspicious entries.
chainsaw analyse shimcache ./SYSTEM \
--regexfile ./shimcache_patterns.txt \
--amcache ./Amcache.hve --tspair \
--output ./shimcache_analysis.csv7. Analyse SRUM and event-log gaps
Detect program/network usage and identify suspicious logging gaps (possible log clearing or timestomp).
# SRUM database analysis
chainsaw analyse srum --software ./SOFTWARE ./SRUDB.dat -o srum.json
# Event-log gaps that may indicate cleared/tampered logs
chainsaw analyse gaps ./collected_evtx --min-time-gap-minutes 30 --json8. Dump and lint
Inspect raw artifact content and validate custom rules before a hunt.
chainsaw dump ./SOFTWARE --json --output dump.json
chainsaw lint -r ./rules --kind sigmaTools and Resources
| Tool | Purpose | Source |
|---|---|---|
| Chainsaw | Fast EVTX/artifact hunting and search | https://github.com/WithSecureLabs/chainsaw |
| SigmaHQ rules | Community detection rules | https://github.com/SigmaHQ/sigma |
| Chainsaw mappings | Sigma-to-EVTX field mappings | https://github.com/WithSecureLabs/chainsaw/tree/master/mappings |
| Hayabusa | Alternative Sigma EVTX timeline tool | https://github.com/Yamato-Security/hayabusa |
| Timeline Explorer | Review CSV output | https://ericzimmerman.github.io/ |
Validation Criteria
- Chainsaw binary installed and
--versionconfirmed. - SigmaHQ rules and the correct mapping file available.
- Sigma hunt run against the collected EVTX directory.
- Chainsaw built-in rules combined with Sigma where appropriate.
- Detections filtered by level/status/kind to reduce noise.
- CSV and/or JSON output produced for reporting.
- Targeted keyword/regex/Tau searches run to confirm findings.
- Shimcache analysed with Amcache timestamp pairing.
- SRUM and event-log-gap analysis performed where artifacts exist.
- Findings (e.g., PowerShell T1059.001) documented for the hunt report.
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 2
api-reference.md2.2 KB
Chainsaw — Command & Flag Reference
Subcommands
| Command | Purpose |
|---|---|
hunt |
Detect threats using Sigma and Chainsaw rules |
search |
Keyword/regex/Tau search across artifacts |
analyse |
shimcache / srum / gaps artifact analysis |
dump |
Dump raw artifact content |
lint |
Validate rule files |
hunt Flags
| Flag | Description |
|---|---|
-s, --sigma <DIR> |
SigmaHQ rules directory |
-r, --rule <DIR> |
Chainsaw rules directory |
-m, --mapping <FILE> |
Sigma->event field mapping (e.g. mappings/sigma-event-logs-all.yml) |
--level <LEVEL> |
Filter by Sigma rule level |
--status <STATUS> |
Filter by rule status (e.g. stable) |
--kind <KIND> |
Filter by detection kind (e.g. evtx) |
--json / --csv |
Output format |
-o, --output <PATH> |
Output file/directory |
chainsaw hunt ./evtx -s ./sigma/rules \
--mapping ./mappings/sigma-event-logs-all.yml --level high --jsonsearch Flags
| Flag | Description |
|---|---|
-e, --regex <RE> |
Regex pattern |
-i, --ignore-case |
Case-insensitive |
-t, --tau <EXPR> |
Tau expression query |
--from / --to |
Timestamp bounds |
--json |
JSON output |
chainsaw search "mimikatz" -i ./evtx
chainsaw search -e "-enc\s+[A-Za-z0-9+/=]{20,}" ./evtx --json
chainsaw search ./evtx -t 'Event.System.EventID: =4624'analyse Subcommands
# Shimcache with Amcache timestamp pairing
chainsaw analyse shimcache ./SYSTEM --regexfile ./patterns.txt \
--amcache ./Amcache.hve --tspair --output ./out.csv
# SRUM database
chainsaw analyse srum --software ./SOFTWARE ./SRUDB.dat -o srum.json
# Event-log gaps
chainsaw analyse gaps ./Logs/ --min-time-gap-minutes 30 --jsondump / lint
chainsaw dump ./SOFTWARE --json --output dump.json
chainsaw lint -r ./rules --kind sigmaInstall
git clone https://github.com/WithSecureLabs/chainsaw.git
cd chainsaw && cargo build --release
# or: nix profile install github:WithSecureLabs/chainsawExternal References
standards.md1.7 KB
Standards and References — Hunting EVTX with Chainsaw
MITRE ATT&CK References
| Technique ID | Name | Tactic | Rationale |
|---|---|---|---|
| T1059.001 | Command and Scripting Interpreter: PowerShell | Execution | Sigma rules over EID 4104/4103 and search flag malicious PowerShell |
| T1059.003 | Command and Scripting Interpreter: Windows Command Shell | Execution | Process-creation Sigma rules surface suspicious cmd usage |
| T1547.001 | Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder | Persistence | Registry-event Sigma rules flag persistence |
| T1053.005 | Scheduled Task/Job: Scheduled Task | Execution / Persistence | Rules over EID 4698/106 detect task creation |
| T1070.006 | Indicator Removal: Timestomp | Defense Evasion | analyse gaps and shimcache reveal time tampering |
| T1204.002 | User Execution: Malicious File | Execution | Shimcache analysis shows executed binaries |
NIST Cybersecurity Framework 2.0
| ID | Name | Rationale |
|---|---|---|
| DE.AE-02 | Potentially adverse events are analyzed to better understand associated activities | Chainsaw hunts/searches analyze event-log activity to characterize threats |
Detection Standards
- Sigma generic signature format: https://github.com/SigmaHQ/sigma
- Chainsaw mappings (Sigma->EVTX): https://github.com/WithSecureLabs/chainsaw/tree/master/mappings
Official Resources
- Chainsaw GitHub: https://github.com/WithSecureLabs/chainsaw
- WithSecure Labs research: https://labs.withsecure.com/
- MITRE ATT&CK T1059.001: https://attack.mitre.org/techniques/T1059/001/
Key Research
- WithSecure Labs: Chainsaw release announcements (shimcache, SRUM, gaps analysers)
- SigmaHQ community detection rule corpus
Scripts 1
agent.py4.7 KB
#!/usr/bin/env python3
"""Chainsaw EVTX hunting helper.
Drives the Chainsaw binary to run a Sigma+Chainsaw hunt over a directory of
.evtx files, emits JSON, and summarizes detections by rule and level. Can also
run a targeted keyword/regex search to confirm a hypothesis.
"""
import argparse
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 chainsaw binary."""
if explicit:
if os.path.isfile(explicit):
return explicit
sys.exit(f"[!] Binary not found: {explicit}")
for name in ("chainsaw", "chainsaw.exe"):
path = shutil.which(name)
if path:
return path
# common build location
local = os.path.join("target", "release", "chainsaw")
if os.path.isfile(local):
return local
sys.exit("[!] chainsaw not found; pass --bin /path/to/chainsaw")
def run_json(cmd):
"""Run a chainsaw command expected to emit JSON on stdout."""
print(f"[*] {' '.join(cmd)}", file=sys.stderr)
proc = subprocess.run(cmd, capture_output=True, text=True)
if proc.returncode != 0 and not proc.stdout.strip():
print(proc.stderr[-1500:], file=sys.stderr)
sys.exit(f"[!] chainsaw exited {proc.returncode}")
try:
return json.loads(proc.stdout)
except json.JSONDecodeError:
return []
def hunt(binary, evtx, sigma, mapping, rules, level, status):
cmd = [binary, "hunt", evtx, "-s", sigma, "--mapping", mapping, "--json"]
if rules:
cmd += ["-r", rules]
if level:
cmd += ["--level", level]
if status:
cmd += ["--status", status]
return run_json(cmd)
def search(binary, evtx, pattern, regex, ignore_case):
cmd = [binary, "search"]
if regex:
cmd += ["-e", pattern]
else:
cmd += [pattern]
if ignore_case:
cmd += ["-i"]
cmd += [evtx, "--json"]
return run_json(cmd)
def summarize(detections):
"""Summarize Chainsaw hunt JSON by rule name and level."""
rules, levels = Counter(), Counter()
total = 0
for group in detections:
# Chainsaw JSON groups detections; each carries name/level metadata
name = group.get("name") or group.get("group") or "unknown"
level = group.get("level", "unknown")
docs = group.get("document") or group.get("documents") or [group]
n = len(docs) if isinstance(docs, list) else 1
total += n
rules[name] += n
levels[level] += n
return {"total_hits": total,
"by_level": dict(levels),
"top_rules": rules.most_common(15)}
def main():
p = argparse.ArgumentParser(description="Chainsaw EVTX hunting helper")
p.add_argument("evtx", help="Directory or file of .evtx logs")
p.add_argument("--bin", help="Path to chainsaw binary")
p.add_argument("-s", "--sigma", help="SigmaHQ rules directory (for hunt)")
p.add_argument("--mapping", help="Sigma->event mapping yml (for hunt)")
p.add_argument("-r", "--rules", help="Chainsaw rules directory")
p.add_argument("--level", help="Filter by Sigma level (e.g. high)")
p.add_argument("--status", help="Filter by rule status (e.g. stable)")
p.add_argument("--search", dest="search_pattern", help="Run a search instead of a hunt")
p.add_argument("--regex", action="store_true", help="Treat --search as a regex")
p.add_argument("-i", "--ignore-case", action="store_true")
p.add_argument("--report", help="Write JSON output to this path")
args = p.parse_args()
binary = find_binary(args.bin)
if args.search_pattern:
results = search(binary, args.evtx, args.search_pattern,
args.regex, args.ignore_case)
out = {"mode": "search", "pattern": args.search_pattern,
"hits": len(results) if isinstance(results, list) else 0}
print(f"[+] search hits: {out['hits']}")
else:
if not (args.sigma and args.mapping):
p.error("hunt mode requires --sigma and --mapping")
results = hunt(binary, args.evtx, args.sigma, args.mapping,
args.rules, args.level, args.status)
out = summarize(results)
out["mode"] = "hunt"
print(f"[+] {out['total_hits']} hits across {len(out['top_rules'])} rules")
print(f"[+] By level: {out['by_level']}")
for name, count in out["top_rules"]:
print(f" {count:5d} {name}")
out["generated"] = datetime.now(timezone.utc).isoformat()
if args.report:
with open(args.report, "w") as f:
json.dump({"summary": out, "raw": results}, f, indent=2)
print(f"[+] Report written to {args.report}")
if __name__ == "__main__":
main()