Skip to content

Siemphony is in beta and still being built. How a rule earns its badge.

Siemphony’s repertoire

Recursive directory listing issued from a Windows shell

AN1040's real discriminator is MITRE's TimeWindow knob — more than fifty directory queries inside thirty seconds — which a single Sigma event cannot count, so this rule instead matches the command forms that ask for a whole tree in one call: `dir /s`, `tree /f`, `forfiles /s`, and PowerShell's `Get-ChildItem -Recurse` and its aliases. Each form is matched with a regex that requires the command word at a token boundary with its recursion flag following it, because an unordered substring pair ('dir' plus '/s') also matches unrelated command lines — a robocopy job against a folder named "Source Dir" run with /s, or a silent installer whose /s flag shares a line with any path containing 'dir'. That is a narrower slice of MITRE's CommandLineRegex knob than "any enumeration command", because a single non-recursive `dir` is indistinguishable from routine shell use and would swamp this rule. UserContext is not encoded — the brief calls for scoping standard versus service accounts, which needs an identity join this event does not carry — and a hand-rolled recursion loop or a compiled enumerator that never shells out to these four commands produces no match at all. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0370, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full description

The detection

The 3 SIEM queries below are previews produced by Siemphony’s own translator, not pySigma, and none has been executed against a real backend — review before you deploy.

detection.yml

