Zion Boggan zionboggan.com ↗

CI (lint/test/convert), coverage docs, readme

cafd5e9   Zion Boggan committed on May 29, 2026 (3 weeks ago)
.github/workflows/detections.yml +31 -0
@@ -0,0 +1,31 @@
+name: detections
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - run: pip install -r requirements.txt
+ - name: Lint Sigma rules
+ run: sigma check rules/
+ - name: Schema + ATT&CK tests
+ run: pytest -q
+ - name: Convert to Splunk / Elastic / Sentinel
+ run: python tools/convert.py
+ - uses: actions/upload-artifact@v4
+ with:
+ name: converted-queries
+ path: dist/
README.md +77 -0
@@ -0,0 +1,77 @@
+# Detection-as-Code
+
+Detection rules kept the way code is kept: written once in [Sigma](https://sigmahq.io/),
+version-controlled, linted and tested in CI, and compiled to whatever SIEM is in front of
+me. I spend my day tuning rules in Sentinel and Splunk by hand; this is that work done as a
+pipeline instead of a console click.
+
+Every rule here converts cleanly to **Splunk SPL**, **Elastic ES|QL**, and **Microsoft
+Sentinel / Defender KQL**, and is tagged to MITRE ATT&CK so coverage is something you can
+measure instead of guess at.
+
+## Why
+
+A detection written in one SIEM's query language is stranded there. Writing it in Sigma
+once and compiling it means the same logic ships to Splunk, Elastic, and Sentinel without
+re-deriving it - and the rule gets reviewed, diffed, and tested like any other code. The
+goal is fewer false positives and provable coverage, not more dashboards.
+
+## Layout
+
+```
+rules/
+ windows/ credential-access, execution, persistence, defense-evasion, initial-access
+ linux/ credential-access, execution, persistence
+tools/convert.py compile every rule to Splunk / Elastic / Sentinel
+tests/test_rules.py schema, ATT&CK tagging, unique IDs, correlation references
+.github/workflows/ lint -> test -> convert on every push
+dist/ generated queries (CI artifact; gitignored)
+```
+
+## The rules
+
+Ten detections across both platforms, each mapped to ATT&CK and tuned past the naive
+version (e.g. LSASS access filtered to the granted-access masks tooling actually uses, not
+the broad `0x1010`). Full table in [docs/coverage.md](docs/coverage.md).
+
+| Technique | Detection | Platform |
+|-----------|-----------|----------|
+| T1003.001 | Suspicious LSASS process access | Windows |
+| T1059.001 | PowerShell EncodedCommand | Windows |
+| T1566 / T1059.001 | Office spawns scripting host / LOLBin | Windows |
+| T1218.011 | Suspicious rundll32 | Windows |
+| T1543.003 | New service installed | Windows |
+| T1053.005 | Scheduled task created | Windows |
+| T1110 | SSH brute force (correlation) | Linux |
+| T1059.004 | Reverse shell one-liner | Linux |
+| T1543.002 | Systemd persistence | Linux |
+
+## Use it
+
+```bash
+pip install -r requirements.txt
+sigma check rules/ # lint
+pytest -q # schema + ATT&CK validation
+python tools/convert.py # compile to dist/{splunk,esql,kusto}/
+```
+
+Convert a single rule on the fly:
+
+```bash
+sigma convert -t splunk -p sysmon rules/windows/credential-access/T1003.001_lsass_memory_access.yml
+sigma convert -t kusto -p sysmon rules/windows/credential-access/T1003.001_lsass_memory_access.yml
+```
+
+`convert.py` picks the right processing pipeline per rule from its `logsource` (Sysmon for
+process/file telemetry, Windows-audit for Security/System channels). Correlation rules like
+the SSH brute force are compiled together with the base rule they reference - `make
+correlations` does that, since they need their referenced rule in the same collection.
+
+## Validation
+
+CI lints with `sigma check`, runs the schema/ATT&CK test suite, and compiles all rules to
+the three backends, failing on any conversion error. The rules themselves are validated
+*behaviourally* in the companion [purple-team lab](https://github.com/zionboggan) - Atomic
+Red Team fires each technique and the matching detection is confirmed in the Wazuh SIEM
+before a rule is promoted here. The Wazuh-native versions of several of these live in the
+[SOC automation lab](https://github.com/zionboggan/soc-automation-lab).
docs/coverage.md +31 -0
@@ -0,0 +1,31 @@
+# ATT&CK Coverage
+
+Every rule compiles to Splunk SPL, Elastic ES|QL, and Microsoft Sentinel KQL.
+
+| Tactic | Technique | Rule | Platform | Level |
+|--------|-----------|------|----------|-------|
+| Initial Access | T1566 Phishing | Office spawns scripting host / LOLBin | Windows | high |
+| Execution | T1059.001 PowerShell | PowerShell EncodedCommand | Windows | medium |
+| Execution | T1059.004 Unix Shell | Reverse shell one-liner | Linux | high |
+| Execution | T1047 / via parent | Office spawns scripting host / LOLBin | Windows | high |
+| Persistence | T1543.003 Windows Service | New service installed | Windows | high |
+| Persistence | T1053.005 Scheduled Task | Scheduled task created | Windows | medium |
+| Persistence | T1543.002 Systemd Service | Systemd persistence | Linux | medium |
+| Defense Evasion | T1218.011 Rundll32 | Suspicious rundll32 | Windows | high |
+| Credential Access | T1003.001 LSASS Memory | Suspicious LSASS access | Windows | high |
+| Credential Access | T1110 Brute Force | SSH brute force (correlation) | Linux | high |
+
+## Telemetry assumptions
+
+- **Windows process/file events:** Sysmon (config aligned to SwiftOnSecurity baseline) - the
+ Sysmon processing pipeline maps fields on conversion.
+- **Windows service/task events:** Security and System channels (4698, 7045) - Windows-audit
+ pipeline.
+- **Linux:** auth logs (sshd) and process/file telemetry (auditd or Sysmon-for-Linux).
+
+## Coverage notes
+
+This is a focused starter set covering the techniques that show up most in the alerts I
+triage day to day - credential dumping, phishing-to-execution, persistence, and brute force.
+It is deliberately small and high-signal rather than a dump of every public rule. New
+detections are added after they're validated against Atomic Red Team in the purple-team lab.