StairQL Reference

Every StairQL prefix, the values each one accepts, and the rules for combining terms. The page to open when you are halfway through a query.

This page lists every StairQL prefix, the values each one accepts, and the rules for combining terms. It is a lookup page. If you are learning the language, read StairQL first and come back here for the field you cannot remember.

StairQL is in beta. The syntax is still evolving, so a prefix or an accepted value can change between releases. If a field you need is missing, tell us at [email protected].

Every prefix, alphabetically

Most prefixes have a short form and a spelled-out long form, and the two are interchangeable. "List" means the prefix accepts the [a,b,c] any-of form.

PrefixLong formMatchesList
a:asset:Asset name or ID, detected from the operandyes
ac:assetcontains:Asset name containsno
an:assetname:Asset nameyes
ar:assetregex:Asset name matches a regular expressionno
asset:Asset name or ID, detected from the operandyes
at:assettag:Asset tag, exactno
bucket:prob:Likelihood band, range onlyno
company:companyname:PE company name containsno
envfs:envfirstseen:First seen in your environmentno
export:exportfunction:PE export function, exactyes
fc:filecontains:Filename containsno
few:fileendswith:Filename ends withno
filedesc:filedescription:PE file description containsno
fr:fileregex:Filename matches a regular expressionno
fs:firstseen:First seen anywhere Stairwell can seeno
fsw:filestartswith:Filename starts withno
hash:MD5, SHA1, or SHA256yes
host:hostname:Hostname containsno
impdll:importdll:PE imported DLL, exactyes
impfunc:importfunction:PE imported function, exactyes
imphash:Import hash, exactyes
intname:internalname:PE internal name containsno
ip:ipaddress:IP address, exactyes
magic:magicnumber:File type, exactyes
mallabel:Verdict label, exactyes
md5:A hash. Searches all three hash fieldsyes
mime:mimetype:MIME type containsyes
oac:objectassetcount:How many of your assets hold the fileno
objenv:oe:The file's environment, by ID or nameIDs only
ogac:objectglobalassetcount:How many assets hold the file globallyno
opinion:Your team's recorded verdict, exactyes
origname:originalfilename:PE original filename containsno
ot:objecttag:Object tag, exactyes
pThe automated verdict. p, p:true, p:false, !pno
pc:pathcontains:Path containsno
pdb:pdbfilename:PE PDB filename containsno
pdbr:pdbregex:PE PDB filename matches a regular expressionno
pew:pathendswith:Path ends withno
pr:pathregex:Path matches a regular expressionno
product:productname:PE product name containsno
psw:pathstartswith:Path starts withno
rich:richheaderhash:PE rich header hash, exactyes
rt:ruletag:Rule tag, exactno
sha1:A hash. Searches all three hash fieldsyes
sha256:A hash. Searches all three hash fieldsyes
signed:Signature verification result, exactyes
size:File size in bytesno
tr:threatreport:Threat report, one at a timeno
version:productversion:PE product version, exact or rangeyes
wkwellknownWell-known filesno
yara:YARA rule name, exactyes
yr:yararegex:YARA rule name matches a regular expressionno

Hashes

A bare hex string of 32, 40, or 64 characters is recognized as a hash without any prefix, and is matched across all three indexed hash fields.

0123456789abcdef0123456789abcdef             # MD5
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa     # SHA1
aaaa...64 chars total...aaaa                 # SHA256

The prefixed forms hash:, sha256:, sha1:, and md5: behave identically to the bare form and to each other. Each one searches all three hash fields, so the prefix you pick is a readability choice rather than a filter. All four accept a list.

hash:[aaa,bbb,ccc]                # any of these three, any algorithm
sha256:[abc,def,123]
hash:[a,b,c] fs:5d+               # any of these, first seen in the last 5 days

Import hash is a separate field.

imphash:deadbeef
imphash:[deadbeef,cafebabe,face1234]

File size

size: takes a whole number of bytes. A trailing + means at least, a trailing - means at most. Units such as KB are not accepted.

FormMeaning
size:1000Exactly 1000 bytes
size:1000+1000 bytes or larger
size:1000-1000 bytes or smaller

Time

fs: (long form firstseen:) matches the time the file was first seen anywhere Stairwell can see. All dates are read as UTC. For the time a file first appeared in your own environment, use envfs:.

