SIS CLI

Query Guide

sis query reads an analysed file’s findings, structure, and content and returns one slice at a time. It is the forensic-extraction surface: predictable, composable, scriptable. Format is detected from content, so any supported root works — a .bin may resolve to HTML, RTF, OOXML, OneNote, MHT, OLE, LNK, PE/ELF, ISO/UDF, ZIP, or a standalone script.

Command shape

sis query <input> [query] [options]
  • Omit [query] to run the default top-level findings query.
  • --format accepts: text (default), json, jsonl, yaml, csv. (--json is a shorthand for --format json.)
  • Diagnostic WARN [NON-FATAL] ... lines go to stderr; the result goes to stdout. When scripting, read stdout and ignore stderr (e.g. 2>/dev/null).

The output envelope for --format json is { "file", "query", "result", ... }. For a findings query the findings live under .result.findings[], and each carries an id of the form sis-<64 hex> (see sis docs explain for how that ID is used).

Multi-format query namespaces

These run on any supported root:

sis query sample.docx                       # default findings query
sis query sample.docx findings --json
sis query sample.docx findings.composite --json    # correlated/composite findings only
sis query sample.hta chains --chain-summary events --json
sis query sample.one correlations --json
sis query sample.html urls --json           # extracted URLs
sis query sample.html iocs --json           # domains, URIs, IPs
sis query sample.js policy.active --json     # active policy provenance
sis query sample.zip policy.rules --json     # loaded rule inventory
sis query sample.js runtime.policy --json    # resolved runtime policy

PDF-only query namespaces

These require the PDF object graph. On a non-PDF root they return a structured scope error in the result envelope (error_code = QUERY_SCOPE_ERROR), not a crash.

sis query sample.pdf pages
sis query sample.pdf catalog
sis query sample.pdf trailer
sis query sample.pdf "object 45 0"
sis query sample.pdf xref.sections
sis query sample.pdf revisions.detail --where "anomaly_score >= 4"
sis query sample.pdf actions.chains --chain-summary events --json
sis query sample.pdf runtime.caps --json

actions.chains is the PDF object-graph PathFinder model. For general, multi-format chain triage use chains instead.

Some sub-namespaces of otherwise-multi-format queries are also PDF-only because they read the object graph — notably iocs.count.unique.by_family and urls.telemetry. The base iocs and urls queries are multi-format; their PDF-specific aggregations are not. If a sub-namespace returns QUERY_SCOPE_ERROR on a non-PDF root, fall back to the base query and aggregate the JSON downstream.

--where predicate grammar

Predicate filtering is supported on findings (and other finding-shaped namespaces). The grammar is deliberately small — use exactly these forms:

  • Comparison operators: ==, !=, >=, <=
  • Substring match: contains (e.g. kind contains 'html:')
  • Boolean connectives: and, or, not (case-insensitive)
  • String values use single quotes; numbers are bare.

There is no in [...] operator, no starts_with, and no bare < / >. Those error with Unexpected token in operator.

# severity / impact / confidence triage
sis query sample.bin findings --where "severity == 'High'" --json
sis query sample.bin findings --where "impact == 'Critical'" --json
sis query sample.bin findings --where "confidence == 'Strong' or confidence == 'Certain'" --json

# kind-family filter (use contains, not starts_with)
sis query sample.bin findings --where "kind contains 'html:'" --json
sis query sample.bin findings --where "not kind contains 'info'" --json

# numeric thresholds (PDF revisions example)
sis query sample.pdf revisions.detail --where "anomaly_score >= 4"

If a namespace rejects --where, filter the JSON output downstream instead.

Asset-path selectors (nested asset graph)

Beyond the finding-shaped namespaces, sis query addresses the file’s nested asset graph — the root plus every contained artefact (archive entries, email parts, embedded files, carved blobs, polyglot interpretations) — with an abbreviated-XPath selector:

sis query bundle.zip "**/[format=pe]"                    # any executable at any depth
sis query bundle.zip "zip:root/zip:doc.pdf/findings"     # findings on one member
sis query bundle.zip "**/[format=ooxml]/text"            # per-member safe-text (live only)
sis query bundle.zip "**/[format=pe]/sha256"             # per-member blake3 digest
sis query bundle.zip "**/[format=pe]/bytes" --extract-to /tmp/out   # carve members to disk
sis query doc.pdf   "**[polyglot=true]/views"            # polyglot interpretations
sis query "shape"   # (as a bare query) the asset-graph shape fingerprint

Selectors work live and over a saved report (--from-report report.json "<selector>"), except the byte-backed terminals (/text, /bytes) which need a live scan. /bytes is egress-gated: it refuses without --extract-to. The full grammar (segments, */**, predicate fields, terminals, polyglots) is in sis docs asset-graph.

Stream and artefact extraction (PDF)

sis query sample.pdf stream 8 0 --decode
sis query sample.pdf stream 8 0 --raw --extract-to /tmp/streams
sis query sample.pdf stream 8 0 --hexdump

Use only one of --raw, --decode, or --hexdump per invocation.

Interactive PDF

sis pdf repl <pdf> builds the parse context once and caches detector results across an interactive session. It is PDF-only. (sis repl is a deprecated alias.)

sis> findings
sis> :where severity == 'High'
sis> actions.chains
sis> :json
  • sis docs investigate — the end-to-end scan/query/report/explain playbook
  • sis docs explain — finding, format, and detection explanation surfaces
  • sis docs verdict — the report data model the queries slice into
  • sis docs asset-graph — the nested asset graph + asset-path selector grammar
  • sis docs shape — clustering files by asset-graph shape (campaign hunting)
  • ../query-interface.md, ../query-predicates.md