Skip to content

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

Siemphony’s repertoire

Kernel module loaded or the module tree modified on Linux

Siemphony@siemphonylowT1547.006unverified
Covers both halves of AN1243 on the one log source they share: an auditd SYSCALL record whose `exe` is a module-management tool, and an auditd PATH record naming a kernel object file or anything inside the module tree. The path half is MITRE's `FilePathRegex` knob, populated here with the `/lib/modules/` substring — a substring rather than a prefix so that distributions which ship the tree at `/usr/lib/modules/` are included — plus the kernel object suffixes themselves, and those are listed as `.ko`, `.ko.xz`, `.ko.zst` and `.ko.gz` because most current distributions install modules compressed and a bare `.ko` endswith silently misses every one of them. The tool half needs the same care in the other direction: on Debian, Ubuntu, RHEL, Fedora and Arch, `insmod`, `rmmod`, `modprobe`, `depmod`, `lsmod` and `modinfo` are all symlinks to a single `kmod` binary, and auditd resolves `exe=` to the executable that was actually mapped, so a selector listing only `/insmod` and `/modprobe` is dead on a modern host. `/kmod` is therefore in the list, and the price of including it is that the read-only queries `lsmod` and `modinfo` match exactly as a load does. Four limits are worth stating before this is deployed. First, the loading paths that skip the tools entirely are missed: `systemd-modules-load` and `systemd-udevd` call `finit_module` directly at boot, and a rootkit dropper that calls `init_module` from its own compiled code execs nothing at all, so the SYSCALL leg never sees either. Second, the `.ko` selection is only as good as the audit configuration behind it — a PATH record is emitted for an audited syscall or a watched path, so a module staged in `/tmp` and loaded from there produces no PATH record unless `openat` is audited globally, which almost nobody does for cost reasons. Third, MITRE's `UserContext` knob cannot be applied inside this rule: auditd splits one event across records and `uid`/`auid` live only on the SYSCALL side, so the PATH selections have no user to filter on. Fourth, MITRE's `TimeWindow` knob is a change-window suppression, which lib/sigma has no way to express. The macOS arm AN1244 is not attempted — its sources are `macos:unifiedlog` and `macos:osquery`, neither of which has a standardised Sigma field vocabulary, so `kextload`, the `/Library/Extensions` write and the KextPolicy database change would all have to be written against invented field names; that is the same ground on which T1543.001 and T1546.014 declined their macOS legs. The osquery leg of AN1243 is unattempted for the same reason. Prerequisite: auditd ships with no rules loaded on any mainstream distribution, so this rule returns zero rows until both an execve rule such as `-a always,exit -F arch=b64 -S execve -k exec` and a watch such as `-w /lib/modules -p wa -k modules` are in place — and zero rows reads as quiet when it actually means blind. The watch permission also sets the noise floor: `wa` records writes and attribute changes only, whereas adding `r` makes every module the kernel loads on demand match as well. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0450, 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="SYSCALL" AND (exe="*/insmod" OR exe="*/rmmod" OR exe="*/modprobe" OR exe="*/depmod" OR exe="*/kmod")) OR (type="PATH" AND (name="*.ko" OR name="*.ko.xz" OR name="*.ko.zst" OR name="*.ko.gz")) OR (type="PATH" AND name="*/lib/modules/*"))

Elastic · ES|QL

Run this as a search.

FROM logs-*| WHERE ((TO_LOWER(type) == "syscall" AND (TO_LOWER(exe) LIKE "*/insmod" OR TO_LOWER(exe) LIKE "*/rmmod" OR TO_LOWER(exe) LIKE "*/modprobe" OR TO_LOWER(exe) LIKE "*/depmod" OR TO_LOWER(exe) LIKE "*/kmod")) OR (TO_LOWER(type) == "path" AND (TO_LOWER(name) LIKE "*.ko" OR TO_LOWER(name) LIKE "*.ko.xz" OR TO_LOWER(name) LIKE "*.ko.zst" OR TO_LOWER(name) LIKE "*.ko.gz")) OR (TO_LOWER(type) == "path" AND TO_LOWER(name) LIKE "*/lib/modules/*"))

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. -->  <!-- 3 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)^SYSCALL$</field>    <field name="exe" type="pcre2">(?i)(/insmod$|/rmmod$|/modprobe$|/depmod$|/kmod$)</field>    <description>Kernel module loaded or the module tree modified on Linux (1/3)</description>    <mitre>      <id>T1547.006</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)(\.ko$|\.ko\.xz$|\.ko\.zst$|\.ko\.gz$)</field>    <description>Kernel module loaded or the module tree modified on Linux (2/3)</description>    <mitre>      <id>T1547.006</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)/lib/modules/</field>    <description>Kernel module loaded or the module tree modified on Linux (3/3)</description>    <mitre>      <id>T1547.006</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.