OperandMeaning
fs:todayFirst seen today, 00:00 to 24:00 UTC
fs:today+At or after today 00:00
fs:today-At or before today 00:00
fs:yesterdayFirst seen yesterday
fs:2024-01-01First seen on exactly that day
fs:2024-01-01+On or after that day
fs:2024-01-01-On or before that day
fs:7d+Within the last 7 days
fs:5d-More than 5 days ago
fs:2w+Within the last 2 weeks
fs:24h+Within the last 24 hours
fs:30m+Within the last 30 minutes

The relative units are m for minutes, h for hours, d for days, and w for weeks. There is no month or year unit; use an absolute date for those.

Two terms give you a window, because terms are combined with AND:

fs:7d+ fs:5d-          # between 5 and 7 days ago

Filename and path

PrefixLong formMatch style
fc:filecontains:Filename contains, substring, case-insensitive
pc:pathcontains:Path contains
fr:fileregex:Filename matches a regular expression
pr:pathregex:Path matches a regular expression
fsw:filestartswith:Filename starts with, anchored as ^str
few:fileendswith:Filename ends with, anchored as str$
psw:pathstartswith:Path starts with
pew:pathendswith:Path ends with
fc:malware                  # contains "malware"
fc:"evil file"              # quote multi-word substrings
pc:Windows                  # path contains "Windows"
pc:`C:\Windows\System32`    # backticks pass backslashes through unchanged
fr:evil.*\.exe              # regular expression
pr:`C:\Program Files\.*`    # regular expression over a Windows path
fsw:svc                     # filename starts with "svc"
few:\.exe                   # filename ends with a literal ".exe"

Two things to know:

  • The contains prefixes are literal. Regular expression metacharacters in the operand are matched as themselves. Use fr: or pr: when you want pattern semantics.
  • A bare dot in few: and pew: is a wildcard, because those prefixes anchor a regular expression. few:.exe matches .exe, aexe, and Xexe. Escape it to match a literal dot: few:\.exe.

Assets

asset: (short form a:) is the umbrella prefix. If the operand has the shape of an asset ID and decodes as one, it matches the ID; anything else matches the asset name.

asset:desktop-01                # name or ID, detected from the operand
asset:"Windows Server"          # multi-word, quoted, so it matches a name
asset:[host1,host2,host3]       # any of these
a:desktop-01                    # short alias

List elements have to be all names or all IDs. A mixed list is an error.

PrefixLong formMatch style
an:assetname:Asset name, list supported
ac:assetcontains:Asset name contains
ar:assetregex:Asset name matches a regular expression
an:desktop-01                # asset name, forced, even for an ID-shaped string
an:"Windows Server"
an:[s1,s2,s3]
ac:malware                   # asset name contains "malware"
ar:^wks-[0-9]+$              # asset name matches this pattern

Asset name lookups are substring matches, including the ones that look exact. an:host1 also matches host10 and myhost1. For a true exact match, anchor a pattern instead: ar:^host1$.

For "how many assets is this file on", see Object metadata.

Environments

objenv: (short form oe:) matches the environment the file was seen in. An operand shaped like an environment ID matches the ID; anything else matches the environment name. Name matching is case-insensitive.

objenv:Production                # by name
objenv:"Prod West"               # multi-word name, quoted
oe:Production                    # short alias

The list form takes IDs only. Environment names have no any-of form, so use OR for several names.

objenv:[ID1,ID2,ID3]                        # any of these environments
objenv:Production OR objenv:Staging         # names, joined with OR

You do not need an ID to write a query. Match your own environments by name, which is the name you see in the environment picker, and read the ID off the Environments page in Stairwell when you want to pin a saved query to one for good.

Stairwell's own shared environments are the exception, because their IDs are the same for every customer:

EnvironmentID
VirusShare6HP5R3-ZM7DAN-RB4732-X6QPCJ36
MalshareD7W6M6-BA9BS4-BQ23Z4-NKCNWQ96
Malware BazaarD4447Q-WJJL6P-W7ME89-WHXJK8TW
JottiVR9Z98-4KU7ZC-PCNFEG-FURQ66FW
vxintelTV6WCV-7Y79LE-BK79EY-C8GUEY46
Threat Report FeedsMKYSAR-3XN9MB-3VAK3R-888ZJUTJ
Stairwell Public VerdictsTT9GM5-JUMD8H-9828FL-GAW5NNXE
Stairwell OSINTEB3DXY-3ZYFVH-6HNKJQ-GAPKHESS
Stairwell MethodologyGEG6FU-MRARGF-TLTM6X-H6MGDT5E
Stairwell ResearchNQNJM6-5LSCAF-3MC5FJ-W8EKGW6N
Florian's Open RulesNCS2SM-YHB2KT-SAFUDX-JC7F6WYA
Pro RulesXAKLND-DKWP3Z-56RL88-6XJ5NH46

