StairQL - A New Way to Query

StairQL is a compact, prefix-driven search language for the Stairwell platform. A query is a sequence of prefix:value terms joined by an implicit AND — easy to type, easy to share, easy to read in a runbook.

📘

StairQL is available to organizations that have the feature enabled. To request access, contact [email protected].

Quick example

p:true fs:today asset:DESKTOP-123

→ "Malicious files first seen today on asset DESKTOP-123." Space-separated terms are AND'd together. Group with parentheses, OR with OR or ||, negate with !, and use lists [a,b,c] for same-field OR.

Prefix reference

Files and hashes

PrefixMeaningExample
(bare hex)MD5 / SHA1 / SHA256, auto-detected by length0123...def
hash: md5: sha1: sha256:Hash, with list supporthash:[aaa,bbb,ccc]
imphash:Import hashimphash:deadbeef
size:File size in bytessize:1000+
magic:File type (EXE, ELF, MACHO, PDF, ZIP, …)magic:[EXE,ELF]
mime:MIME type containsmime:application/pdf
signed:Authenticode: VALID, INVALID, UNSUPPORTEDsigned:VALID
🚧

PE collapse. magic:EXE covers every Portable Executable variant — .exe, .dll, .sys, .ocx, etc. To narrow to a sub-type, combine with a filename suffix: magic:EXE few:\.dll.

Filename and path

PrefixMeaning
fc: / pc:Filename / path contains (substring, case-insensitive)
fr: / pr:Filename / path matches regex
fsw: / few:Filename starts / ends with
psw: / pew:Path starts / ends with
fc:malware                  # contains "malware"
pc:`C:\Windows\System32`    # backticks: literal backslashes
fr:evil.*\.exe              # regex
few:\.exe                   # ends with literal ".exe" — escape the dot,
                            # otherwise `.` matches any character

contains prefixes treat regex metacharacters literally; use fr:/pr: for regex semantics.

Time

fs: is global first-seen across the platform; envfs: is first-seen in your environment. Dates are UTC. + means at-or-after, - means at-or-before.

fs:today                # first seen today
fs:7d+                  # last 7 days (also 24h+, 30m+, 2w+)
fs:2024-01-01+          # on or after that day
fs:7d+ fs:5d-           # between 5 and 7 days ago
envfs:7d+               # first time *you* saw it, last 7 days

Maliciousness

PrefixMeaningExample
p:MalEval verdictp:true (or bare p), !p
opinion:Stairwell verdict: MALICIOUS, BENIGN, TRUSTED, GRAYWARE, SUSPICIOUS, NO_OPINIONopinion:[MALICIOUS,SUSPICIOUS]
mallabel:MalEval labelmallabel:Emotet
bucket: / prob:Probability bucket: VERY_HIGH > HIGH > MEDIUM > LOW. Range-only — always needs + or -bucket:HIGH+

Note: p:true reflects MalEval only, not opinions you've set manually. Combine explicitly: p:true OR opinion:MALICIOUS.

Assets and environments

PrefixMeaningExample
asset: / a:Asset name or ID, auto-detectedasset:DESKTOP-123
an:Asset name (explicit)an:[host1,host2]
ac: / ar:Asset name contains / regexar:^wks-[0-9]+$
objenv: / oe:Environment ID or name, auto-detectedoe:Production
oac: / ogac:Asset count for the object — your envs / globaloac:5+
🚧

Asset name lookups are substring matches. an:host1 also matches host10 and myhost1. For a true exact match, anchor with regex: ar:^host1$.

Rules, reports, network, tags

PrefixMeaningExample
yara:YARA rule name (exact, list)yara:[Emotet,Trickbot]
yr:YARA rule name regexyr:^APT
tr:Threat reporttr:APT123
ip:IP address (exact, list)ip:[1.2.3.4,5.6.7.8]
host:Hostname containshost:evil.com
wkWell-known file!wk to exclude
ot: / at: / rt:Object / asset / rule tag (exact)at:critical
🚧

Tags are case-sensitive. If you tagged something Critical, at:critical won't match — use the exact case you applied.

PE metadata

For PE binaries: pdb: company: product: filedesc: intname: origname: are substring matches; version: is exact with +/- ranges (semver-aware); export: impdll: impfunc: rich: are exact with list support.

company:Microsoft version:1.0.0+
magic:EXE impdll:kernel32.dll impfunc:CreateRemoteThread

Combining terms

p:true fs:today                       # implicit AND (explicit AND also works)
tr:APT1 OR yara:APT1_Loader           # OR, or the || symbol
(yara:APT1 AND fs:today) OR p:true    # parentheses for grouping
!fc:safe                              # ! negates a term
!an:[A1,B2,C3]                        # none of these
  • AND binds tighter than OR (same as SQL): a OR b AND c parses as a OR (b AND c).
  • Lists are exact-match only. Contains/regex prefixes reject [a,b] — use OR instead: fc:`.sys` OR fc:`.exe` .
  • Operators inside quotes are never split: fc:"foo OR bar" is one substring.

Quoting

When in doubt, use backticks. `...` is a raw literal — every character is taken verbatim, including backslashes. Ideal for Windows paths and regex:

pc:`C:\Windows\System32`
psw:`\\server\share`
fr:`evil\.exe`

"..." and '...' also work and support escapes (\", \\). Quote multi-word values: fc:"evil file". Most fields are case-insensitive — type values the way they look in the UI (tags are the exception).

Examples

pc:`Windows\System32` few:\.exe !wk          # suspicious executables in system folders
yara:Emotet oac:5+                           # rule match, on 5+ of your assets
hash:[aaa,bbb,ccc] fs:5d+                    # any of these hashes, last 5 days
!an:[A1,B2,C3] fs:today                      # today, excluding known-good assets
p:true envfs:7d+ ar:^WKS-                    # new malicious files on WKS- hosts
magic:EXE impdll:kernel32.dll !signed:VALID  # unsigned PEs importing kernel32

Current limitations

Not yet supported: bare environment-scoped rule queries ("any rule in environment X"), negated regex (!fr:, !pr:), case-insensitive tag matching, and last-seen timestamps (first-seen only). If any of these block your team, let us know at [email protected].