Skip to content

Development

Build, test, and extend the Exploitmatic runtime.

Layout

cmd/exploitmatic/   CLI entry (solution + target -> result)
internal/model/      solution model
internal/parse/      plain text solution parser
internal/validate/   strict solution validation before execution
internal/transport/  protocol dispatch (http, https, websocket, tls, tcp, byte services, dns, process, file)
internal/assert/      contains / regex / flag / oob predicates
internal/oob/        out-of-band callback sink
internal/engine/     step loop, variable substitution, result reporting
solutions/           seed corpus (verified solutions)
examples/            host-scope examples (process, file)
grammar/             formal ANTLR grammar for the .txt language (Exm.g4, ExmLex.g4)
tools/exmcheck/      separate Go module: validates .txt files against the grammar

Build and test

From the cli directory:

go build -o exploitmatic.exe ./cmd/exploitmatic
go test ./...
go vet ./...

The grammar and exmcheck

grammar/Exm.g4 and grammar/ExmLex.g4 are the formal ANTLR grammar for the .txt language. tools/exmcheck is a separate Go module (its own go.mod, so the runtime stays stdlib-only) that validates .txt files against the grammar plus the semantic rules the runtime enforces, and tests that every corpus solution conforms. Regenerate and run it from cli:

cd grammar && .\generate.ps1          # regenerates tools/exmcheck/parser
cd ..\tools\exmcheck
go test ./...                          # grammar tests + the whole corpus
go run . ..\..\solutions\*.txt         # validate files on the command line

Design constraints

  • Solutions are data, never code. The corpus has no arbitrary-code supply chain: no template engine, no injected interpreter.
  • Go is the runtime language: single static binary, stdlib-only, no dependency tree.
  • Plain text solutions, no YAML: the format is line-based, validated at load, and there are no YAML aliases, anchors, or YAML CVEs.
  • The runtime prints the request and response and the test that ran, but never stores a result: the result always comes from the tests.
  • LLM-friendly by design: a closed eighteen-protocol grammar, a deterministic runtime, parse errors with line numbers, and stable result lines. Natural language is an authoring aid in front of the tool, never an input to the runtime.

Roadmap

  • M2: incident-derived corpus entries.
  • M3: replay-all(scope): run the whole corpus against a target, return only verified findings.
  • M4: model-agnostic surface (tool/MCP) so any agent calls replay().
  • M5: incident-ingestion pipeline: published timelines become verified corpus entries.

Write attacks down. Verify them.

Download the binary, point it at a target you own, and get a verified result. The corpus is open and the format is plain text.