Environment IDs are matched case-insensitively, so type them in whatever case you have them.

YARA rules

PrefixLong formMatch style
yara:Rule name, exact, list supported
yr:yararegex:Rule name matches a regular expression
yara:Emotet
yara:"APT29 Dropper"                 # multi-word
yara:[Emotet,Trickbot,Qakbot]        # any of these rules
yr:Cobalt.*
yr:^Pro_                             # anchored
yararegex:^(APT|FIN)_[0-9]+$

A rule name match tells you the file matched that rule. That is evidence to look at, not a verdict on the file. See What is a YARA rule?.

PE metadata

For Portable Executable binaries. Substring matching is the default for human-readable strings. Function names, DLL names, version, and the rich header hash are exact.

PrefixLong formFieldMatch style
pdb:pdbfilename:PDB filenamesubstring
pdbr:pdbregex:PDB filenameregular expression
company:companyname:Company namesubstring
product:productname:Product namesubstring
filedesc:filedescription:File descriptionsubstring
intname:internalname:Internal namesubstring
origname:originalfilename:Original filenamesubstring
version:productversion:Product versionexact, range, list
export:exportfunction:Export functionexact, list
impdll:importdll:Imported DLLexact, list
impfunc:importfunction:Imported functionexact, list
rich:richheaderhash:Rich header hashexact, list
pdb:src/main.pdb                         # PDB path contains src/main.pdb
pdbr:`.*\.pdb$`
company:Microsoft                        # company name contains "Microsoft"
product:"Acme Office"
filedesc:installer
version:1.0.0                            # exact version
version:1.0.0+                           # 1.0.0 or later, semantic-version aware
version:2.5-                             # 2.5 or earlier
version:[1.0.0,2.0.0,3.0.0]              # any of these
export:DllRegisterServer
impdll:kernel32.dll
impdll:[kernel32.dll,ntdll.dll]
impfunc:CreateFileA
rich:deadbeef

Object metadata

PrefixLong formMeaningMatch style
magic:magicnumber:File type, read from the file's own contentexact, list
mime:mimetype:MIME typesubstring
opinion:Your team's recorded verdictexact, list
signed:Signature verification resultexact, list
oac:objectassetcount:Asset count for this file, in your environmentsrange, exact
ogac:objectglobalassetcount:Asset count for this file, globallyrange, exact
magic:EXE                                # any Portable Executable
magic:[EXE,ELF,MACHO]                    # any of these file types
mime:application/pdf                     # MIME type contains "application/pdf"
mimetype:zip                             # any MIME type containing "zip"
opinion:MALICIOUS
opinion:[MALICIOUS,GRAYWARE]
signed:VALID
signed:[INVALID,UNSUPPORTED]

oac:5+                                   # on 5 or more of your assets
oac:100-                                 # on 100 or fewer of your assets
oac:5                                    # on exactly 5 of your assets
ogac:100+                                # on 100 or more assets globally
ogac:42                                  # on exactly 42 assets globally

oac: and ogac: describe the file, not the asset: they count how many assets a given file touches. See Prevalence.

magic values

Values are case-insensitive.

FamilyValues
ExecutablesEXE ELF MACHO WASM
Archives and containersZIP TAR RAR GZ BZ2 XZ SEVENZ Z LZ AR CAB DEB RPM ISO EPUB CRX
DocumentsPDF RTF PS DOC DOCX XLS XLSX PPT PPTX
ImagesPNG JPEG JPEG2000 GIF WEBP BMP TIFF ICO HEIF PSD CR2 JXR DWG
AudioMP3 M4A OGG FLAC WAV AAC AMR MIDI
VideoMP4 M4V MKV MOV AVI WMV MPEG WEBM FLV THREEGP
FontsWOFF WOFF2 TTF OTF EOT
OtherSQLITE SWF DCM NES

Two of those are spelled out because a value cannot start with a digit: SEVENZ is 7z, and THREEGP is 3gp.

