Linux Audit system disabled, purged or its config files tampered with
AN0171 names three mechanisms — killing the auditd process, stopping it as a service, and editing/deleting its rule and config files — plus the `auditctl` command line the technique's own description calls out as one of "two primary ways to configure the log generation rules". This rule covers all four as single-event auditd EXECVE or PATH records on the same `product: linux, service: auditd` logsource the brief maps every non-syslog log source in AN0171 onto; the correlation AN0171 also asks for — suspicious commands, file writes and a resulting gap in audit logging inside its `TimeWindow` knob — is not expressible in lib/sigma and is not attempted. The first group matches `auditctl -D` (delete all loaded rules) or `auditctl -e 0` (turn auditing off at runtime) — the two invocations that neutralise the running ruleset without touching a file. Both are pinned to the flag appearing first (a1, with `0` at a2 for the second form), which is how these commands are documented and almost always run; a build with another option ahead of `-D` or `-e` — `auditctl -q -D`, say — is missed by this selection. The second and third groups are two fixed-order selections rather than one selection OR-ing the verb and the target across several argument positions: `systemctl stop|disable|mask auditd` (verb at a1, target at a2) and `service auditd stop|disable|mask` (target at a1, verb at a2), which is the documented argument order for each command and covers the ordinary invocation of both. On most current distributions the auditd unit ships `RefuseManualStop=yes`, so a `systemctl stop auditd` from a shell is refused by systemd at the unit level — but the execve of `systemctl stop auditd` still happens and still lands in this selection, which is why the attempt is matched rather than an assumption that it succeeded. Flags ahead of the verb, `systemctl --user stop auditd` for instance, shift the target out of a2 and are missed, the same positional trade-off made for the auditctl group and made everywhere else in this rule: each cross-field OR that the Sigma logic could otherwise use to absorb argument-order variance costs the Wazuh translator a multiplying number of expanded `<rule>` blocks, and this rule is written to stay under that ceiling rather than refuse Wazuh outright, at the cost of the flagged and reordered forms of every command it matches. The fourth group matches `pkill auditd` and `killall auditd`, the two invocations that reference the daemon by name at a1; `pkill -9 auditd`, with the target pushed to a2, is missed for the same reason. A bare `kill -9 <pid>` cannot be matched at all, because the EXECVE record's arguments carry only the numeric pid and nothing ties that number back to auditd without a live process table this rule has no access to — the second log source in the brief ("kill syscalls targeting auditd process") describes exactly this case and is the reason it is listed as a log source MITRE named but this rule cannot cover. The fifth group matches PATH records naming `/etc/audit/audit.rules`, `/etc/audit/audit.conf`, or the `/etc/audit/rules.d/` drop-in directory that `augenrules` compiles into audit.rules on RHEL-family systems; the drop-in directory is an addition beyond the two files MITRE's `FilePathScope` knob names explicitly, added here because it is the only place these rules actually live on any system using augenrules. As with other PATH-based rules in this corpus, auditd records `name=` exactly as handed to the syscall, so an edit made from inside `/etc/audit/` logs a bare filename with the directory only on a CWD record Sigma cannot join, and a relative-path edit from that working directory is missed by this selection. There is a sharper version of the usual blind-prerequisite problem here: this technique's entire premise is removing the very rules that would detect it, so a `-D` that succeeds deletes the exec-watch rule this detection depends on along with everything else — the kernel evaluates rules at syscall entry, so the `auditctl -D` invocation itself should still be logged before its own deletion takes effect, but nothing after it will be, and MITRE's correlation-based observation of "a gap in audit logs following privileged execution" is precisely the signal this rule cannot produce. As with every other auditd-sourced rule in this corpus, none of these watches exist by default; execve is not audited without `-a always,exit -F arch=b64 -S execve -k exec` (plus its b32 twin), and the file group returns nothing until `/etc/audit/audit.rules` and `/etc/audit/audit.conf` are separately watched with `-p wa`. A watch on `/etc/audit/` does not extend to the `/etc/audit/rules.d/` leg above: `auditctl -w` directory watches are documented as non-recursive — they cover only the entries directly inside the watched directory, not files inside a subdirectory of it — so `/etc/audit/rules.d/` needs its own `-w /etc/audit/rules.d/ -p wa` watch or that leg never fires no matter how the parent directory is configured. Zero rows from any group reads as quiet when it means blind, and here specifically it can mean the attack already succeeded. The fourth log source in AN0171 — `linux:syslog::auditd service stopped or disabled` — is a different logsource block (`product: linux, service: syslog`) and is not attempted here; a rule copying that logsource verbatim would need its own selectors in syslog's field vocabulary and is out of scope for this file. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0062, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full descriptionShow less
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="EXECVE" AND a0="*auditctl") AND (a1="-D" OR (a1="-e" AND a2="0"))) OR (type="EXECVE" AND a0="*systemctl" AND (a1="*stop*" OR a1="*disable*" OR a1="*mask*") AND a2="*auditd*")) OR (type="EXECVE" AND a0="*service" AND a1="*auditd*" AND (a2="*stop*" OR a2="*disable*" OR a2="*mask*"))) OR (type="EXECVE" AND (a0="*pkill" OR a0="*killall") AND a1="*auditd*")) OR (type="PATH" AND (name="*/etc/audit/audit.rules*" OR name="*/etc/audit/audit.conf*" OR name="*/etc/audit/rules.d/*")))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE ((((((TO_LOWER(type) == "execve" AND TO_LOWER(a0) LIKE "*auditctl") AND (TO_LOWER(a1) == "-d" OR (TO_LOWER(a1) == "-e" AND TO_LOWER(a2) == "0"))) OR (TO_LOWER(type) == "execve" AND TO_LOWER(a0) LIKE "*systemctl" AND (TO_LOWER(a1) LIKE "*stop*" OR TO_LOWER(a1) LIKE "*disable*" OR TO_LOWER(a1) LIKE "*mask*") AND TO_LOWER(a2) LIKE "*auditd*")) OR (TO_LOWER(type) == "execve" AND TO_LOWER(a0) LIKE "*service" AND TO_LOWER(a1) LIKE "*auditd*" AND (TO_LOWER(a2) LIKE "*stop*" OR TO_LOWER(a2) LIKE "*disable*" OR TO_LOWER(a2) LIKE "*mask*"))) OR (TO_LOWER(type) == "execve" AND (TO_LOWER(a0) LIKE "*pkill" OR TO_LOWER(a0) LIKE "*killall") AND TO_LOWER(a1) LIKE "*auditd*")) OR (TO_LOWER(type) == "path" AND (TO_LOWER(name) LIKE "*/etc/audit/audit.rules*" OR TO_LOWER(name) LIKE "*/etc/audit/audit.conf*" OR TO_LOWER(name) LIKE "*/etc/audit/rules.d/*")))
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. --> <!-- 6 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)^EXECVE$</field> <field name="a0" type="pcre2">(?i)auditctl$</field> <field name="a1" type="pcre2">(?i)^-D$</field> <description>Linux Audit system disabled, purged or its config files tampered with (1/6)</description> <mitre> <id>T1685.004</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)^EXECVE$</field> <field name="a0" type="pcre2">(?i)auditctl$</field> <field name="a1" type="pcre2">(?i)^-e$</field> <field name="a2" type="pcre2">(?i)^0$</field> <description>Linux Audit system disabled, purged or its config files tampered with (2/6)</description> <mitre> <id>T1685.004</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)^EXECVE$</field> <field name="a0" type="pcre2">(?i)systemctl$</field> <field name="a1" type="pcre2">(?i)(stop|disable|mask)</field> <field name="a2" type="pcre2">(?i)auditd</field> <description>Linux Audit system disabled, purged or its config files tampered with (3/6)</description> <mitre> <id>T1685.004</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="type" type="pcre2">(?i)^EXECVE$</field> <field name="a0" type="pcre2">(?i)service$</field> <field name="a1" type="pcre2">(?i)auditd</field> <field name="a2" type="pcre2">(?i)(stop|disable|mask)</field> <description>Linux Audit system disabled, purged or its config files tampered with (4/6)</description> <mitre> <id>T1685.004</id> </mitre> </rule> <rule id="100004" level="5"> <!-- Set <if_sid> to the decoder/base rule for linux so this only evaluates relevant events. --> <field name="type" type="pcre2">(?i)^EXECVE$</field> <field name="a0" type="pcre2">(?i)(pkill$|killall$)</field> <field name="a1" type="pcre2">(?i)auditd</field> <description>Linux Audit system disabled, purged or its config files tampered with (5/6)</description> <mitre> <id>T1685.004</id> </mitre> </rule> <rule id="100005" 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/audit/audit\.rules|/etc/audit/audit\.conf|/etc/audit/rules\.d/)</field> <description>Linux Audit system disabled, purged or its config files tampered with (6/6)</description> <mitre> <id>T1685.004</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.
Nobody has run this in a real environment and said what happened.
Verdicts from engineers who deployed it
0 castNo 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.