Detect Rootkit in IBM QRadar
Adversaries may use rootkits to hide the presence of programs, files, network connections, services, drivers, and other system components. Rootkits intercept and modify operating system API calls to conceal malware activity and can reside at user-space, kernel-space, or firmware levels. Real-world deployments include Drovorub (GRU-attributed Linux kernel rootkit using LKMs), Skidmap (cryptocurrency miner with kernel-mode hooking), TeamTNT's Diamorphine (open-source LKM), Ebury (SSH userland rootkit), Rocke (ld.so.preload hijacking), Umbreon (libc hooking), and Windows-based rootkits from Carberp and Stuxnet. Linux kernel rootkits typically leverage loadable kernel modules (LKMs) or shared library preloading via /etc/ld.so.preload. Windows kernel rootkits abuse driver loading mechanisms. Detection is most effective at installation and loading time — once active, rootkits actively conceal themselves from OS-level enumeration.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Technique
- T1014 Rootkit
- Canonical reference
- https://attack.mitre.org/techniques/T1014/
QRadar Detection Query
SELECT
DATEFORMAT(starttime, 'yyyy-MM-dd HH:mm:ss') AS event_time,
sourceip,
username,
LOGSOURCETYPENAME(devicetype) AS log_source_type,
QIDNAME(qid) AS event_name,
CATEGORYNAME(category) AS event_category,
"ServiceName",
"ServiceType",
"ImagePath",
"ImageLoaded",
"syscall",
"name" AS audit_file_path,
"nametype",
"comm" AS parent_process_name,
"auid",
CASE
WHEN eventid = 7045
AND (LOWER("ServiceType") LIKE '%kernel%'
OR "ServiceType" = '1'
OR "ServiceType" = '0x1')
AND (
"ImagePath" ILIKE '%\temp\%'
OR "ImagePath" ILIKE '%\appdata\%'
OR "ImagePath" ILIKE '%\downloads\%'
OR "ImagePath" ILIKE '%\programdata\%'
OR "ImagePath" ILIKE '%\users\public\%'
)
THEN 'WindowsKernelDriverInstall'
WHEN QIDNAME(qid) ILIKE '%Driver Loaded%'
AND NOT (
"ImageLoaded" ILIKE 'C:\Windows\System32\%'
OR "ImageLoaded" ILIKE 'C:\Windows\SysWOW64\%'
OR "ImageLoaded" ILIKE 'C:\Windows\WinSxS\%'
OR "ImageLoaded" ILIKE 'C:\Program Files\%'
OR "ImageLoaded" ILIKE 'C:\Program Files (x86)\%'
OR "ImageLoaded" ILIKE 'C:\Windows\servicing\%'
)
THEN 'SuspiciousDriverLoad'
WHEN "type" = 'SYSCALL'
AND "syscall" IN ('init_module', 'finit_module')
AND NOT (
"comm" ILIKE 'apt%' OR "comm" ILIKE 'dpkg%'
OR "comm" = 'rpm' OR "comm" = 'yum' OR "comm" = 'dnf'
OR "comm" = 'kmod' OR "comm" = 'dracut'
OR "comm" = 'systemd' OR "comm" = 'pacman'
OR "comm" = 'zypper' OR "comm" = 'snap'
)
THEN 'LinuxKernelModuleLoad'
WHEN "type" = 'SYSCALL' AND "syscall" = 'delete_module'
THEN 'LinuxKernelModuleUnload'
WHEN "type" = 'PATH'
AND "name" = '/etc/ld.so.preload'
AND "nametype" IN ('CREATE', 'NORMAL')
THEN 'LdPreloadModification'
ELSE 'Unknown'
END AS detection_type
FROM events
WHERE
LAST 24 HOURS
AND (
/* Signal 1: Windows kernel driver service install from suspicious path (System Event 7045) */
(
eventid = 7045
AND (
LOWER("ServiceType") LIKE '%kernel%'
OR "ServiceType" = '1'
OR "ServiceType" = '0x1'
)
AND (
"ImagePath" ILIKE '%\temp\%'
OR "ImagePath" ILIKE '%\appdata\%'
OR "ImagePath" ILIKE '%\downloads\%'
OR "ImagePath" ILIKE '%\programdata\%'
OR "ImagePath" ILIKE '%\users\public\%'
)
)
OR
/* Signal 2: Driver (.sys) loaded from non-standard path (Sysmon EventCode 6 via QRadar DSM) */
(
QIDNAME(qid) ILIKE '%Driver Loaded%'
AND NOT (
"ImageLoaded" ILIKE 'C:\Windows\System32\%'
OR "ImageLoaded" ILIKE 'C:\Windows\SysWOW64\%'
OR "ImageLoaded" ILIKE 'C:\Windows\WinSxS\%'
OR "ImageLoaded" ILIKE 'C:\Program Files\%'
OR "ImageLoaded" ILIKE 'C:\Program Files (x86)\%'
OR "ImageLoaded" ILIKE 'C:\Windows\servicing\%'
)
)
OR
/* Signal 3: Linux auditd kernel module load syscalls outside package manager */
(
"type" = 'SYSCALL'
AND "syscall" IN ('init_module', 'finit_module', 'delete_module')
AND NOT (
"comm" ILIKE 'apt%' OR "comm" ILIKE 'dpkg%'
OR "comm" = 'rpm' OR "comm" = 'yum' OR "comm" = 'dnf'
OR "comm" = 'kmod' OR "comm" = 'dracut'
OR "comm" = 'systemd' OR "comm" = 'pacman'
OR "comm" = 'zypper' OR "comm" = 'snap'
)
)
OR
/* Signal 4: auditd PATH write to /etc/ld.so.preload (userland rootkit hook point) */
(
"type" = 'PATH'
AND "name" = '/etc/ld.so.preload'
AND "nametype" IN ('CREATE', 'NORMAL')
)
)
ORDER BY starttime DESC IBM QRadar AQL query detecting four T1014 Rootkit signals: kernel driver service installation from suspicious paths via Windows System Event 7045, non-standard driver loads mapped from Sysmon EventCode 6 via QRadar DSM QIDNAME lookup, Linux auditd SYSCALL records for init_module/finit_module/delete_module outside recognized package manager comm names, and auditd PATH records showing creation or write to /etc/ld.so.preload.
Data Sources
Required Tables
False Positives & Tuning
- Software installers that unpack .sys driver files to %TEMP% before registering via sc.exe — Event 7045 fires while the ImagePath still points to the temp staging location before the MSI/NSIS installer relocates it
- Security operations tooling such as volatility, rekall, or commercial forensic suites running modprobe or insmod during live memory acquisition or malware triage on production Linux systems, where comm does not match any package manager
- QRadar's own custom property extraction may fail to parse ServiceType or ImagePath fields from non-English Windows locale deployments, causing false positives when the CASE expression falls through to an incorrect detection_type due to null field values
Other platforms for T1014
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1 Linux: Load a Benign Kernel Module from Non-Standard Path
Expected signal: auditd SYSCALL record with syscall=init_module, exe=/sbin/insmod, auid=<current_user>. DeviceProcessEvents (MDE for Linux): FileName=insmod, ProcessCommandLine containing '/tmp/testmodule/test_rootkit_sim.ko', InitiatingProcessFileName=bash/sh. dmesg shows 'argus_test: rootkit simulation module loaded'. lsmod shows 'test_rootkit_sim' in module list.
- Test 2 Linux: Userland Rootkit Hook via ld.so.preload Injection
Expected signal: auditd PATH record: type=PATH name=/etc/ld.so.preload nametype=NORMAL with associated SYSCALL record showing write/openat syscall, exe=/usr/bin/tee. DeviceFileEvents (MDE for Linux): FolderPath=/etc, FileName=ld.so.preload, ActionType=FileModified or FileCreated. File integrity monitoring (if deployed) triggers on /etc/ld.so.preload change.
- Test 3 Windows: Install a Kernel Driver Service from Suspicious Path
Expected signal: Security Event ID 4697 in Security Log: ServiceName=ArgusTestRootkit, ServiceFileName=C:\Users\Public\argus_test_driver.sys, ServiceType=0x00000001 (Kernel Driver), AccountName=<current_admin_user>. Sysmon Event ID 6 (Driver Loaded): ImageLoaded=C:\Users\Public\argus_test_driver.sys, Signed=true (null.sys is signed). System Event Log 7045: same service details. The file is legitimately signed but the path is suspicious.
- Test 4 Linux: Enumerate Running Processes to Detect Rootkit-Induced Discrepancies
Expected signal: On a clean system: proc_pids.txt and ps_pids.txt should differ only by kernel threads and very short-lived processes, and the final comm output should be empty or show only expected kernel thread PIDs. Module comparison should show no discrepancies on a clean system. During active rootkit incident: hidden PIDs and module names would appear in the discrepancy output. This test generates no detection alerts on a clean system — it is a verification tool for the investigation phase.
References (9)
- https://attack.mitre.org/techniques/T1014/
- https://media.defense.gov/2020/Aug/13/2002476465/-1/-1/0/CSA_DROVORUB_RUSSIAN_GRU_MALWARE_AUG_2020.PDF
- https://www.anomali.com/blog/rocke-evolves-its-arsenal-with-a-new-malware-family-written-in-golang
- https://www.welivesecurity.com/2017/10/30/windigo-ebury-update-2/
- https://blog.trendmicro.com/trendlabs-security-intelligence/umbreon-linux-rootkit-hits-x86-arm-systems/
- https://www.crowdstrike.com/blog/http-iframe-injecting-linux-rootkit/
- https://github.com/m0nad/Diamorphine
- https://github.com/marin-m/vmlinux-to-elf
- https://volatility3.readthedocs.io/en/latest/
Response Playbook
Triage
- Identify the specific detection signal that fired: KernelDriverInstall, SuspiciousDriverLoad, LinuxKernelModuleLoad, or LdPreloadModification — each has a different initial triage path and urgency level
- For Windows driver events (7045/4697 or Sysmon EventCode 6): check the driver binary path, file hash, and digital signature. Run: Get-AuthenticodeSignature '<driver_path>' — an unsigned driver from a temp directory is high-confidence malicious
- For Linux kernel module loads: examine the .ko file using modinfo <module_path> to check author, description, and license fields. Legitimate modules show expected kernel version and module author. Run lsmod and compare to /proc/modules — discrepancies indicate active rootkit concealment
- For /etc/ld.so.preload modification: immediately cat /etc/ld.so.preload to identify the injected library path. Verify the library exists, then run nm -D <library_path> to identify which libc functions it hooks (read, getdents, write, connect are common rootkit targets)
- Check for process visibility discrepancies: compare 'ps aux' output against /proc entries using: ls /proc | grep -E '^[0-9]+$' | while read pid; do [ ! -d /proc/$pid/exe ] 2>/dev/null && echo "Hidden: $pid"; done — hidden PIDs indicate an active rootkit
- Review the initiating process and user context: was the module load/driver install initiated by a privileged user, a compromised service account, or an unexpected binary such as a web server or database process?
- Check dmesg output and /var/log/kern.log for kernel module load events and any ERROR or WARNING messages from the loaded module that may indicate rootkit activity or kernel tainting
Containment
- If active Linux kernel rootkit confirmed: do NOT attempt to clean the live system — the rootkit may have hooked syscalls making all output unreliable. Isolate the host from the network immediately using firewall rules or hypervisor-level network disconnection
- For Windows kernel rootkit confirmed: isolate the endpoint using EDR network isolation. Boot from external media (WinPE or forensic live USB) to examine the filesystem and driver store without loading potentially compromised kernel components
- If /etc/ld.so.preload is compromised: the rootkit library is injected into every new process. Do not spawn additional shells or processes on the compromised host until the preload is removed from a trusted context (single-user mode or external boot)
- Identify and block the C2 infrastructure: extract network IOCs from the rootkit binary if accessible from a clean context and block at perimeter. Drovorub and Skidmap used specific ports and protocols documented in their threat intelligence reports
- Preserve volatile memory before any remediation: if forensic capability exists, take a memory dump (LiME for Linux, DumpIt for Windows) from a trusted kernel or external tool — this is the most reliable artifact for rootkit analysis
- Revoke credentials used on the compromised host: all credentials (SSH keys, service account passwords, API keys, certificates) that were accessible on the system should be treated as compromised and rotated immediately
Evidence Collection
- Memory dump: For Linux use LiME (Linux Memory Extractor) — insmod lime-$(uname -r).ko 'path=/mnt/external/memory.lime format=lime' — this captures a full memory image from a known-clean module before the rootkit can intercept
- Kernel module artifacts: copy all .ko files from /lib/modules/$(uname -r)/ to external storage; hash each file and compare against known-good package checksums using rpm -V kernel or dpkg --verify linux-image-$(uname -r)
- File system artifacts: run an offline scan using a live boot to enumerate all files without the rootkit's getdents hook — compare against the live system's 'ls' output to identify hidden files
- Windows driver store: collect C:\Windows\System32\drivers\*.sys hashes; query the service registry at HKLM\SYSTEM\CurrentControlSet\Services for entries with ServiceType=1 (kernel driver) where ImagePath points outside the driver store
- Network artifacts: capture pcap from a network tap or external sensor (not the compromised host's tcpdump, which may be hooked) to identify C2 communication patterns — Drovorub used port 443 with custom TLS fingerprints
- Audit log review: Linux — /var/log/auth.log, /var/log/kern.log, journalctl -k for kernel messages, ausearch -k rootkit for auditd events; Windows — System Event Log for Event ID 7045, Security Log for 4697
- Rootkit-specific IOC comparison: hash the suspicious module/driver and compare against known rootkit signatures from VirusTotal, YARA rules for Diamorphine, Drovorub, Skidmap, Ebury, and vendor threat intelligence reports
- Timeline reconstruction: use filesystem timestamps (mtime, atime, ctime) on the .ko or .sys file — discrepancies between install time in logs and filesystem timestamps may indicate timestamp manipulation by the attacker
Escalation Criteria
- !Any confirmed kernel-mode rootkit — escalate immediately to incident response; kernel rootkits can intercept and manipulate all OS-level security telemetry, making the entire system untrusted
- !Evidence of syscall hooking or process hiding (discrepancy between /proc entries and ps output, or between netstat and /proc/net/ entries) — this indicates the rootkit is actively concealing attacker presence
- !Rootkit found on a domain controller, authentication server, PKI system, or privileged access workstation — blast radius includes credential theft at scale
- !/etc/ld.so.preload found containing an unknown library — all processes spawned on this host since the modification may have executed attacker-controlled code
- !Rootkit binary or driver matches a known threat actor tool (Drovorub = APT28/GRU, Skidmap = cryptomining campaigns, Diamorphine = TeamTNT) — threat intelligence escalation required
- !Evidence of lateral movement from the rootkit-infected host to other systems — SSH private keys, Kerberos tickets, or credential material may have been stolen via the hooked authentication functions
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Linux /proc/modules and lsmod output: compare against known-good module list; rootkits may hide themselves from both but leave traces in /sys/module/ - >
Linux /etc/ld.so.preload: if present and non-empty, contains the path to injected shared libraries — should normally be empty on production systems - >
Linux /sys/module/<module_name>/: even when lsmod is hooked, kernel sysfs entries for loaded modules may persist — enumerate with ls /sys/module/ from a trusted context - >
Linux dmesg / /var/log/kern.log: kernel module load events appear as 'module: <name>' entries; rootkits that taint the kernel generate 'kernel tainted' messages - >
Windows Registry HKLM\SYSTEM\CurrentControlSet\Services: kernel drivers (ServiceType=0x1) registered here; compare against known-good service baseline - >
Windows C:\Windows\System32\drivers\: unexpected .sys files not present in a clean baseline or not signed by a trusted CA indicate kernel rootkit presence - >
Windows Prefetch C:\Windows\Prefetch\: execution traces for tools used to install the rootkit (sc.exe, bcdedit.exe, devmgmt.exe) may persist even if logs are cleared - >
Memory artifacts: kernel rootkits are visible in memory dumps via Volatility plugins (linux_check_syscall, linux_check_idt for Linux; ssdt, callbacks for Windows) which compare in-memory kernel structures against expected values
Tuning Guidance
Rootkit detection has an inherent signal quality challenge: once active, rootkits modify the OS telemetry that detection queries rely on, making the installation phase the highest-confidence detection window. Focus tuning efforts on the pre-execution and loading phase. For Windows kernel driver detections (4697/Sysmon EventCode 6), build a vetted allowlist of known driver binary paths for each device class in your environment — security software, VPN clients, and hardware vendors often have consistent driver paths. Never allowlist by service name alone since rootkits commonly masquerade as legitimate service names. For Linux kernel module detections, establish a baseline of expected modules per server role using lsmod output from known-clean systems — database servers should not load WiFi drivers, web servers should not load bluetooth modules. The most reliable Linux auditd rule set for this technique requires these rules in /etc/audit/rules.d/rootkit.rules: '-a always,exit -F arch=b64 -S init_module -S finit_module -S delete_module -k rootkit' and '-w /etc/ld.so.preload -p wa -k rootkit'. Without these auditd rules, the linux_auditd SPL query produces no output. For environments with heavy legitimate kernel module activity (HPC, specialized hardware), add a whitelist of expected module names to filter from the LinuxKernelModuleLoad signal. Consider deploying file integrity monitoring (FIM) on /etc/ld.so.preload, /etc/ld.so.conf.d/, and /lib/modules/ as a complementary control. The SuspiciousDriverLoad KQL signal can be noisy during software deployments — consider time-bounding alerts to exclude known maintenance windows.
Hunting Queries
Hunt for rare unsigned kernel drivers loaded from non-standard paths across the fleet over the past 7 days. Rootkit drivers tend to appear on very few systems (low prevalence) unlike legitimate vendor drivers which load consistently across many managed endpoints. Low count combined with non-standard path is a high-signal indicator.
// Hunt for unsigned kernel drivers loaded in the past 7 days across the fleet
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where FileName endswith ".sys"
| where not(FolderPath has_any (
@"C:\\Windows\\System32\\",
@"C:\\Windows\\SysWOW64\\",
@"C:\\Windows\\WinSxS\\",
@"C:\\Program Files\\",
@"C:\\Program Files (x86)\\"
))
| summarize Count = count(), Devices = dcount(DeviceName), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), DeviceList = make_set(DeviceName, 10) by FileName, FolderPath, SHA1
| where Count < 5 // Rare drivers are more suspicious than prevalent ones
| sort by Count asc sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=6
NOT (ImageLoaded="C:\\Windows\\System32\\*" OR ImageLoaded="C:\\Windows\\SysWOW64\\*" OR ImageLoaded="C:\\Windows\\WinSxS\\*" OR ImageLoaded="C:\\Program Files\\*")
earliest=-7d
| stats count as Count, dc(host) as Devices, values(Signed) as Signed, earliest(_time) as FirstSeen, latest(_time) as LastSeen by ImageLoaded, Hashes
| where Count < 5
| sort + Count Hunt for systems with unusually high frequency of kernel module operations or module loads from many different parent processes. Rootkit deployment often involves multiple load/unload cycles during testing or redeployment. High module operation counts or diverse parent processes on a single host are behavioral anomalies worth investigating.
// Hunt for Linux systems where insmod/modprobe has been called by non-root or unexpected parents
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("insmod", "modprobe", "rmmod")
| summarize Count = count(), UniqueParents = dcount(InitiatingProcessFileName), ParentList = make_set(InitiatingProcessFileName, 10), ModuleList = make_set(ProcessCommandLine, 20) by DeviceName, AccountName
| where UniqueParents > 3 or Count > 10
| sort by Count desc sourcetype="linux_auditd" type=SYSCALL (syscall="init_module" OR syscall="finit_module" OR syscall="delete_module") earliest=-7d
| stats count as Count, dc(ppid) as UniquePPIDs, values(exe) as Executables, values(comm) as Commands by host, auid
| where Count > 5 OR UniquePPIDs > 3
| sort - Count Hunt for any writes to /etc/ld.so.preload over the past 30 days. This file is rarely modified on production Linux systems — any write event warrants immediate investigation. Used by Rocke to hijack libc calls and hide cryptomining activity, and by Umbreon to intercept authentication and system calls. Even a single event here is significant.
// Hunt for any process that wrote to /etc/ld.so.preload — should be near-zero in production
DeviceFileEvents
| where Timestamp > ago(30d)
| where FolderPath =~ "/etc" and FileName =~ "ld.so.preload"
| project Timestamp, DeviceName, AccountName, ActionType, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName
| sort by Timestamp desc sourcetype="linux_auditd" type=PATH name="/etc/ld.so.preload" earliest=-30d
| join type=left auid [search sourcetype="linux_auditd" type=SYSCALL earliest=-30d | rename auid as auid, exe as exe | table auid, exe, comm, ppid]
| table _time, host, auid, exe, comm, ppid, nametype, name
| sort - _time Atomic Red Team Tests
Simulates LKM rootkit installation by loading a simple kernel module from /tmp rather than the standard module directory. Uses the 'hello' example module (compiled from kernel headers) or the 'dummy' network driver that ships with many Linux distributions. This generates auditd init_module syscall events and Sysmon-for-Linux process events without deploying actual malicious functionality. Requires root privileges and kernel headers.
Command
# Step 1: Create a minimal benign kernel module
mkdir -p /tmp/testmodule
cat > /tmp/testmodule/test_rootkit_sim.c << 'EOF'
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int __init test_init(void) { printk(KERN_INFO "argus_test: rootkit simulation module loaded\n"); return 0; }
static void __exit test_exit(void) { printk(KERN_INFO "argus_test: rootkit simulation module unloaded\n"); }
module_init(test_init);
module_exit(test_exit);
EOF
# Step 2: Build module (requires kernel headers: apt install linux-headers-$(uname -r))
echo -e 'obj-m += test_rootkit_sim.o\nall:\n\tmake -C /lib/modules/$(uname -r)/build M=$(PWD) modules\nclean:\n\tmake -C /lib/modules/$(uname -r)/build M=$(PWD) clean' > /tmp/testmodule/Makefile
make -C /tmp/testmodule
# Step 3: Load from non-standard path (key detection trigger)
sudo insmod /tmp/testmodule/test_rootkit_sim.ko Cleanup
sudo rmmod test_rootkit_sim 2>/dev/null; rm -rf /tmp/testmodule Expected Telemetry
auditd SYSCALL record with syscall=init_module, exe=/sbin/insmod, auid=<current_user>. DeviceProcessEvents (MDE for Linux): FileName=insmod, ProcessCommandLine containing '/tmp/testmodule/test_rootkit_sim.ko', InitiatingProcessFileName=bash/sh. dmesg shows 'argus_test: rootkit simulation module loaded'. lsmod shows 'test_rootkit_sim' in module list.
Expected Detection
SPL: auditd SYSCALL record matches syscall=init_module trigger. KQL: LinuxKernelModuleLoad fires on insmod with ProcessCommandLine containing '/tmp/'. from_pkg_manager=0 because parent is bash. Alert: DetectionType=LinuxKernelModuleLoad.
Simulates the Rocke and Umbreon userland rootkit technique by writing a shared library path to /etc/ld.so.preload. Uses a benign test library that only logs a message to demonstrate the hook mechanism. Once set, every newly spawned process will load the injected library before any other — this is how Rocke hid cryptominers and Umbreon intercepted authentication. Requires root privileges.
Command
# Step 1: Create a benign preload library
cat > /tmp/argus_preload_test.c << 'EOF'
#include <stdio.h>
__attribute__((constructor)) void init(void) {
fprintf(stderr, "[argus-test] ld.so.preload hook active\n");
}
EOF
gcc -shared -fPIC -o /tmp/argus_preload_test.so /tmp/argus_preload_test.c
# Step 2: Write to /etc/ld.so.preload (key detection trigger — auditd watches this file)
echo '/tmp/argus_preload_test.so' | sudo tee /etc/ld.so.preload
# Step 3: Verify hook is active (every new process loads the library)
whoami Cleanup
sudo rm -f /etc/ld.so.preload; rm -f /tmp/argus_preload_test.so /tmp/argus_preload_test.c Expected Telemetry
auditd PATH record: type=PATH name=/etc/ld.so.preload nametype=NORMAL with associated SYSCALL record showing write/openat syscall, exe=/usr/bin/tee. DeviceFileEvents (MDE for Linux): FolderPath=/etc, FileName=ld.so.preload, ActionType=FileModified or FileCreated. File integrity monitoring (if deployed) triggers on /etc/ld.so.preload change.
Expected Detection
SPL: auditd PATH record matches name=/etc/ld.so.preload with nametype=CREATE or NORMAL. KQL: LdPreloadModification fires with ActionType=FileModified/FileCreated. Hunting query returns this event in 30-day lookback. Alert: DetectionType=LdPreloadModification, severity=critical.
Simulates Windows kernel rootkit installation by registering a kernel driver service with its binary path pointing to a user-writable directory (AppData\Local\Temp). Uses a legitimate, benign .sys file (null.sys — the Windows null device driver) copied to a suspicious location. This triggers Security Event ID 4697 and Sysmon EventCode 6 without loading actual malicious code. Requires administrator privileges.
Command
# Copy a legitimate benign .sys to a suspicious path
copy C:\Windows\System32\drivers\null.sys C:\Users\Public\argus_test_driver.sys
# Register as kernel driver service (ServiceType=1 = kernel driver)
sc create ArgusTestRootkit type= kernel binPath= "C:\Users\Public\argus_test_driver.sys" DisplayName= "Argus Rootkit Simulation Test"
# Start the service to trigger driver load event (optional — registration alone triggers 4697)
sc start ArgusTestRootkit Cleanup
sc stop ArgusTestRootkit; sc delete ArgusTestRootkit; del C:\Users\Public\argus_test_driver.sys Expected Telemetry
Security Event ID 4697 in Security Log: ServiceName=ArgusTestRootkit, ServiceFileName=C:\Users\Public\argus_test_driver.sys, ServiceType=0x00000001 (Kernel Driver), AccountName=<current_admin_user>. Sysmon Event ID 6 (Driver Loaded): ImageLoaded=C:\Users\Public\argus_test_driver.sys, Signed=true (null.sys is signed). System Event Log 7045: same service details. The file is legitimately signed but the path is suspicious.
Expected Detection
KQL: KernelDriverInstall fires on Event ID 4697 with ServiceType=0x00000001 and ServiceFileName containing C:\Users\Public\. SPL: WinEventLog:System EventCode=7045 matches ServiceType=Kernel Driver. Alert: DetectionType=KernelDriverInstall, is_suspicious_path=1.
Simulates the forensic technique used to detect active process-hiding rootkits. Compares PIDs visible in /proc against those returned by the ps command. On a clean system these should match exactly. When a kernel rootkit (Diamorphine, Drovorub) is active, getdents-hooked ps will miss PIDs that are still visible in /proc. This atomic test establishes a clean baseline and demonstrates the detection methodology used during incident response.
Command
# Method 1: Compare /proc PID list against ps output
echo '=== PIDs in /proc (direct kernel view) ==='
ls /proc | grep -E '^[0-9]+$' | sort -n > /tmp/proc_pids.txt
cat /tmp/proc_pids.txt | wc -l
echo '=== PIDs from ps (potentially hooked) ==='
ps -eo pid --no-headers | sort -n > /tmp/ps_pids.txt
cat /tmp/ps_pids.txt | wc -l
echo '=== PIDs in /proc but NOT in ps output (potential hidden processes) ==='
comm -23 /tmp/proc_pids.txt /tmp/ps_pids.txt
# Method 2: Check for kernel module hiding (compare /proc/modules vs lsmod)
echo '=== Modules in /proc/modules ==='
cat /proc/modules | awk '{print $1}' | sort > /tmp/proc_modules.txt
echo '=== Modules from lsmod ==='
lsmod | awk 'NR>1 {print $1}' | sort > /tmp/lsmod_modules.txt
echo '=== Modules in /proc/modules but NOT in lsmod (potential hidden modules) ==='
comm -23 /tmp/proc_modules.txt /tmp/lsmod_modules.txt Cleanup
rm -f /tmp/proc_pids.txt /tmp/ps_pids.txt /tmp/proc_modules.txt /tmp/lsmod_modules.txt Expected Telemetry
On a clean system: proc_pids.txt and ps_pids.txt should differ only by kernel threads and very short-lived processes, and the final comm output should be empty or show only expected kernel thread PIDs. Module comparison should show no discrepancies on a clean system. During active rootkit incident: hidden PIDs and module names would appear in the discrepancy output. This test generates no detection alerts on a clean system — it is a verification tool for the investigation phase.
Expected Detection
No alert fires on a clean system — this is an IR verification technique. If running during an active incident with a rootkit present, the discrepancy output identifies hidden processes/modules. Analyst action: if comm -23 output shows non-kernel PIDs (above 1000) or module names that cannot be explained, escalate immediately as active rootkit concealment is occurring.