magic:EXE covers every Portable Executable variant, including .exe binaries, .dll libraries, .sys drivers, .ocx, .cpl, and .scr. To narrow to one of them, add a filename condition: magic:EXE few:\.dll for DLLs, magic:EXE few:\.sys for drivers.

opinion values

An opinion is your team's own recorded verdict on a file. See Setting Opinions.

ValueMeaning
MALICIOUSMalicious
GRAYWAREUnwanted, but not malicious
VULNERABLEHas known vulnerabilities, not necessarily malicious
BENIGNNothing bad found
TRUSTEDTrusted across all environments
NO_OPINIONNo opinion recorded

Values are case-insensitive.

signed values

The result of verifying the file's signature.

ValueMeaning
VALIDSignature verified
INVALIDSignature did not verify
UNSUPPORTEDSignature could not be verified, so the result is unknown

Network

PrefixLong formMatch style
ip:ipaddress:Exact, list supported
host:hostname:Substring
ip:1.2.3.4
ip:[1.2.3.4,5.6.7.8,9.10.11.12]
host:evil.com                    # hostname contains "evil.com"
hostname:c2.attacker

Both prefixes search the indicators found inside files and the ones observed during detonation. See Network Intelligence.

Threat reports

tr: (long form threatreport:) takes one report identifier. There is no list form, so use OR for several reports.

tr:APT123
threatreport:Lazarus2022
tr:APT123 OR tr:APT124

Well-known files

Well-known files are the ones Stairwell already recognizes, and excluding them is how most hunts cut the noise.

FormMeaning
wkWell-known files only
wk:trueSame as wk
!wkExclude well-known files
wk:falseSame as !wk
wellknownLong form of wk

Maliciousness

p: is the automated verdict.

FormMeaning
pSame as p:true
p:trueThe automated verdict is malicious
!pSame as p:false
p:falseThe automated verdict is not malicious

p:true reflects the automated verdict only. It does not pick up the opinions your team has set. Ask for both when you want both:

p:true OR opinion:MALICIOUS

Verdict label

mallabel: matches the label attached to the verdict, such as a family name. Exact, list supported.

mallabel:Emotet
mallabel:[Emotet,Trickbot,Qakbot]

Likelihood band

bucket: (alias prob:) is range-only. The band is a comparison rather than an exact value, so the operand always needs a + for at least or a - for at most.

bucket:HIGH+        # HIGH or VERY_HIGH
bucket:MEDIUM-      # MEDIUM, LOW, or unranked
prob:VERY_HIGH+

Bands, highest first: VERY_HIGH, HIGH, MEDIUM, LOW. Case does not matter.

The longer PROBABILITY_ prefixed form is also accepted, so bucket:PROBABILITY_HIGH+ means the same thing as bucket:HIGH+. Use the short form; the prefixed one exists because it is what the CEL equivalent and the product's own saved queries use.

bucket:HIGH with no suffix, and bucket:[A,B] as a list, are both rejected.

Tags

PrefixLong formFieldList
ot:objecttag:Object tagyes
at:assettag:Asset tagno
rt:ruletag:Rule tagno
ot:campaign-foo
at:critical
rt:apt

Tag matching is exact. Asset tags and rule tags take a single value, so use OR for several.

Tag matching is case-sensitive today. If you applied the tag as Critical, then at:critical does not match it. Use the case you applied. This is a known beta rough edge.

Per-environment first-seen

envfs: (long form envfirstseen:) matches the time the file first appeared in your environment, as opposed to fs:, which is the first time it was seen anywhere Stairwell can see. It takes the same date and range operands as fs:.

envfs:today                      # first seen in your environment today
envfs:7d+                        # in the last 7 days
envfirstseen:2024-01-01+         # on or after Jan 1 2024

Use fs: for "has this ever existed" and envfs: for "when did this reach us".

Combining terms

Implicit AND

Space-separated terms are combined with AND.

p:true fs:today asset:DESKTOP-123

Explicit AND

p:true AND fs:today

The keyword is case-insensitive, so AND, And, and and all work. There is no && symbol form; use the word.

Same-field OR, with a list

[a,b,c] means any of these values.

asset:[A1,B2,C3]             # asset is A1, B2, or C3
hash:[a,b,c]
imphash:[x,y]
yara:[R1,R2]
objenv:[e1,e2]               # environment IDs
an:[s1,s2,s3]

