Skip to content

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

Siemphony’s repertoire

Unix shell spawned by a network-facing service daemon

A Unix shell running is unremarkable on any Linux host, so the parent is the entire detection: this rule matches sh, bash, dash, zsh, ksh, ash or busybox whose parent is a web, database or file-sharing daemon that has no business execing a shell. That is MITRE's ParentProcess knob from AN1081 ("Shell invoked by unexpected parents (e.g., curl, mail, apache2)"), populated here with a daemon list authored for this rule rather than taken from MITRE. php-fpm and uwsgi are matched with contains rather than endswith on purpose, because the shipped binaries are version-suffixed (php-fpm8.2, uwsgi_python311) and an endswith on the bare name never fires. sshd, cron and login are deliberately absent — a shell under those is the system working normally. Known gap: a service hosted inside an interpreter is not selectable by name here, because the exec is the runtime's — a Tomcat, Jetty or Spring Boot app appears as java and a Gunicorn worker as python3, so an RCE in one of those produces a shell whose ParentImage is the runtime. The osquery socket_events and syslog auth.log legs of AN1081 are not authored: the shell-to-network-discovery chain and the remote-session attribution both need a join across sources within a time window, which lib/sigma has no construct for, and AN1082's macOS leg is macos/unifiedlog with no field schema anywhere in the brief. The rule is written in the Sigma linux process_creation vocabulary (Image, ParentImage); a raw auditd SYSCALL feed carries the same facts as exe= and ppid and needs a field mapping first, and auditd records no execve at all until an explicit execve audit rule is loaded. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0384, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full description

The detection

The 4 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: Unix shell spawned by a network-facing service daemonid: e9e26c24-621b-4c22-a0ad-d61d65ca1820status: experimentaldescription: |  A Unix shell running is unremarkable on any Linux host, so the parent is the  entire detection: this rule matches sh, bash, dash, zsh, ksh, ash or busybox  whose parent is a web, database or file-sharing daemon that has no business  execing a shell. That is MITRE's ParentProcess knob from AN1081 ("Shell  invoked by unexpected parents (e.g., curl, mail, apache2)"), populated here  with a daemon list authored for this rule rather than taken from MITRE.  php-fpm and uwsgi are matched with contains rather than endswith on purpose,  because the shipped binaries are version-suffixed (php-fpm8.2,  uwsgi_python311) and an endswith on the bare name never fires. sshd, cron  and login are deliberately absent — a shell under those is the system  working normally. Known gap: a service hosted inside an interpreter is not  selectable by name here, because the exec is the runtime's — a Tomcat, Jetty  or Spring Boot app appears as java and a Gunicorn worker as python3, so an  RCE in one of those produces a shell whose ParentImage is the runtime. The  osquery socket_events and syslog auth.log legs of AN1081 are not authored:  the shell-to-network-discovery chain and the remote-session attribution both  need a join across sources within a time window, which lib/sigma has no  construct for, and AN1082's macOS leg is macos/unifiedlog with no field  schema anywhere in the brief. The rule is written in the Sigma linux  process_creation vocabulary (Image, ParentImage); a raw auditd SYSCALL feed  carries the same facts as exe= and ppid and needs a field mapping first, and  auditd records no execve at all until an explicit execve audit rule is  loaded.  UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0384, 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/T1059/004  - https://attack.mitre.org/detectionstrategies/DET0384author: Siemphony pipeline (machine-derived from MITRE ATT&CK v19.2)date: 2026-08-17tags:  - attack.execution  - attack.t1059.004logsource:  category: process_creation  product: linuxdetection:  selection_shell:    Image|endswith:      - '/sh'      - '/bash'      - '/dash'      - '/zsh'      - '/ksh'      - '/ash'      - '/busybox'  selection_parent_daemon:    ParentImage|endswith:      - '/httpd'      - '/apache2'      - '/nginx'      - '/lighttpd'      - '/mysqld'      - '/mariadbd'      - '/postgres'      - '/redis-server'      - '/memcached'      - '/vsftpd'      - '/proftpd'      - '/smbd'  selection_parent_versioned:    ParentImage|contains:      - '/php-fpm'      - '/uwsgi'  condition: selection_shell and (selection_parent_daemon or selection_parent_versioned)falsepositives:  - "Web applications that shell out by design from PHP — WordPress, Nextcloud and Magento cron runners, ImageMagick and ffmpeg thumbnail helpers, and backup plugins that call sh -c mysqldump, all reached through exec() or shell_exec() under php-fpm. On a CMS or shared-hosting box this is the highest-volume match by a wide margin and fires on the application's own schedule rather than on human activity."  - "PostgreSQL archive_command and restore_command, which the archiver process runs through /bin/sh once per WAL segment, so a busy database emits a steady stream of postgres-parented shells that no operator ever sees."  - "Apache mod_cgi and suexec serving shell CGI scripts, where a .sh or .cgi file with a #!/bin/sh shebang makes httpd or apache2 the parent of /bin/sh every time the page is requested."  - "Samba print and VFS commands and vsftpd upload hooks, which are configured as shell command strings and are therefore executed as a child shell of smbd or vsftpd on every matching client operation."level: medium

