In the relentless cat-and-mouse game of cybersecurity, detecting initial compromise is only half the battle. True victory lies in understanding and thwarting an adversary’s attempts at persistence – their means of maintaining access to a compromised system over time. While most defenders are adept at spotting standard persistence mechanisms like Windows Run keys or Linux cron jobs, sophisticated attackers increasingly leverage more subtle, less-obvious techniques to embed themselves deep within a system.
This post dives into the shadows, exploring advanced persistence methods on both Windows and Linux that often fly under the radar of conventional security tools and audits. By understanding how these techniques work and what indicators to look for, you can significantly bolster your organization’s detection and response capabilities.
Windows: WMI Event Subscriptions and MOF Files
Windows Management Instrumentation (WMI) is a powerful framework for managing Windows systems, but its flexibility also makes it a prime target for adversaries seeking covert persistence. WMI event subscriptions allow an attacker to register code to be executed whenever a specific system event occurs, such as a process starting, a user logging in, or even a log file being written to. These subscriptions are defined using MOF (Managed Object Format) files or directly via WMI commands.
An attacker can create an __EventFilter to define the triggering event, an __EventConsumer (e.g., CommandLineEventConsumer) to specify the action to take, and an __FilterToConsumerBinding to link them. This can execute arbitrary commands or scripts with high privileges. These subscriptions persist across reboots and are often invisible to standard file system scans.
Detection Strategy:
- Inspect WMI event consumers, filters, and bindings using `wmic` or PowerShell’s `Get-WmiObject`:
- `wmic /namespace:\rootsubscription PATH __EventConsumer GET /ALL`
- `wmic /namespace:\rootsubscription PATH CommandLineEventConsumer GET /ALL` (look for suspicious executables or scripts)
- `wmic /namespace:\rootsubscription PATH __EventFilter GET /ALL`
- `wmic /namespace:\rootsubscription PATH __FilterToConsumerBinding GET /ALL`
- Look for suspicious MOF files, especially in directories like `C:WindowsSystem32wbemAutoRecover` or any non-standard location.
- Sysmon event IDs 19, 20, and 21 specifically log WMI activity and can be invaluable for detecting creation or modification of these components. Monitor these logs for unusual WMI consumers or filters.
- Tools like Sysinternals Autoruns have a WMI tab that can help enumerate these.
Beyond Standard Scheduled Tasks: Triggers and Actions
While `schtasks /create` is a well-known command, the Windows Task Scheduler offers far more sophisticated persistence opportunities than simple time-based execution. Modern scheduled tasks support a rich array of triggers and actions that can be used to execute malicious code under very specific, and often less noticeable, conditions.
Attackers can configure tasks to trigger on events like system startup, user logon (even for specific users or groups), idle time, the creation of a specific log entry, or even the availability of a network connection. Actions can involve launching complex PowerShell scripts, encoded commands, or custom executables, often running with SYSTEM privileges. These tasks can be configured to be hidden, or named to blend in with legitimate system tasks.
Detection Strategy:
- Query all scheduled tasks with verbose output: `schtasks /query /v /fo list`. Scrutinize the ‘Triggers’ and ‘Actions’ sections for any unusual configurations.
- Use PowerShell to inspect tasks programmatically: `Get-ScheduledTask | Where-Object {$_.Actions.Execute -like “*powershell.exe*” -or $_.Actions.Execute -like “*cmd.exe*”}`. Look for suspicious script content, especially encoded commands.
- Examine the XML definitions of suspicious tasks: `Get-ScheduledTask -TaskName “SuspiciousTaskName” | Export-ScheduledTask -Path task.xml`. These XML files are also stored in `C:WindowsSystem32Tasks`.
- Monitor Security Event Log IDs 4698 (A scheduled task was created), 4699 (A scheduled task was deleted), 4700 (A scheduled task was updated), and 4701 (A scheduled task was enabled/disabled).
- Sysmon event ID 1 for process creation should be configured to flag suspicious processes launched by `taskhostw.exe` or `schtasks.exe`.
COM Hijacking and DLL Search Order Vulnerabilities
Component Object Model (COM) hijacking and DLL search order vulnerabilities represent powerful, stealthy Windows persistence methods that leverage how the operating system loads executable code.
COM Hijacking: This technique involves modifying the Windows Registry to redirect a legitimate COM object to load a malicious DLL instead of its intended, benign counterpart. When a trusted application attempts to load the COM object, the attacker’s DLL is executed. Common targets include `HKCUSoftwareClassesCLSID` or `HKLMSoftwareClassesCLSID` entries, allowing for user-specific or system-wide redirection. By overwriting the `InprocServer32` key for a CLSID, an attacker can specify their own DLL.
DLL Search Order Hijacking: Windows applications load dynamic-link libraries (DLLs) from specific locations in a predefined order. If an attacker places a malicious DLL with the same name as a legitimate, but non-existent or later-searched, DLL in an earlier-searched directory (e.g., the application’s directory), their malicious DLL will be loaded instead. This is particularly effective against applications that are frequently executed and may try to load common system DLLs (like `version.dll`, `dbghelp.dll`) that aren’t present in their own directory.
Detection Strategy:
- COM Hijacking:
- Monitor Registry changes (via Sysmon Event ID 12/13/14 or EDR) in `HKCUSoftwareClassesCLSID` and `HKLMSoftwareClassesCLSID` where the `InprocServer32` key points to an unusual path or a non-existent file.
- Use tools like Sysinternals ProcMon to trace DLL loading when applications start, looking for redirections.
- Audit the integrity of COM objects with tools that scan for unexpected DLL paths.
- DLL Search Order Hijacking:
- Periodically scan common application directories (e.g., those containing frequently used `.exe` files) for suspicious DLLs matching names of common system libraries.
- Use ProcMon to observe DLL load attempts and successful loads from unexpected paths during application startup.
- Leverage EDR solutions that monitor DLL loads and flag those originating from unusual directories, or those signed by an unexpected entity.
- File Integrity Monitoring (FIM) for critical application directories can help detect unexpected DLLs.
Linux: LD_PRELOAD and Shared Library Injection
On Linux systems, `LD_PRELOAD` is an environment variable that provides a potent mechanism for shared library injection, allowing attackers to hijack existing processes. When set, `LD_PRELOAD` instructs the dynamic linker to load specified shared libraries *before* any other libraries linked to a program. This means functions within the preloaded library can override functions with the same name in other libraries, effectively allowing an attacker to hook system calls, manipulate program behavior, or execute arbitrary code.
An attacker can gain persistence by setting `LD_PRELOAD` globally (e.g., in `/etc/ld.so.preload`, which is read by all programs that use the dynamic linker, or `/etc/environment`) or on a per-user basis (e.g., in `~/.bashrc`, `~/.profile`). The malicious shared library can then intercept critical functions, capture credentials, or establish covert communication channels.
Detection Strategy:
- Crucial first check: Inspect the `/etc/ld.so.preload` file. Any entry here should be highly scrutinized. It should typically be empty or contain entries from legitimate security products.
- Examine user-specific configuration files (`~/.bashrc`, `~/.profile`, `~/.pam_environment`, `~/.ssh/environment`) for `LD_PRELOAD` being set.
- Check `/etc/environment` and other system-wide environment configuration files for suspicious `LD_PRELOAD` declarations.
- Use `lsof -p ` to list loaded shared objects for critical processes. Look for unfamiliar or suspicious `.so` files.
- Integrity monitoring (FIM) of `/etc/ld.so.preload` and core shared library directories (e.g., `/lib`, `/usr/lib`) is essential.
- Tools like `auditd` can be configured to monitor access to `/etc/ld.so.preload`.
Systemd Path/Timer Units for Covert Execution
Systemd, the ubiquitous init system on modern Linux distributions, offers more than just traditional service units. Its `path` and `timer` units provide flexible, event-driven execution capabilities that can be abused for stealthy persistence, often blending in with legitimate system configurations.
- Path Units: A `path` unit monitors a specified file or directory path. When a change (creation, modification, deletion) occurs, it triggers an associated `service` unit. This allows an attacker to execute code whenever a specific file is interacted with, perhaps a log file, a user’s configuration file, or a temporary directory.
- Timer Units: Similar to cron jobs but more powerful, `timer` units trigger associated `service` units at specified times or intervals. They can be configured to run at irregular, obscure intervals (`OnCalendar=`), after boot (`OnBootSec=`), or relative to other events, making them harder to detect by simply looking for daily or hourly cron jobs.
Detection Strategy:
- List all active path and timer units:
- `systemctl list-units –type=path`
- `systemctl list-units –type=timer`
- Examine the unit files themselves. These are typically located in `/etc/systemd/system/`, `/usr/lib/systemd/system/`, and their respective symlinks. Look for unusual `ExecStart` commands within service units, or suspicious `PathExists=`, `PathModified=`, or `OnCalendar=` entries within path and timer units.
- Check the contents of `.path` and `.timer` files that don’t belong to known, legitimate packages.
- Use `journalctl -u ` to review execution logs for suspicious units.
- File Integrity Monitoring (FIM) on `/etc/systemd/system/` and `/usr/lib/systemd/system/` is vital for detecting new or modified unit files.
PAM Module Backdoors and Rootkit Indicators
Pluggable Authentication Modules (PAM) are a core component of Linux authentication, handling user authentication for services like `login`, `ssh`, `su`, and `sudo`. By inserting a malicious PAM module into the authentication stack, an attacker can intercept credentials, grant unauthorized access, or execute code whenever an authentication event occurs.
Beyond PAM, a thorough search for hidden persistence also involves looking for general rootkit indicators, which often include sophisticated methods to hide their presence and maintain access.
Detection Strategy:
- PAM Module Backdoors:
- Inspect `/etc/pam.d/` directory. Each file in this directory corresponds to a service (e.g., `sshd`, `sudo`). Look for suspicious `auth`, `account`, `password`, or `session` entries that load unfamiliar modules (e.g., `auth required pam_malicious.so`).
- Examine the PAM modules themselves, located in `/lib/security/` or `/lib64/security/`. Look for newly added or modified `.so` files. Compare checksums against known good files from package managers.
- Use `ldd` on critical authentication binaries (e.g., `ldd /usr/sbin/sshd`, `ldd /bin/login`) to see which shared libraries they load, looking for anything unusual.
- General Rootkit Indicators:
- File Integrity Monitoring (FIM): An absolute must. Use tools like AIDE or Tripwire to regularly checksum critical system files, binaries (`/bin`, `/sbin`, `/usr/bin`), libraries, and configuration files (`/etc`).
- Hidden Processes: While `ps` can be hooked, compare its output against direct inspection of `/proc` directory entries (`ls -l /proc`).
- Hidden Files/Directories: Look for unusual dotfiles or hidden directories in system paths, especially in `/tmp` or within user home directories.
- Network Anomalies: Use `netstat -tulnp` or `ss -tulnp` to identify unexpected listening ports or unusual outbound connections that persist.
- Kernel Modules: Use `lsmod` to list loaded kernel modules and `modinfo ` to inspect them. Look for unfamiliar modules.
- Modified Binaries: Adversaries may replace legitimate system binaries (e.g., `ls`, `netstat`, `ps`) with trojaned versions. FIM is key here.
Defenders must evolve alongside adversaries. While the usual suspects for persistence remain relevant, a deeper understanding of less common, more sophisticated techniques is crucial for robust security. Regularly auditing these hidden corners of your Windows and Linux systems, coupled with strong monitoring, FIM, and EDR solutions, will significantly enhance your ability to detect and eradicate persistent threats. Stay vigilant, dig deep, and keep hunting for those hidden gems of persistence.