Kernel Module Load from Unusual Location

This rule detects the loading of a kernel module from an unusual location. Threat actors may use this technique to maintain persistence on a system by loading a kernel module into the kernel namespace. This behavior is strongly related to the presence of a rootkit on the system.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/02/20"
  3integration = ["endpoint"]
  4maturity = "production"
  5updated_date = "2026/02/20"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10This rule detects the loading of a kernel module from an unusual location. Threat actors may use
 11this technique to maintain persistence on a system by loading a kernel module into the kernel namespace.
 12This behavior is strongly related to the presence of a rootkit on the system.
 13"""
 14from = "now-9m"
 15index = ["logs-endpoint.events.process*"]
 16language = "eql"
 17license = "Elastic License v2"
 18name = "Kernel Module Load from Unusual Location"
 19note = """## Triage and analysis
 20
 21> **Disclaimer**:
 22> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
 23
 24### Investigating Kernel Module Load from Unusual Location
 25
 26This rule detects attempts to load Linux kernel modules from atypical directories, which can indicate an attacker trying to run code in kernel space for stealth and long-term persistence. Adversaries often drop a malicious `.ko` into writable paths like `/tmp` or `/dev/shm` after initial access, then use `insmod` or `modprobe` to insert it and hide processes, files, or network activity as a rootkit.
 27
 28### Possible investigation steps
 29
 30- Capture the full command line and resolve any referenced `.ko` path, then collect the module file for hashing and static analysis to determine provenance and known-malware matches.  
 31- Confirm whether the module is currently loaded by querying `lsmod`/`/proc/modules`, then map it to its on-disk location with `modinfo -n <module>` (or `/sys/module/<module>/sections/*`) to validate it was loaded from the suspicious directory.  
 32- Review recent kernel and audit telemetry (`dmesg`, `/var/log/kern.log`, `journalctl -k`, and any audit records) around the event time for insertion messages, signature/taint indicators, and any follow-on errors suggesting tampering.  
 33- Identify the initiating user/session and execution chain (parent process tree, TTY/SSH source, container context), then determine whether the action aligns with legitimate admin activity or coincides with other compromise signals on the host.  
 34- Hunt for persistence and repeatability by checking for recurring module-load attempts and inspecting boot-time and scheduled execution paths (systemd units, init scripts, cron, rc.local) that could reload the module after reboot.
 35
 36### False positive analysis
 37
 38- A system administrator or automated maintenance workflow may build or test an out-of-tree kernel module and load it with `insmod`/`modprobe` from a staging directory such as `/tmp`, `/root`, or `/mnt` before installing it into standard module paths.  
 39- A legitimate bootstrapping or recovery operation may load a required driver module from nonstandard media or temporary runtime locations (e.g., `/boot`, `/run`, `/var/run`, or `/mnt`) during troubleshooting, initramfs/early-boot tasks, or mounting encrypted/storage devices.
 40
 41### Response and remediation
 42
 43- Isolate the affected Linux host from the network and disable external access (e.g., revoke SSH keys or block inbound SSH) to prevent additional module loads or lateral movement while preserving evidence.  
 44- If the suspicious module is currently loaded, record `lsmod` and `modinfo` output, then unload it where safe (`modprobe -r <name>`/`rmmod <name>`) and quarantine the corresponding `.ko` from the unusual path (e.g., `/tmp`, `/dev/shm`, `/home`, `/mnt`) for hashing and malware analysis.  
 45- Remove persistence mechanisms that would reload the module by deleting or disabling any related systemd units, init scripts, cron entries, and boot-time hooks, and validate `/etc/modules-load.d/`, `/lib/modules/$(uname -r)/`, and `depmod` outputs for unauthorized additions.  
 46- Recover the host by restoring known-good kernel/module packages and rebuilding the initramfs, then reboot and verify no unexpected modules remain in `/proc/modules` and no new load attempts occur from writable directories.  
 47- Escalate immediately to IR/forensics and consider full host rebuild if the module is unsigned/unknown, the kernel is tainted, module removal fails, or post-reboot evidence indicates stealth behavior consistent with a rootkit.  
 48- Harden by restricting module loading (enable Secure Boot/module signature enforcement where supported, set `kernel.modules_disabled=1` after boot on fixed-function systems, and limit `CAP_SYS_MODULE` to trusted admins), and enforce file integrity monitoring/permissions to prevent `.ko` creation in world-writable locations."""
 49references = [
 50    "https://decoded.avast.io/davidalvarez/linux-threat-hunting-syslogk-a-kernel-rootkit-found-under-development-in-the-wild/",
 51]
 52risk_score = 73
 53rule_id = "d54b649d-46d0-4b4c-a9a7-1bc9fc458d3c"
 54setup = """## Setup
 55
 56This rule requires data coming in from Elastic Defend.
 57
 58### Elastic Defend Integration Setup
 59Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
 60
 61#### Prerequisite Requirements:
 62- Fleet is required for Elastic Defend.
 63- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
 64
 65#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
 66- Go to the Kibana home page and click "Add integrations".
 67- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
 68- Click "Add Elastic Defend".
 69- Configure the integration name and optionally add a description.
 70- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
 71- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
 72- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
 73- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
 74For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
 75- Click "Save and Continue".
 76- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
 77For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
 78"""
 79severity = "high"
 80tags = [
 81    "Domain: Endpoint",
 82    "OS: Linux",
 83    "Use Case: Threat Detection",
 84    "Tactic: Persistence",
 85    "Tactic: Defense Evasion",
 86    "Threat: Rootkit",
 87    "Data Source: Elastic Defend",
 88    "Resources: Investigation Guide",
 89]
 90timestamp_override = "event.ingested"
 91type = "eql"
 92query = '''
 93process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
 94  (process.name == "kmod" and process.args == "insmod" and process.args like~ "*.ko*") or
 95  (process.name == "kmod" and process.args == "modprobe" and not process.args in ("-r", "--remove")) or
 96  (process.name == "insmod" and process.args like~ "*.ko*") or
 97  (process.name == "modprobe" and not process.args in ("-r", "--remove"))
 98) and (
 99  process.working_directory like (
100    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/home/*/*", "/root/*",
101    "/var/www/*", "/boot/*", "/srv/*", "/mnt/*"
102  ) or
103  process.parent.working_directory like (
104    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/home/*/*", "/root/*",
105    "/var/www/*", "/boot/*", "/srv/*", "/mnt/*"
106  ) or
107  process.args like (
108    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/home/*/*", "/root/*",
109    "/var/www/*", "/boot/*", "/srv/*", "/mnt/*", "./*"
110  )
111) and
112not (
113  process.parent.executable == "/usr/bin/podman" or
114  process.working_directory like "/tmp/newroot"
115)
116'''
117
118[[rule.threat]]
119framework = "MITRE ATT&CK"
120
121[[rule.threat.technique]]
122id = "T1547"
123name = "Boot or Logon Autostart Execution"
124reference = "https://attack.mitre.org/techniques/T1547/"
125
126[[rule.threat.technique.subtechnique]]
127id = "T1547.006"
128name = "Kernel Modules and Extensions"
129reference = "https://attack.mitre.org/techniques/T1547/006/"
130
131[rule.threat.tactic]
132id = "TA0003"
133name = "Persistence"
134reference = "https://attack.mitre.org/tactics/TA0003/"
135
136[[rule.threat]]
137framework = "MITRE ATT&CK"
138
139[[rule.threat.technique]]
140id = "T1014"
141name = "Rootkit"
142reference = "https://attack.mitre.org/techniques/T1014/"
143
144[rule.threat.tactic]
145id = "TA0005"
146name = "Defense Evasion"
147reference = "https://attack.mitre.org/tactics/TA0005/"

Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating Kernel Module Load from Unusual Location

This rule detects attempts to load Linux kernel modules from atypical directories, which can indicate an attacker trying to run code in kernel space for stealth and long-term persistence. Adversaries often drop a malicious .ko into writable paths like /tmp or /dev/shm after initial access, then use insmod or modprobe to insert it and hide processes, files, or network activity as a rootkit.

Possible investigation steps

  • Capture the full command line and resolve any referenced .ko path, then collect the module file for hashing and static analysis to determine provenance and known-malware matches.
  • Confirm whether the module is currently loaded by querying lsmod//proc/modules, then map it to its on-disk location with modinfo -n <module> (or /sys/module/<module>/sections/*) to validate it was loaded from the suspicious directory.
  • Review recent kernel and audit telemetry (dmesg, /var/log/kern.log, journalctl -k, and any audit records) around the event time for insertion messages, signature/taint indicators, and any follow-on errors suggesting tampering.
  • Identify the initiating user/session and execution chain (parent process tree, TTY/SSH source, container context), then determine whether the action aligns with legitimate admin activity or coincides with other compromise signals on the host.
  • Hunt for persistence and repeatability by checking for recurring module-load attempts and inspecting boot-time and scheduled execution paths (systemd units, init scripts, cron, rc.local) that could reload the module after reboot.

False positive analysis

  • A system administrator or automated maintenance workflow may build or test an out-of-tree kernel module and load it with insmod/modprobe from a staging directory such as /tmp, /root, or /mnt before installing it into standard module paths.
  • A legitimate bootstrapping or recovery operation may load a required driver module from nonstandard media or temporary runtime locations (e.g., /boot, /run, /var/run, or /mnt) during troubleshooting, initramfs/early-boot tasks, or mounting encrypted/storage devices.

Response and remediation

  • Isolate the affected Linux host from the network and disable external access (e.g., revoke SSH keys or block inbound SSH) to prevent additional module loads or lateral movement while preserving evidence.
  • If the suspicious module is currently loaded, record lsmod and modinfo output, then unload it where safe (modprobe -r <name>/rmmod <name>) and quarantine the corresponding .ko from the unusual path (e.g., /tmp, /dev/shm, /home, /mnt) for hashing and malware analysis.
  • Remove persistence mechanisms that would reload the module by deleting or disabling any related systemd units, init scripts, cron entries, and boot-time hooks, and validate /etc/modules-load.d/, /lib/modules/$(uname -r)/, and depmod outputs for unauthorized additions.
  • Recover the host by restoring known-good kernel/module packages and rebuilding the initramfs, then reboot and verify no unexpected modules remain in /proc/modules and no new load attempts occur from writable directories.
  • Escalate immediately to IR/forensics and consider full host rebuild if the module is unsigned/unknown, the kernel is tainted, module removal fails, or post-reboot evidence indicates stealth behavior consistent with a rootkit.
  • Harden by restricting module loading (enable Secure Boot/module signature enforcement where supported, set kernel.modules_disabled=1 after boot on fixed-function systems, and limit CAP_SYS_MODULE to trusted admins), and enforce file integrity monitoring/permissions to prevent .ko creation in world-writable locations.

References

Related rules

to-top