The list form is exact-match only. The contains, regular expression, starts-with, and ends-with prefixes (fc:, fr:, pc:, pr:, fsw:, few:, psw:, pew:, yr:, ac:, ar:, pdbr:) reject a list. Use OR for those, and for tr:, at:, and rt:.

Cross-field OR

Use the OR keyword for alternatives across different fields, and for any prefix that rejects a list. Both OR and || are accepted, and the keyword is case-insensitive.

tr:APT1 OR yara:APT1_Loader            # in that report, or matching that rule
hash:abc123 OR an:host1
fc:`.sys` OR fc:`.exe`                 # same field, contains prefix
(yara:APT1 AND fs:today) OR p:true     # nested
p:true || fc:`.exe`                    # symbol form

Same environment, same asset, same import

When you AND together terms that all describe one environment, one asset, or one import pair, StairQL requires the same one to satisfy all of them.

objenv:Prod AND (envfs:today OR envfs:yesterday)

That reads as "one of your environments is Prod and saw the file today or yesterday", not "Prod somewhere, and some environment saw it today". You can usually write what you mean without thinking about it. Stacking many OR groups over the same family can be rejected with an error, in which case split the query.

Precedence and grouping

AND binds tighter than OR, the same precedence CEL and SQL use. Without parentheses, alternatives are read as OR over AND-groups.

a OR b AND c                 # parsed as a OR (b AND c)
a AND b OR c AND d           # parsed as (a AND b) OR (c AND d)

Parentheses force the other grouping, and nest freely.

(a OR b) AND c
((a OR b) AND c) OR d

Parentheses only mean grouping at a boundary between terms. Inside a value they are part of the value, so fc:"(foo)" and pr:`(a|b)` pass them through as written. Operators inside a quoted value are never split: fc:"foo OR bar" is one substring match.

Negation

! negates a term.

!fc:safe              # filename does not contain "safe"
!wk                   # not well-known
!an:A1                # asset name is not A1
!an:[A1,B2,C3]        # asset name is none of those
!size:1000+           # not 1000 bytes or larger, so smaller than 1000

Negation works on contains, equality, lists, and ranges. It does not work on the regular expression prefixes; see What is not supported yet.

Quoting and escaping

When in doubt, use backticks. `...` is a raw literal: every character between the backticks is taken as typed, backslashes included.

QuoteBackslash handlingWhen to use
`...`None. Every character is a literalRecommended. Windows paths, regular expressions, anything with a backslash
"..."\\ becomes \, \" becomes ", other escapes pass throughWhen the value contains a double quote
'...'Same as "..."Alternative when the value contains a double quote
pc:`C:\Windows\System32`                # path contains that literal string
fr:`evil\.exe`                          # pattern with an escaped dot
psw:`\\server\share`                    # UNC path prefix
fc:`.sys`                               # filename contains a literal ".sys"

For the regular expression prefixes (fr:, pr:, fsw:, few:, psw:, pew:, yr:, yararegex:, pdbr:), all three quote styles are treated as raw, so backslashes reach the pattern unchanged.

Quotes work inside lists, and styles can be mixed.

an:[`A1`,`B2`,`C3`]
an:[`A1`,"B2",'C3',D4]

Case sensitivity

StairQL normalizes operands to match how each field is stored, so most of the time you type the value the way it looks in the app.

  • Case-insensitive: hashes, asset names, environment names and IDs, filename and path substrings, hostnames, verdict labels, magic values, MIME types, opinions, signature results.
  • Case-sensitive: tags, on objects, assets, and rules. Use the case you applied.
  • Passed through unchanged: numbers, sizes, and timestamps.

What is not supported yet

  • Environment-scoped rule queries. "Any rule in environment X", without naming a rule or a rule tag, has no StairQL form. CEL expresses it with rule.environment_id.
  • Negated regular expressions. !fr:, !pr:, !fsw:, !few:, !psw:, !pew:, and !yr: are not accepted. Negation on contains, equality, lists, and ranges works.
  • p:true covering opinions. p:true is the automated verdict only. Write p:true OR opinion:MALICIOUS for both.
  • Case-insensitive tag matching. See Tags.
  • Last-seen time. StairQL filters on first-seen. There is no per-file last-seen-anywhere timestamp to filter on.

If one of these blocks your team, tell us at [email protected]. Knowing which gap costs you the most is what decides the order they close in.

What should I read next?


Did this page help you?