Sentinel · KQL

Run this as a search.

DeviceProcessEvents| where ((FolderPath endswith "/sh" or FolderPath endswith "/bash" or FolderPath endswith "/dash" or FolderPath endswith "/zsh" or FolderPath endswith "/ksh" or FolderPath endswith "/ash" or FolderPath endswith "/busybox") and ((InitiatingProcessFolderPath endswith "/httpd" or InitiatingProcessFolderPath endswith "/apache2" or InitiatingProcessFolderPath endswith "/nginx" or InitiatingProcessFolderPath endswith "/lighttpd" or InitiatingProcessFolderPath endswith "/mysqld" or InitiatingProcessFolderPath endswith "/mariadbd" or InitiatingProcessFolderPath endswith "/postgres" or InitiatingProcessFolderPath endswith "/redis-server" or InitiatingProcessFolderPath endswith "/memcached" or InitiatingProcessFolderPath endswith "/vsftpd" or InitiatingProcessFolderPath endswith "/proftpd" or InitiatingProcessFolderPath endswith "/smbd") or (InitiatingProcessFolderPath contains "/php-fpm" or InitiatingProcessFolderPath contains "/uwsgi")))

Splunk · SPL

Run this as a search.

index=* ((Image="*/sh" OR Image="*/bash" OR Image="*/dash" OR Image="*/zsh" OR Image="*/ksh" OR Image="*/ash" OR Image="*/busybox") AND ((ParentImage="*/httpd" OR ParentImage="*/apache2" OR ParentImage="*/nginx" OR ParentImage="*/lighttpd" OR ParentImage="*/mysqld" OR ParentImage="*/mariadbd" OR ParentImage="*/postgres" OR ParentImage="*/redis-server" OR ParentImage="*/memcached" OR ParentImage="*/vsftpd" OR ParentImage="*/proftpd" OR ParentImage="*/smbd") OR (ParentImage="*/php-fpm*" OR ParentImage="*/uwsgi*")))

Elastic · ES|QL

Run this as a search.

FROM logs-*| WHERE ((TO_LOWER(process.executable) LIKE "*/sh" OR TO_LOWER(process.executable) LIKE "*/bash" OR TO_LOWER(process.executable) LIKE "*/dash" OR TO_LOWER(process.executable) LIKE "*/zsh" OR TO_LOWER(process.executable) LIKE "*/ksh" OR TO_LOWER(process.executable) LIKE "*/ash" OR TO_LOWER(process.executable) LIKE "*/busybox") AND ((TO_LOWER(process.parent.executable) LIKE "*/httpd" OR TO_LOWER(process.parent.executable) LIKE "*/apache2" OR TO_LOWER(process.parent.executable) LIKE "*/nginx" OR TO_LOWER(process.parent.executable) LIKE "*/lighttpd" OR TO_LOWER(process.parent.executable) LIKE "*/mysqld" OR TO_LOWER(process.parent.executable) LIKE "*/mariadbd" OR TO_LOWER(process.parent.executable) LIKE "*/postgres" OR TO_LOWER(process.parent.executable) LIKE "*/redis-server" OR TO_LOWER(process.parent.executable) LIKE "*/memcached" OR TO_LOWER(process.parent.executable) LIKE "*/vsftpd" OR TO_LOWER(process.parent.executable) LIKE "*/proftpd" OR TO_LOWER(process.parent.executable) LIKE "*/smbd") OR (TO_LOWER(process.parent.executable) LIKE "*/php-fpm*" OR TO_LOWER(process.parent.executable) LIKE "*/uwsgi*")))

Wazuh · XML rule

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

<group name="sigma,linux,process_creation,">  <!-- Rule ids must be unique on your manager; 100000+ is the user range. -->  <rule id="100000" level="7">    <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. -->    <field name="Image" type="pcre2">(?i)(/sh$|/bash$|/dash$|/zsh$|/ksh$|/ash$|/busybox$)</field>    <field name="ParentImage" type="pcre2">(?i)((/httpd$|/apache2$|/nginx$|/lighttpd$|/mysqld$|/mariadbd$|/postgres$|/redis-server$|/memcached$|/vsftpd$|/proftpd$|/smbd$)|(/php-fpm|/uwsgi))</field>    <description>Unix shell spawned by a network-facing service daemon</description>    <mitre>      <id>T1059.004</id>    </mitre>  </rule></group>

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.