title: Recursive directory listing issued from a Windows shellid: efcf797d-092a-45fd-b5e7-0c726c7548b3status: experimentaldescription: |  AN1040's real discriminator is MITRE's TimeWindow knob — more than fifty  directory queries inside thirty seconds — which a single Sigma event cannot  count, so this rule instead matches the command forms that ask for a whole  tree in one call: `dir /s`, `tree /f`, `forfiles /s`, and PowerShell's  `Get-ChildItem -Recurse` and its aliases. Each form is matched with a regex  that requires the command word at a token boundary with its recursion flag  following it, because an unordered substring pair ('dir' plus '/s') also  matches unrelated command lines — a robocopy job against a folder named  "Source Dir" run with /s, or a silent installer whose /s flag shares a line  with any path containing 'dir'. That is a narrower slice of MITRE's  CommandLineRegex knob than "any enumeration command", because a single  non-recursive `dir` is indistinguishable from routine shell use and would  swamp this rule. UserContext is not encoded — the brief calls for scoping  standard versus service accounts, which needs an identity join this event does  not carry — and a hand-rolled recursion loop or a compiled enumerator that  never shells out to these four commands produces no match at all.  UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0370, not hand-written and not tested by its author. Any lab result is on this rule's own page.references:  - https://attack.mitre.org/techniques/T1083  - https://attack.mitre.org/detectionstrategies/DET0370author: Siemphony pipeline (machine-derived from MITRE ATT&CK v19.2)date: 2026-08-16tags:  - attack.discovery  - attack.t1083logsource:  category: process_creation  product: windowsdetection:  selection_shell:    Image|endswith:      - '\cmd.exe'      - '\powershell.exe'      - '\pwsh.exe'  selection_recurse:    CommandLine|re:      - '(?:^|[\s&|("])dir(?:\s+[^&|;]+)?\s+/s(?:[\s"]|$)'      - '(?:^|[\s&|("])tree(?:\.com)?(?:\s+[^&|;]+)?\s+/f(?:[\s"]|$)'      - 'forfiles(?:\.exe)?(?:\s+[^&|;]+)?\s+/s(?:[\s"]|$)'      - '(?:^|[\s;|({"])(?:get-childitem|gci|ls|dir)(?:\s+[^;|]+)?\s+-(?:r|re|rec|recu|recur|recurs|recurse)(?:[\s"]|$)'  condition: selection_shell and selection_recursefalsepositives:  - "Build, packaging and CI scripts that run `dir /s /b` or `Get-ChildItem -Recurse` to enumerate a source or output tree before archiving it. On any developer or build-agent host this is a routine, repeated event and is the loudest match by a wide margin, which is what the level below reflects."  - "Backup, inventory and software-asset-management agents that walk every user profile or shared drive on a fixed schedule with a recursive `dir` or `Get-ChildItem` to build a file or size report."  - "Disk-usage and storage-cleanup tooling, including admin one-liners that use `Get-ChildItem -Recurse` or its `dir`/`ls` aliases while sizing a directory tree during routine troubleshooting."  - "Log and cache rotation tasks that call `forfiles /s` against an application log directory on a fixed schedule to find and prune old files."level: low

Sentinel · KQL

Run this as a search.

DeviceProcessEvents| where ((FolderPath endswith "\\cmd.exe" or FolderPath endswith "\\powershell.exe" or FolderPath endswith "\\pwsh.exe") and (ProcessCommandLine matches regex "(?i)(?:^|[\\s&|(\"])dir(?:\\s+[^&|;]+)?\\s+/s(?:[\\s\"]|$)" or ProcessCommandLine matches regex "(?i)(?:^|[\\s&|(\"])tree(?:\\.com)?(?:\\s+[^&|;]+)?\\s+/f(?:[\\s\"]|$)" or ProcessCommandLine matches regex "(?i)forfiles(?:\\.exe)?(?:\\s+[^&|;]+)?\\s+/s(?:[\\s\"]|$)" or ProcessCommandLine matches regex "(?i)(?:^|[\\s;|({\"])(?:get-childitem|gci|ls|dir)(?:\\s+[^;|]+)?\\s+-(?:r|re|rec|recu|recur|recurs|recurse)(?:[\\s\"]|$)"))

Splunk · SPL

Run this as a search.

index=* | where ((match(Image, "(?i)\\\\cmd\\.exe$") OR match(Image, "(?i)\\\\powershell\\.exe$") OR match(Image, "(?i)\\\\pwsh\\.exe$")) AND (match(CommandLine, "(?:^|[\\s&|(\"])dir(?:\\s+[^&|;]+)?\\s+/s(?:[\\s\"]|$)") OR match(CommandLine, "(?:^|[\\s&|(\"])tree(?:\\.com)?(?:\\s+[^&|;]+)?\\s+/f(?:[\\s\"]|$)") OR match(CommandLine, "forfiles(?:\\.exe)?(?:\\s+[^&|;]+)?\\s+/s(?:[\\s\"]|$)") OR match(CommandLine, "(?:^|[\\s;|({\"])(?:get-childitem|gci|ls|dir)(?:\\s+[^;|]+)?\\s+-(?:r|re|rec|recu|recur|recurs|recurse)(?:[\\s\"]|$)")))

Wazuh · XML rule

Deploy to your manager — this is a rule, not a search.

<group name="sigma,windows,process_creation,">  <!-- Rule ids must be unique on your manager; 100000+ is the user range. -->  <rule id="100000" level="5">    <!-- Set <if_sid> to the decoder/base rule for windows so this only evaluates relevant events. -->    <field name="Image" type="pcre2">(?i)(\\cmd\.exe$|\\powershell\.exe$|\\pwsh\.exe$)</field>    <field name="CommandLine" type="pcre2">(?i)((?:^|[\s&amp;|(&quot;])dir(?:\s+[^&amp;|;]+)?\s+/s(?:[\s&quot;]|$)|(?:^|[\s&amp;|(&quot;])tree(?:\.com)?(?:\s+[^&amp;|;]+)?\s+/f(?:[\s&quot;]|$)|forfiles(?:\.exe)?(?:\s+[^&amp;|;]+)?\s+/s(?:[\s&quot;]|$)|(?:^|[\s;|({&quot;])(?:get-childitem|gci|ls|dir)(?:\s+[^;|]+)?\s+-(?:r|re|rec|recu|recur|recurs|recurse)(?:[\s&quot;]|$))</field>    <description>Recursive directory listing issued from a Windows shell</description>    <mitre>      <id>T1083</id>    </mitre>  </rule></group>

Elastic · ES|QL

Run this as a search.

Elastic cannot express this construct. ES|QL RLIKE uses Lucene regexp syntax, which has no case-insensitive flag, and Sigma regexes are case-insensitive. Use |contains/|startswith/|endswith, or write the ES|QL by hand. The Sigma source is on the first tab, unchanged.

Verdicts · reactions · comments

Community

Verdicts from engineers who actually deployed it, and the conversation around it.

Log in to react
Not yet reported on

Nobody has run this in a real environment and said what happened.

Verdicts from engineers who deployed it

0 cast

No verdicts reported yet. The first one is worth more than the tenth — say what you ran it against.

Log in to report a verdict.

Log in to join the discussion.

No comments yet. Someone who deploys this will have something to say about it.