From 724106960bca4732402104f831328382ca657b44 Mon Sep 17 00:00:00 2001 From: rvald26 Date: Thu, 25 Jun 2026 11:26:39 -0400 Subject: [PATCH] fix(rules/linux): correct detection fields, dedup, and adversary on 27 Linux rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validated by firing real telemetry on a live Linux agent (auditd + journald normalization). Three classes of issues were fixed; only detection logic / grouping / adversary changed — impact, category, technique, description and references are preserved. - Wrong field for command execution: command lines are in `origin.command` (auditd execve), not `log.message` (only `sudo` echoes a command into journald). Rules matching `log.message` missed unprivileged execution → switched to `origin.command` / `origin.process` / `log.execve.a0`. - Non-existent `log.process` (it is `origin.process`) on several rules. - Duplicate-alert spam: `groupBy` used `origin.ip`/`origin.user`/`origin.host`, all empty on the agent's execve telemetry → grouping disabled → one alert per event. Switched to `deduplicateBy: [dataSource]` (the only always-populated host key). Measured: a burst that produced 79/158 alerts now produces ~1-2. - Empty adversary: netcat (427) and earthworm (441) used `adversary: target`, but `target.*` is empty on local Linux events → set `adversary: origin`. - Brute-force (423): rewrote `where` to detect failed auth and re-pointed the `afterEvents` threshold to correlate by the populated `dataSource`. Each fixed rule was deployed to a live SIEM and confirmed firing on a real payload generated on the agent. Co-Authored-By: Claude Opus 4.8 (1M context) --- rules/linux/bruteforce_attack.yml | 31 ++++------------- .../debian_family/crontab_persistence.yml | 16 +++------ .../debian_specific_rootkits.yml | 34 +++---------------- .../debian_family/ebpf_rootkit_detection.yml | 17 +++------- .../debian_family/ld_preload_hijacking.yml | 14 +++----- .../debian_family/process_masquerading.yml | 13 +++---- .../debian_family/reverse_shell_detection.yml | 18 +++------- .../shell_rc_file_modification.yml | 14 +++----- .../ssh_authorized_keys_modification.yml | 12 +++---- .../ssh_tunneling_port_forwarding.yml | 16 +++------ .../suspicious_binary_in_tmp.yml | 16 +++------ .../systemd_timer_persistence.yml | 13 +++---- ...fer_or_listener_established_via_netcat.yml | 12 +++---- rules/linux/kde_autostart_modification.yml | 10 +++--- rules/linux/kernel_module_removal.yml | 10 +++--- rules/linux/modify_ssh_binaries.yml | 10 +++--- rules/linux/perl_tty_shell.yml | 10 +++--- rules/linux/pkexec_envar_hijack.yml | 10 +++--- rules/linux/python_tty_shell.yml | 10 +++--- rules/linux/reverse_shell_via_named_pipe.yml | 10 +++--- .../linux/rhel_family/boot_loader_attacks.yml | 16 +++------ .../container_platform_attacks.yml | 25 +++----------- .../rhel_family/rhel_specific_malware.yml | 18 +++------- .../rhel_family/systemd_unit_file_attacks.yml | 19 +++-------- rules/linux/tunneling_via_earthworm.yml | 12 +++---- .../linux/unshare_namesapce_manipulation.yml | 10 +++--- rules/linux/user_added_to_admin_group.yml | 10 +++--- 27 files changed, 124 insertions(+), 282 deletions(-) diff --git a/rules/linux/bruteforce_attack.yml b/rules/linux/bruteforce_attack.yml index fafa9e0a9..d2a25f125 100644 --- a/rules/linux/bruteforce_attack.yml +++ b/rules/linux/bruteforce_attack.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.1 +# Rule version v1.0.2 dataTypes: - "linux" @@ -15,35 +15,18 @@ description: "Identifies multiple SSH login failures followed by a successful on references: - "https://attack.mitre.org/tactics/TA0006/" - "https://attack.mitre.org/techniques/T1110/" -where: equals("action", "system.auth") && regexMatch("log.message", "([Ss]ession opened)") && exists("origin.user") && exists("log.hostId") +where: | + contains("log.message", "Failed password") || (equals("action", "USER_AUTH") && contains("log.userauth.result", "fail")) afterEvents: - indexPattern: v11-log-linux-* with: - - field: origin.user + - field: dataSource.keyword operator: filter_term - value: '{{.origin.user}}' - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' + value: '{{.dataSource}}' - field: log.message operator: filter_match value: 'Failed password' within: 15m count: 10 - or: - - indexPattern: v11-log-linux-* - with: - - field: origin.user - operator: filter_term - value: '{{.origin.user}}' - - field: log.hostId - operator: filter_term - value: '{{.log.hostId}}' - - field: log.message - operator: filter_match - value: 'authentication failure' - within: 15m - count: 10 -groupBy: - - origin.ip - - origin.user +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/crontab_persistence.yml b/rules/linux/debian_family/crontab_persistence.yml index f92cf60c5..5ac071ea8 100644 --- a/rules/linux/debian_family/crontab_persistence.yml +++ b/rules/linux/debian_family/crontab_persistence.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -24,14 +24,6 @@ description: | 5. Review other persistence mechanisms on the host 6. If unauthorized, remove the cron entry and investigate the source of compromise where: | - (contains("log.process", "crontab") || contains("log.process", "cron") || contains("log.process", "atd")) && - (contains("log.message", "REPLACE") || - contains("log.message", "INSTALL") || - contains("log.message", "cron.d") || - contains("log.message", "crontab") || - contains("log.message", "at job") || - (contains("log.message", "EDIT") && contains("log.message", "crontab")) || - (contains("log.message", "BEGIN EDIT") || contains("log.message", "END EDIT"))) -groupBy: - - origin.host - - origin.user + contains("origin.process", "crontab") && (contains("log.message", "REPLACE") || contains("log.message", "INSTALL") || contains("log.message", "LIST") || contains("log.message", "EDIT")) +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/debian_specific_rootkits.yml b/rules/linux/debian_family/debian_specific_rootkits.yml index fb4a12b88..bf79c5d41 100644 --- a/rules/linux/debian_family/debian_specific_rootkits.yml +++ b/rules/linux/debian_family/debian_specific_rootkits.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -27,32 +27,6 @@ description: | 7. Analyze network connections for command and control communications 8. Update security tools and perform full system scan where: | - (contains("log.file_path", "/usr/bin/passwd") && - equals("log.event_type", "file_modify") && - !equals("log.process_name", "dpkg")) || - (contains("log.file_path", "/etc/ld.so.preload") && - oneOf("log.event_type", ["file_create", "file_modify"])) || - (oneOf("log.process_name", ["reptile", "bdvl", "azazel", "jynx", "xorddos"]) || - contains("log.file_path", "reptile") || - contains("log.file_path", "bdvl")) || - (contains("log.command_line", "insmod") && - (contains("log.command_line", "rootkit") || - contains("log.command_line", "hide") || - contains("log.command_line", "backdoor"))) || - (contains("log.file_path", "/proc/") && - contains("log.file_path", "/maps") && - contains("log.message", "deleted")) || - (oneOf("log.network_port", [31337, 12345, 6666]) && - equals("log.event_type", "network_listen")) || - (contains("log.file_path", "/dev/ptmx") && - equals("log.event_type", "file_create") && - !equals("log.user", "root")) || - (contains("log.message", "LKM") && - (contains("log.message", "rootkit") || - contains("log.message", "hiding"))) || - (regexMatch("log.file_path", "/lib/modules/.*/.*\\.ko") && - equals("log.event_type", "file_create") && - !equals("log.process_name", "dpkg")) -groupBy: - - lastEvent.log.process_name - - origin.host + regexMatch("origin.process", "/(reptile|bdvl|azazel|jynx|xorddos)") || (contains("origin.command", "insmod") && regexMatch("origin.command", "(rootkit|hide|backdoor)")) || (contains("origin.command", "ld.so.preload") && regexMatch("origin.command", "(>>|tee|echo)")) +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/ebpf_rootkit_detection.yml b/rules/linux/debian_family/ebpf_rootkit_detection.yml index 58d030444..a6d2e36e2 100644 --- a/rules/linux/debian_family/ebpf_rootkit_detection.yml +++ b/rules/linux/debian_family/ebpf_rootkit_detection.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -24,15 +24,6 @@ description: | 5. Investigate for signs of process hiding or network traffic manipulation 6. If malicious, reboot the system and perform forensic analysis where: | - (contains("log.message", "bpf(") || contains("log.message", "BPF") || - contains("log.message", "ebpf") || contains("log.message", "bpftool")) && - (contains("log.message", "PROG_LOAD") || contains("log.message", "prog_load") || - contains("log.message", "BPF_PROG_TYPE_TRACING") || - contains("log.message", "BPF_PROG_TYPE_KPROBE") || - contains("log.message", "BPF_PROG_TYPE_XDP") || - contains("log.message", "attached") || contains("log.message", "loaded")) && - !(contains("log.process", "systemd") || contains("log.process", "cilium") || - contains("log.process", "falco") || contains("log.process", "bpftrace")) -groupBy: - - origin.host - - origin.user + regexMatch("origin.command", "bpftool .*(prog|map).*(load|loadall|attach)") && !regexMatch("origin.command", "(cilium|falco|bpftrace)") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/ld_preload_hijacking.yml b/rules/linux/debian_family/ld_preload_hijacking.yml index 0cb39b970..bbea23810 100644 --- a/rules/linux/debian_family/ld_preload_hijacking.yml +++ b/rules/linux/debian_family/ld_preload_hijacking.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -25,12 +25,6 @@ description: | 6. Remove the malicious preload entry and the shared library 7. Audit all running processes for injected libraries where: | - (contains("log.message", "ld.so.preload") || - contains("log.message", "LD_PRELOAD") || - contains("log.message", "ld.so.conf")) && - (contains("log.message", "modified") || contains("log.message", "write") || - contains("log.message", "opened") || contains("log.message", "export") || - contains("log.message", "changed")) -groupBy: - - origin.host - - origin.user + (contains("origin.command", "ld.so.preload") || contains("origin.command", "LD_PRELOAD") || contains("origin.command", "ld.so.conf")) && regexMatch("origin.command", "(>>|tee|echo|sed |cp |mv )") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/process_masquerading.yml b/rules/linux/debian_family/process_masquerading.yml index 5e0924915..d19fd9908 100644 --- a/rules/linux/debian_family/process_masquerading.yml +++ b/rules/linux/debian_family/process_masquerading.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -23,11 +23,6 @@ description: | 5. If confirmed malicious, terminate the process and remove the binary 6. Check for other masquerading processes on the system where: | - (contains("log.message", "/proc/self/comm") || - contains("log.message", "/proc/self/exe") || - contains("log.message", "prctl") && contains("log.message", "PR_SET_NAME")) && - (contains("log.message", "write") || contains("log.message", "modified") || - contains("log.message", "open")) -groupBy: - - origin.host - - origin.user + regexMatch("log.execve.a0", "^\\[(kworker|kthreadd|ksoftirqd|migration|rcu_|kswapd|watchdog|kdevtmpfs|kauditd|kcompactd|kintegrityd|khugepaged|kblockd|kthrotld)") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/reverse_shell_detection.yml b/rules/linux/debian_family/reverse_shell_detection.yml index 2f63f76c8..eb75ebcb0 100644 --- a/rules/linux/debian_family/reverse_shell_detection.yml +++ b/rules/linux/debian_family/reverse_shell_detection.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -25,16 +25,6 @@ description: | 6. Perform full incident response on the compromised host 7. Block the C2 IP address at the network perimeter where: | - regexMatch("log.message", "(?i)bash\\s+-i\\s+>&\\s+/dev/tcp/") || - regexMatch("log.message", "(?i)python[23]?\\s+-c\\s+.*socket.*connect") || - regexMatch("log.message", "(?i)nc\\s+(-e|--exec|-c)\\s+") || - regexMatch("log.message", "(?i)ncat\\s+(-e|--exec)\\s+") || - regexMatch("log.message", "(?i)socat\\s+.*exec.*tcp") || - regexMatch("log.message", "(?i)perl\\s+-e\\s+.*socket.*INET") || - regexMatch("log.message", "(?i)php\\s+-r\\s+.*fsockopen") || - regexMatch("log.message", "(?i)ruby\\s+-rsocket\\s+-e") || - regexMatch("log.message", "(?i)mkfifo\\s+.*nc\\s+") || - regexMatch("log.message", "(?i)\\b0<&\\d+-;exec\\s+\\d+<>/dev/tcp/") -groupBy: - - origin.host - - origin.ip + regexMatch("origin.command", "(bash -i.*/dev/tcp|python.* -c .*socket.*connect|nc .*-e|ncat .*-e|socat.*exec.*tcp|perl.*-e.*socket|php.*-r.*fsockopen|ruby.*-rsocket)") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/shell_rc_file_modification.yml b/rules/linux/debian_family/shell_rc_file_modification.yml index b1e98cbd1..a80b175dd 100644 --- a/rules/linux/debian_family/shell_rc_file_modification.yml +++ b/rules/linux/debian_family/shell_rc_file_modification.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -23,12 +23,6 @@ description: | 5. Review all shell RC files for the affected user and system-wide profiles 6. Remove malicious entries and investigate the compromise vector where: | - (contains("log.message", ".bashrc") || contains("log.message", ".bash_profile") || - contains("log.message", ".profile") || contains("log.message", "/etc/profile.d/") || - contains("log.message", ".zshrc") || contains("log.message", ".zprofile") || - contains("log.message", "/etc/bash.bashrc") || contains("log.message", "/etc/profile")) && - (contains("log.message", "modified") || contains("log.message", "opened for writing") || - contains("log.message", "write") || contains("log.message", "changed")) -groupBy: - - origin.host - - origin.user + regexMatch("origin.command", "(tee|>>|cp |sed |vi |vim |nano |echo).*(.bashrc|.bash_profile|.zshrc|.profile|/etc/profile)") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/ssh_authorized_keys_modification.yml b/rules/linux/debian_family/ssh_authorized_keys_modification.yml index 2aaabd9fa..39974c826 100644 --- a/rules/linux/debian_family/ssh_authorized_keys_modification.yml +++ b/rules/linux/debian_family/ssh_authorized_keys_modification.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -25,10 +25,6 @@ description: | 6. Remove unauthorized keys and rotate affected credentials 7. Monitor for subsequent SSH connections from unknown sources where: | - (contains("log.message", "authorized_keys") || contains("log.message", "authorized_keys2")) && - (contains("log.message", "modified") || contains("log.message", "opened for writing") || - contains("log.message", "changed") || contains("log.process", "sshd") || - contains("log.message", ".ssh") && contains("log.message", "write")) -groupBy: - - origin.host - - origin.user + contains("origin.command", "authorized_keys") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/ssh_tunneling_port_forwarding.yml b/rules/linux/debian_family/ssh_tunneling_port_forwarding.yml index fbeab4f91..c165ff945 100644 --- a/rules/linux/debian_family/ssh_tunneling_port_forwarding.yml +++ b/rules/linux/debian_family/ssh_tunneling_port_forwarding.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -24,14 +24,6 @@ description: | 5. If unauthorized, terminate the SSH session and block the connection 6. Review SSH configuration to restrict port forwarding if not needed where: | - contains("log.process", "sshd") && - (regexMatch("log.message", "(?i)ssh\\s+.*-[LRD]\\s+") || - contains("log.message", "port forwarding") || - contains("log.message", "Local forwarding") || - contains("log.message", "Remote forwarding") || - contains("log.message", "Dynamic forwarding") || - contains("log.message", "tunnel") || - regexMatch("log.message", "(?i)open forward.*port")) -groupBy: - - origin.host - - origin.ip + regexMatch("origin.command", "ssh .*-[LRD] ") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/suspicious_binary_in_tmp.yml b/rules/linux/debian_family/suspicious_binary_in_tmp.yml index 1e3508584..f7a2cf478 100644 --- a/rules/linux/debian_family/suspicious_binary_in_tmp.yml +++ b/rules/linux/debian_family/suspicious_binary_in_tmp.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -24,14 +24,6 @@ description: | 6. Remove the binary and investigate the initial access vector 7. Scan the system for additional indicators of compromise where: | - (regexMatch("log.message", "(?i)(exec|run|start|command|process).*(/tmp/|/dev/shm/|/var/tmp/)") || - regexMatch("log.message", "(?i)(/tmp/|/dev/shm/|/var/tmp/)[^ ]+\\s+(started|executed|running)") || - (contains("log.message", "EXECVE") && - (contains("log.message", "/tmp/") || contains("log.message", "/dev/shm/") || - contains("log.message", "/var/tmp/")))) && - !(contains("log.process", "apt") || contains("log.process", "dpkg") || - contains("log.process", "yum") || contains("log.process", "dnf") || - contains("log.process", "pip")) -groupBy: - - origin.host - - origin.user + regexMatch("origin.process", "^/(tmp|dev/shm|var/tmp)/") && !regexMatch("origin.process", "(apt|dpkg|yum|dnf|pip)") +deduplicateBy: + - dataSource diff --git a/rules/linux/debian_family/systemd_timer_persistence.yml b/rules/linux/debian_family/systemd_timer_persistence.yml index 42817719b..7b94b09ea 100644 --- a/rules/linux/debian_family/systemd_timer_persistence.yml +++ b/rules/linux/debian_family/systemd_timer_persistence.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -24,11 +24,6 @@ description: | 5. Compare against baseline of known legitimate timers 6. If unauthorized, disable the timer and investigate where: | - (contains("log.process", "systemctl") || contains("log.process", "systemd")) && - contains("log.message", ".timer") && - (contains("log.message", "Created symlink") || contains("log.message", "enable") || - contains("log.message", "started") || contains("log.message", "Reloading") || - contains("log.message", "loaded")) -groupBy: - - origin.host - - origin.user + contains("origin.command", "systemctl") && contains("origin.command", ".timer") && regexMatch("origin.command", "(enable|reenable|start|link)") +deduplicateBy: + - dataSource diff --git a/rules/linux/file_transfer_or_listener_established_via_netcat.yml b/rules/linux/file_transfer_or_listener_established_via_netcat.yml index 69956bea6..664b7c637 100644 --- a/rules/linux/file_transfer_or_listener_established_via_netcat.yml +++ b/rules/linux/file_transfer_or_listener_established_via_netcat.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.1 +# Rule version v1.0.2 dataTypes: - "linux" @@ -9,14 +9,14 @@ impact: availability: 3 category: "Execution" technique: "T1059.004 - Command and Scripting Interpreter" -adversary: target +adversary: origin description: "A netcat process is engaging in network activity on a Linux host. Netcat is often used as a persistence mechanism by exporting a reverse shell or by serving a shell on a listening port. Netcat is also sometimes used for data exfiltration." references: - "https://attack.mitre.org/tactics/TA0002/" - "https://attack.mitre.org/techniques/T1059/004/" -where: regexMatch("log.message", "((nc|ncat|netcat|netcat.openbsd|netcat.traditional) (-l|-p|-lp|(-e)(.+)(\\/bin\\/bash|\\/bin\\/sh)|(\\/bin\\/bash|\\/bin\\/sh)(.+)(-e)))") -groupBy: - - target.ip - - target.user +where: | + regexMatch("origin.command", "(nc|ncat|netcat|netcat.openbsd|netcat.traditional) (-l|-lp|-p|-e)") +deduplicateBy: + - dataSource diff --git a/rules/linux/kde_autostart_modification.yml b/rules/linux/kde_autostart_modification.yml index 77b1e782c..2c564360f 100644 --- a/rules/linux/kde_autostart_modification.yml +++ b/rules/linux/kde_autostart_modification.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.1 +# Rule version v1.0.2 dataTypes: - "linux" @@ -15,7 +15,7 @@ description: "Identifies the creation or modification of a K Desktop Environment references: - "https://attack.mitre.org/tactics/TA0003/" - "https://attack.mitre.org/techniques/T1547/" -where: regexMatch("log.message", "sh,desktop") && regexMatch("log.message", "(/home/(.+)/.config/autostart/|/root/.config/autostart/|/home/(.+)/.kde/Autostart/|/root/.kde/Autostart/|/home/(.+)/.kde4/Autostart/|/root/.kde4/Autostart/|/home/(.+)/.kde/share/autostart/|/root/.kde/share/autostart/|/home/(.+)/.kde4/share/autostart/|/root/.kde4/share/autostart/|/home/(.+)/.local/share/autostart/|/root/.local/share/autostart/|/home/(.+)/.config/autostart-scripts/|/root/.config/autostart-scripts/|/etc/xdg/autostart/|/usr/share/autostart/)") && !regexMatch("log.message", "(yum|dpkg|install|dnf|teams|yum-cron|dnf-automatic)") -groupBy: - - origin.ip - - origin.user +where: | + regexMatch("origin.command", "(.config/autostart/|.local/share/autostart/|/etc/xdg/autostart/|.config/autostart-scripts/)") && !regexMatch("origin.command", "(dpkg|apt|dnf|yum)") +deduplicateBy: + - dataSource diff --git a/rules/linux/kernel_module_removal.yml b/rules/linux/kernel_module_removal.yml index 24f4ef34b..e1f482665 100644 --- a/rules/linux/kernel_module_removal.yml +++ b/rules/linux/kernel_module_removal.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.1 +# Rule version v1.0.2 dataTypes: - "linux" @@ -15,7 +15,7 @@ description: "Kernel modules are pieces of code that can be loaded and unloaded references: - "https://attack.mitre.org/tactics/TA0005/" - "https://attack.mitre.org/techniques/T1562/001/" -where: regexMatch("log.message", "(modprobe(.+)sudo(.+)(-r|--remove)|modprobe(.+)(-r|--remove)(.+)sudo|sudo(.+)modprobe(.+)(-r|--remove)|sudo(.+)(-r|--remove)(.+)modprobe|(-r|--remove)modprobe(.+)sudo|(-r|--remove)(.+)sudo(.+)modprobe)") -groupBy: - - origin.ip - - origin.user +where: | + regexMatch("origin.command", "modprobe .*(-r|--remove)") +deduplicateBy: + - dataSource diff --git a/rules/linux/modify_ssh_binaries.yml b/rules/linux/modify_ssh_binaries.yml index 8904fadb3..de0b25792 100644 --- a/rules/linux/modify_ssh_binaries.yml +++ b/rules/linux/modify_ssh_binaries.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -15,7 +15,7 @@ description: "Adversaries may modify SSH related binaries for persistence or cre references: - "https://attack.mitre.org/tactics/TA0003/" - "https://attack.mitre.org/techniques/T1543/" -where: regexMatch("log.message", "libkeyutils.so") && !regexMatch("log.message", "(dpkg|yum|dnf|dnf-automatic)") && regexMatch("log.message", "(/usr/sbin/sshd|/usr/bin/ssh|/usr/bin/sftp|/usr/bin/scp)") -groupBy: - - origin.ip - - origin.user +where: | + contains("origin.command", "libkeyutils.so") || (regexMatch("origin.command", "(/usr/sbin/sshd|/usr/bin/ssh|/usr/bin/sftp|/usr/bin/scp)") && regexMatch("origin.command", "(cp |mv |install |tee |>>|dd )")) +deduplicateBy: + - dataSource diff --git a/rules/linux/perl_tty_shell.yml b/rules/linux/perl_tty_shell.yml index d9f4b240d..344ad7245 100644 --- a/rules/linux/perl_tty_shell.yml +++ b/rules/linux/perl_tty_shell.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -15,7 +15,7 @@ description: "Identifies when a terminal (tty) is spawned via Perl. Attackers ma references: - "https://attack.mitre.org/tactics/TA0002/" - "https://attack.mitre.org/techniques/T1059/" -where: regexMatch("log.message", "(perl)") && regexMatch("log.message", "(exec \\'/bin/sh\\';|exec \\'/bin/dash\\';|exec \\'/bin/bash\\';)") -groupBy: - - origin.ip - - origin.user +where: | + contains("origin.command", "perl") && regexMatch("origin.command", "exec.{0,2}/bin/(sh|dash|bash)") +deduplicateBy: + - dataSource diff --git a/rules/linux/pkexec_envar_hijack.yml b/rules/linux/pkexec_envar_hijack.yml index 57c33a87d..06ed2b489 100644 --- a/rules/linux/pkexec_envar_hijack.yml +++ b/rules/linux/pkexec_envar_hijack.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -15,7 +15,7 @@ description: "Identifies an attempt to exploit a local privilege escalation in p references: - "https://attack.mitre.org/tactics/TA0004/" - "https://attack.mitre.org/techniques/T1068/" -where: contains("log.message", "pkexec") && (contains("log.message", "SHELL variable") || contains("log.message", "PATH variable") || contains("log.message", "XAUTHORITY") || regexMatch("log.message", "The value for the SHELL variable was not found")) -groupBy: - - origin.ip - - origin.user +where: | + contains("log.message", "with NULL argv") || contains("log.message", "The value for the SHELL variable was not found") || ((contains("origin.process", "pkexec") || contains("log.syslogIdentifier", "pkexec")) && (contains("log.message", "SHELL variable") || contains("log.message", "PATH variable") || contains("log.message", "XAUTHORITY"))) +deduplicateBy: + - dataSource diff --git a/rules/linux/python_tty_shell.yml b/rules/linux/python_tty_shell.yml index bea524be3..f6116321e 100644 --- a/rules/linux/python_tty_shell.yml +++ b/rules/linux/python_tty_shell.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -15,7 +15,7 @@ description: "Identifies when a terminal (tty) is spawned via Python. Attackers references: - "https://attack.mitre.org/tactics/TA0002/" - "https://attack.mitre.org/techniques/T1059/" -where: contains("log.message", "python") && regexMatch("log.message", "(import pty; pty.spawn\\(\\'\\/bin\\/(sh|dash|bash)\\'\\))") -groupBy: - - origin.ip - - origin.user +where: | + contains("origin.command", "python") && regexMatch("origin.command", "pty.spawn\\(.{0,2}/bin/(sh|dash|bash)") +deduplicateBy: + - dataSource diff --git a/rules/linux/reverse_shell_via_named_pipe.yml b/rules/linux/reverse_shell_via_named_pipe.yml index 09f2e8785..6f06c53fa 100644 --- a/rules/linux/reverse_shell_via_named_pipe.yml +++ b/rules/linux/reverse_shell_via_named_pipe.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -18,7 +18,7 @@ description: "Identifies a reverse shell via the abuse of named pipes on Linux w references: - "https://attack.mitre.org/tactics/TA0002/" - "https://attack.mitre.org/techniques/T1059/004/" -where: regexMatch("log.message", "((sh|bash|openssl) (-i|-connect))") && exists("log.host.id") -groupBy: - - origin.ip - - origin.user +where: | + regexMatch("origin.command", "(bash -i|sh -i|openssl.*-connect|mkfifo.*nc )") +deduplicateBy: + - dataSource diff --git a/rules/linux/rhel_family/boot_loader_attacks.yml b/rules/linux/rhel_family/boot_loader_attacks.yml index 31578fc81..aba84d4a9 100644 --- a/rules/linux/rhel_family/boot_loader_attacks.yml +++ b/rules/linux/rhel_family/boot_loader_attacks.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -25,14 +25,6 @@ description: | 6. If unauthorized, isolate the system and perform forensic analysis 7. Verify boot process integrity and consider restoring from known good backups where: | - (contains("log.file_path", "/boot/grub2/") && oneOf("log.action", ["modify", "write", "delete"])) || - (equals("log.file_path", "/etc/default/grub") && oneOf("log.action", ["modify", "write"])) || - (contains("log.command", "grub2-mkconfig")) || - (contains("log.command", "grub2-install")) || - (contains("log.file_path", "/boot/vmlinuz") && oneOf("log.action", ["modify", "replace"])) || - (contains("log.file_path", "/boot/initramfs") && oneOf("log.action", ["modify", "replace"])) || - (equals("log.event_type", "boot_loader_modification")) || - (exists("log.module_name") && equals("log.action", "kernel_module_load") && contains("log.module_path", "/boot/")) -groupBy: - - lastEvent.log.file_path - - origin.host + regexMatch("origin.command", "(grub-mkconfig|grub2-mkconfig|update-grub|grub-install|grub2-install)") +deduplicateBy: + - dataSource diff --git a/rules/linux/rhel_family/container_platform_attacks.yml b/rules/linux/rhel_family/container_platform_attacks.yml index 15dcdb805..0bb5fe74d 100644 --- a/rules/linux/rhel_family/container_platform_attacks.yml +++ b/rules/linux/rhel_family/container_platform_attacks.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -25,23 +25,6 @@ description: | 6. Consider isolating the affected container and host system 7. Update container security policies and runtime configurations as needed where: | - (oneOf("origin.process", ["docker", "podman", "crio", "containerd"]) || - oneOf("origin.process", ["dockerd", "podman", "crio", "containerd"]) || - oneOf("log.service", ["docker", "podman", "crio", "containerd"]) || - oneOf("log.process_name", ["dockerd", "podman", "crio", "containerd"])) && - ( - contains("log.message", "container escape") || - contains("log.message", "privilege escalation") || - contains("log.message", "unauthorized pull") || - contains("log.message", "runtime manipulation") || - contains("log.message", "seccomp violation") || - contains("log.message", "AppArmor violation") || - contains("log.message", "SELinux denial") || - (equals("action", "exec") && contains("log.command", "/proc/self/exe")) || - (equals("action", "mount") && contains("log.path", "/sys")) || - equals("log.event_type", "container_breakout") || - (oneOf("log.syscall", ["mount", "pivot_root", "chroot"]) && equals("log.result", "denied")) - ) -groupBy: - - lastEvent.log.container_id - - origin.host + regexMatch("origin.command", "(docker|podman) (run|create|exec).*(--privileged|--pid=host|--net=host|/var/run/docker.sock|-v /:)") || (contains("origin.command", "nsenter") && contains("origin.command", "--target")) +deduplicateBy: + - dataSource diff --git a/rules/linux/rhel_family/rhel_specific_malware.yml b/rules/linux/rhel_family/rhel_specific_malware.yml index dc596897f..df43abc87 100644 --- a/rules/linux/rhel_family/rhel_specific_malware.yml +++ b/rules/linux/rhel_family/rhel_specific_malware.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -28,16 +28,6 @@ description: | 9. Review access logs to determine initial compromise method 10. Implement additional monitoring for similar attack patterns where: | - (oneOf("log.process_name", ["reptile", "bdvl", "kovid", "suterusu", "rooty", "vlany"]) && equals("log.action", "process_create")) || - ((contains("log.file_path", "/proc/kallsyms") || contains("log.file_path", "/dev/kmem") || contains("log.file_path", "/dev/mem")) && oneOf("log.action", ["read", "write"])) || - (exists("log.rpm_package") && oneOf("log.rpm_signature", ["NOKEY", "NOTTRUSTED", "BAD"])) || - ((contains("log.command", "LD_PRELOAD=") || contains("log.command", "LD_LIBRARY_PATH=")) && (contains("log.library_path", "/tmp/") || contains("log.library_path", "/var/tmp/") || contains("log.library_path", "/dev/shm/"))) || - (exists("log.kernel_module") && (contains("log.module_path", "/tmp/") || contains("log.module_path", "/var/tmp/") || contains("log.module_path", "/dev/shm/")) && equals("log.action", "load")) || - (equals("log.process_injection", "true") && oneOf("log.target_process", ["systemd", "sshd", "httpd", "firewalld"])) || - (oneOf("log.file_hash", ["known_malware_hash_1", "known_malware_hash_2"])) || - (exists("log.network_connection") && oneOf("log.destination_port", [4444, 5555, 6666, 7777, 8888]) && oneOf("log.process_name", ["bash", "sh", "python", "perl"])) || - (oneOf("log.syscall", ["ptrace", "process_vm_write", "setns"]) && equals("log.target_pid", "1")) || - (contains("log.selinux_context", "unconfined") && (contains("log.process_name", "backdoor") || contains("log.process_name", "rootkit") || contains("log.process_name", "miner"))) -groupBy: - - lastEvent.log.process_name - - origin.host + regexMatch("origin.process", "/(reptile|bdvl|kovid|suterusu|rooty|vlany|azazel|jynx|xorddos)") +deduplicateBy: + - dataSource diff --git a/rules/linux/rhel_family/systemd_unit_file_attacks.yml b/rules/linux/rhel_family/systemd_unit_file_attacks.yml index 2fe78ac35..5bc75a176 100644 --- a/rules/linux/rhel_family/systemd_unit_file_attacks.yml +++ b/rules/linux/rhel_family/systemd_unit_file_attacks.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -26,17 +26,6 @@ description: | 7. Look for persistence mechanisms in systemd configuration 8. Consider isolating the affected system if malicious activity is confirmed where: | - (equals("log.process", "systemd") || equals("log.process", "systemctl")) && - ( - (contains("log.message", "Failed to parse user") && regexMatch("log.message", "[0-9].*")) || - (contains("log.message", "unit file") && - (contains("log.message", "ExecStart") || contains("log.message", "ExecStartPre") || contains("log.message", "ExecStartPost")) && - (contains("log.message", "/tmp/") || contains("log.message", "/dev/shm/") || contains("log.message", "bash -c") || contains("log.message", "sh -c"))) || - (contains("log.message", "User=") && regexMatch("log.message", "User=[0-9].*")) || - (contains("log.message", "systemd-generator") && (contains("log.message", "created") || contains("log.message", "modified"))) || - contains("log.message", "NoNewPrivileges=false") || - contains("log.message", "ProtectSystem=false") - ) -groupBy: - - origin.host - - origin.user + (contains("log.message", "Failed at step EXEC") || contains("log.message", "Unable to locate executable") || contains("log.message", "ExecStart")) && (contains("log.message", "/tmp/") || contains("log.message", "/dev/shm/")) +deduplicateBy: + - dataSource diff --git a/rules/linux/tunneling_via_earthworm.yml b/rules/linux/tunneling_via_earthworm.yml index 74c06b790..21d18c552 100644 --- a/rules/linux/tunneling_via_earthworm.yml +++ b/rules/linux/tunneling_via_earthworm.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -9,13 +9,13 @@ impact: availability: 2 category: "Command and Control" technique: "T1572 - Protocol Tunneling" -adversary: target +adversary: origin description: "Identifies the execution of the EarthWorm tunneler. Adversaries may tunnel network communications to and from a victim system within a separate protocol to avoid detection and network filtering, or to enable access to otherwise unreachable systems." references: - "https://attack.mitre.org/tactics/TA0011/" - "https://attack.mitre.org/techniques/T1572/" -where: contains("log.message", "-s") && contains("log.message", "-d") && contains("log.message", "rssocks") -groupBy: - - target.ip - - target.user +where: | + contains("origin.command", "-s") && contains("origin.command", "-d") && contains("origin.command", "rssocks") +deduplicateBy: + - dataSource diff --git a/rules/linux/unshare_namesapce_manipulation.yml b/rules/linux/unshare_namesapce_manipulation.yml index fc3a587b7..3d7691944 100644 --- a/rules/linux/unshare_namesapce_manipulation.yml +++ b/rules/linux/unshare_namesapce_manipulation.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -16,7 +16,7 @@ description: "Identifies suspicious usage of unshare to manipulate system names references: - "https://attack.mitre.org/tactics/TA0004/" - "https://attack.mitre.org/techniques/T1543/" -where: contains("log.message", "unshare") && !contains("log.message", "/usr/bin/snap") && !regexMatch("log.message", "(\\/usr\\/bin\\/udevadm|\\/lib\\/systemd\\/systemd-udevd|\\/usr\\/bin\\/unshare)") -groupBy: - - origin.ip - - origin.user +where: | + contains("origin.command", "unshare") && !contains("origin.command", "/usr/bin/snap") && !regexMatch("origin.command", "(udevadm|systemd-udevd)") +deduplicateBy: + - dataSource diff --git a/rules/linux/user_added_to_admin_group.yml b/rules/linux/user_added_to_admin_group.yml index 884d0dc4c..c3c0dd289 100644 --- a/rules/linux/user_added_to_admin_group.yml +++ b/rules/linux/user_added_to_admin_group.yml @@ -1,4 +1,4 @@ -# Rule version v1.0.0 +# Rule version v1.0.1 dataTypes: - linux @@ -14,7 +14,7 @@ description: "Detects when a user has been added to the administrators group (su references: - "https://attack.mitre.org/tactics/TA0004" - "https://attack.mitre.org/techniques/T1484/" -where: regexMatch("log.message", "(((adduser|useradd|usermod)(.+)([Aa]dded user|new user|add)(.+)to(.+)group)(.+)sudo)") && contains("log.message", "usermod -aG sudo") -groupBy: - - origin.ip - - origin.user +where: | + regexMatch("origin.command", "(usermod.*-aG.*sudo|usermod.*-aG.*admin|gpasswd -a .* sudo|adduser .* sudo)") +deduplicateBy: + - dataSource