Detection rules › Elastic

Loadable Kernel Module Loaded via Loader

Source
github.com/elastic/protections-artifacts

This rule monitors for the loading of kernel modules via an unusual process, indicating the use of a loader. Loadable kernel modules (LKMs) are pieces of code that can be loaded into the kernel at runtime to extend its functionality. These are commonly abused by rootkits or other malicious software to hide their presence or to gain elevated privileges. These LKMs are normally loaded via a pre-installed utility such as insmod, kmod, or modprobe.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
This rule monitors for the loading of kernel modules via an unusual process, indicating the use of a loader. Loadable
kernel modules (LKMs) are pieces of code that can be loaded into the kernel at runtime to extend its functionality.
These are commonly abused by rootkits or other malicious software to hide their presence or to gain elevated privileges.
These LKMs are normally loaded via a pre-installed utility such as insmod, kmod, or modprobe.
"""
id = "ce304037-0b55-47bd-aa14-140c658ee48a"
license = "Elastic License v2"
name = "Loadable Kernel Module Loaded via Loader"
os_list = ["linux"]
reference = ["https://www.elastic.co/security-labs/continuation-on-persistence-mechanisms"]
version = "1.0.3"

query = '''
process where event.type == "start" and event.action == "load_module" and (
  process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "mksh", "busybox", "node", "deno", "nodejs", "java") or
  process.name like ("memfd:*", ".*", "python*", "perl*", "php*", "ruby*", "lua*") or
  process.executable like (
    "./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
    "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*", "/mnt/*",
    "/srv/*", "/etc/*"
  )
) and
not (
  process.executable like ("/tmp/newroot/*", "/run/systemd/mount-rootfs/sbin/*") or
  (
    process.parent.command_line == "bash /var/lib/guardicore/bin/gc-enforcement-wrapper start-agent" and
    process.command_line == "bash /var/lib/guardicore/bin/gc-enforcement-wrapper start-agent" and
    process.working_directory == "/var/lib/guardicore"
  )
)
'''

min_endpoint_version = "9.1.4"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"



[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1014"
name = "Rootkit"
reference = "https://attack.mitre.org/techniques/T1014/"


[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "9.1.4"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "load_module" and (
  process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "mksh", "busybox", "node", "deno", "nodejs", "java") or
  process.name like ("memfd:*", ".*", "python*", "perl*", "php*", "ruby*", "lua*") or
  process.executable like (
    "./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
    "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*", "/mnt/*",
    "/srv/*", "/etc/*"
  )
) and
not (
  process.executable like ("/tmp/newroot/*", "/run/systemd/mount-rootfs/sbin/*") or
  (
    process.parent.command_line == "bash /var/lib/guardicore/bin/gc-enforcement-wrapper start-agent" and
    process.command_line == "bash /var/lib/guardicore/bin/gc-enforcement-wrapper start-agent" and
    process.working_directory == "/var/lib/guardicore"
  )
)

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • load_module
field:"EventType" kind:eq value:"load_module"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /etc/*
  • /home/*/*
  • /lost+found/*
  • /mnt/*
  • /proc/*
  • /root/*
  • /run/*
  • /srv/*
  • /sys/*
  • /tmp/*
  • /var/mail/*
  • /var/run/*
  • /var/tmp/*
  • /var/www/*
field:"Image" kind:wildcard
process.namein
  • bash
  • busybox
  • csh
  • dash
  • deno
  • fish
  • java
  • ksh
  • mksh
  • node
  • nodejs
  • sh
  • tcsh
  • zsh
field:"process_name" kind:in
process.namewildcard
  • .*
  • lua*
  • memfd:*
  • perl*
  • php*
  • python*
  • ruby*
field:"process_name" kind:wildcard