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
| Prefix | Meaning | Example |
|---|---|---|
| (bare hex) | MD5 / SHA1 / SHA256, auto-detected by length | 0123...def |
hash: md5: sha1: sha256: | Hash, with list support | hash:[aaa,bbb,ccc] |
imphash: | Import hash | imphash:deadbeef |
size: | File size in bytes | size:1000+ |
magic: | File type (EXE, ELF, MACHO, PDF, ZIP, …) | magic:[EXE,ELF] |
mime: | MIME type contains | mime:application/pdf |
signed: | Authenticode: VALID, INVALID, UNSUPPORTED | signed:VALID |
PE collapse.
magic:EXEcovers 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
| Prefix | Meaning |
|---|---|
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
| Prefix | Meaning | Example |
|---|---|---|
p: | MalEval verdict | p:true (or bare p), !p |
opinion: | Stairwell verdict: MALICIOUS, BENIGN, TRUSTED, GRAYWARE, SUSPICIOUS, NO_OPINION | opinion:[MALICIOUS,SUSPICIOUS] |
mallabel: | MalEval label | mallabel: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
| Prefix | Meaning | Example |
|---|---|---|
asset: / a: | Asset name or ID, auto-detected | asset:DESKTOP-123 |
an: | Asset name (explicit) | an:[host1,host2] |
ac: / ar: | Asset name contains / regex | ar:^wks-[0-9]+$ |
objenv: / oe: | Environment ID or name, auto-detected | oe:Production |
oac: / ogac: | Asset count for the object — your envs / global | oac:5+ |
Asset name lookups are substring matches.
an:host1also matcheshost10andmyhost1. For a true exact match, anchor with regex:ar:^host1$.
Rules, reports, network, tags
| Prefix | Meaning | Example |
|---|---|---|
yara: | YARA rule name (exact, list) | yara:[Emotet,Trickbot] |
yr: | YARA rule name regex | yr:^APT |
tr: | Threat report | tr:APT123 |
ip: | IP address (exact, list) | ip:[1.2.3.4,5.6.7.8] |
host: | Hostname contains | host:evil.com |
wk | Well-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:criticalwon'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 cparses asa 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].
