Skip to content

Siemphony is in beta and still being built. What ships today, and what does not.

Siemphony’s repertoire

Crontab file or cron drop-in directory written on Linux

Siemphony@siemphonylowT1053.003unverified
Matches the file-modification leg of AN0805: an auditd PATH record naming one of the stores cron reads its schedule from — the per-user spool under /var/spool/cron/, the system-wide /etc/crontab and /etc/anacrontab, and the drop-in directories /etc/cron.d/ and the hourly, daily, weekly and monthly run-parts folders. The path list is MITRE's `CronFilePath` knob, populated here with the Debian and RHEL layouts; a distribution that keeps its spool elsewhere needs its own entry. ESXi is one of the technique's platforms and its crontab lives at the same /var/spool/cron/crontabs/root path, but ESXi runs no auditd, so this logsource does not reach it and the ESXi arm of the technique is uncovered. Matching is on `contains` and `endswith` rather than an absolute path because `crontab -e` writes a temporary file and renames it into the spool — the rename target is what shows up, not the editor's scratch file. That does not rescue the relative case: auditd records `name=` exactly as it was handed to the syscall, so `cd /etc/cron.d && echo '* * * * * root /tmp/x' > job` logs `name="job"`, with the directory on a separate CWD record that Sigma cannot join, and no path selection here can match it. Such a write is caught only by the fourth selection, which matches the audit `key` the watches below install and which rides on the SYSCALL record whatever form the path took — so it works only if those watches were loaded with that exact `-k cron` key. Two parts of the analytic cannot be expressed here. auditd emits PATH and SYSCALL as separate records for one event, and the writing process's `exe`, `uid` and `auid` live only on the SYSCALL side, so MITRE's `RunUser` knob ("only root may schedule jobs") cannot be applied inside this selection; and the analytic's second half — an uncommon binary later executing on the schedule, with MITRE's `ExecutionFrequency` knob thresholding how often — is a cross-event correlation Sigma has no way to state. The macOS arm AN0806 is not attempted, because its unifiedlog source has no standardised Sigma field names and inventing them would produce a rule that renders everywhere and matches nothing. Prerequisite: no distribution audits these paths by default, so this rule returns zero rows until watches such as `-w /var/spool/cron -p wa -k cron`, `-w /etc/crontab -p wa -k cron` and `-w /etc/cron.d -p wa -k cron` are loaded — and zero rows reads as quiet when it actually means blind. The `wa` permission also decides the noise floor: with it, only writes and attribute changes are recorded, whereas a watch that includes `r` makes every scan by the cron daemon itself match. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0290, 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

Splunk · SPL

Run this as a search.

index=* ((type="PATH" AND name="*/var/spool/cron/*") OR (type="PATH" AND (name="*/etc/cron.d/*" OR name="*/etc/cron.hourly/*" OR name="*/etc/cron.daily/*" OR name="*/etc/cron.weekly/*" OR name="*/etc/cron.monthly/*")) OR (type="PATH" AND (name="*/etc/crontab" OR name="*/etc/anacrontab")) OR key="cron")

Elastic · ES|QL

Run this as a search.

FROM logs-*| WHERE ((TO_LOWER(type) == "path" AND TO_LOWER(name) LIKE "*/var/spool/cron/*") OR (TO_LOWER(type) == "path" AND (TO_LOWER(name) LIKE "*/etc/cron.d/*" OR TO_LOWER(name) LIKE "*/etc/cron.hourly/*" OR TO_LOWER(name) LIKE "*/etc/cron.daily/*" OR TO_LOWER(name) LIKE "*/etc/cron.weekly/*" OR TO_LOWER(name) LIKE "*/etc/cron.monthly/*")) OR (TO_LOWER(type) == "path" AND (TO_LOWER(name) LIKE "*/etc/crontab" OR TO_LOWER(name) LIKE "*/etc/anacrontab")) OR TO_LOWER(key) == "cron")

Wazuh · XML rule

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

<group name="sigma,linux,">  <!-- Rule ids must be unique on your manager; 100000+ is the user range. -->  <!-- 4 rules: the Sigma condition ORs across different fields,       which one rule cannot express. Any one matching is a hit. -->  <rule id="100000" level="5">    <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. -->    <field name="type" type="pcre2">(?i)^PATH$</field>    <field name="name" type="pcre2">(?i)/var/spool/cron/</field>    <description>Crontab file or cron drop-in directory written on Linux (1/4)</description>    <mitre>      <id>T1053.003</id>    </mitre>  </rule>   <rule id="100001" level="5">    <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. -->    <field name="type" type="pcre2">(?i)^PATH$</field>    <field name="name" type="pcre2">(?i)(/etc/cron\.d/|/etc/cron\.hourly/|/etc/cron\.daily/|/etc/cron\.weekly/|/etc/cron\.monthly/)</field>    <description>Crontab file or cron drop-in directory written on Linux (2/4)</description>    <mitre>      <id>T1053.003</id>    </mitre>  </rule>   <rule id="100002" level="5">    <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. -->    <field name="type" type="pcre2">(?i)^PATH$</field>    <field name="name" type="pcre2">(?i)(/etc/crontab$|/etc/anacrontab$)</field>    <description>Crontab file or cron drop-in directory written on Linux (3/4)</description>    <mitre>      <id>T1053.003</id>    </mitre>  </rule>   <rule id="100003" level="5">    <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. -->    <field name="key" type="pcre2">(?i)^cron$</field>    <description>Crontab file or cron drop-in directory written on Linux (4/4)</description>    <mitre>      <id>T1053.003</id>    </mitre>  </rule></group>

Sentinel · KQL

Run this as a search.

Sentinel cannot express this construct. No Sentinel table is modelled for this logsource ({"product":"linux","service":"auditd"}), so there is nothing honest to query. Pick a logsource this translator maps, or write the KQL 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.