Writing detection rules for process injection on Linux
Process injection on Linux takes multiple forms - ptrace, /proc/mem writes, LD_PRELOAD hijacking. Here's how to write detection rules that catch each variant.
Process injection is one of those techniques that gets extensive coverage on Windows and almost none on Linux. The result is a real detection gap: defenders tune their rules for CreateRemoteThread and WriteProcessMemory while attackers quietly abuse ptrace and /proc/[pid]/mem on Linux servers where nobody is watching.
This post covers the main Linux injection paths, what telemetry you need to detect them, and concrete Sigma rules you can adapt for your own environment.
The four main injection paths on Linux
MITRE ATT&CK T1055 covers process injection across platforms, with several sub-techniques that are Linux-specific or Linux-common.
T1055.008 - Ptrace system calls. ptrace is the Linux kernel interface used by debuggers. An attacker calls ptrace(PTRACE_ATTACH, target_pid, ...) to attach to a running process, uses PTRACE_POKEDATA to overwrite memory with shellcode, then PTRACE_DETACH to resume and disappear. The injected code runs inside the target process, inheriting its privileges and file descriptor table.
T1055.009 - /proc/[pid]/mem writes. Less well-known but no ptrace call required. On Linux, /proc/[pid]/mem exposes a process’s virtual address space as a file. An attacker with sufficient privilege can open it for write and patch shellcode directly into the target’s memory. Detections that only watch ptrace syscalls will miss this entirely.
LD_PRELOAD injection. Set LD_PRELOAD in the environment before launching a process, or write a shared library path to /etc/ld.so.preload, and the dynamic linker will load that library into every new process. Not strictly runtime injection, but the net effect - attacker-controlled code running inside another process - is the same.
Shared library injection via ptrace. Attach to a process with ptrace, write shellcode that calls dlopen() with a path to an attacker-controlled .so file, execute it, then detach. The attacker’s shared library is now resident in the target process without appearing in the original binary.
Each path leaves different forensic evidence. A detection strategy that covers only one of them is incomplete.
What telemetry you actually need
Before writing a single rule, audit what your EDR is collecting. The minimum set for Linux injection detection:
- Syscall events:
ptrace,process_vm_writev,process_vm_readv,memfd_create. These are the direct building blocks of most injection techniques. - File access events: Opens of
/proc/[pid]/memwith write flags, and modifications to/etc/ld.so.preload. - Process creation events: Includes the full environment block (not just argv) so you can inspect
LD_PRELOADandLD_LIBRARY_PATHat launch time. - Module load events:
/proc/[pid]/mapschanges that introduce new shared libraries into a long-running process.
eBPF-based collection captures all of these with low overhead. Kernel module-based agents often instrument only execve and file events - if that describes your current EDR, you have a significant blind spot.
Detection rules
Here are three Sigma rules covering the primary injection paths.
Ptrace attach against a non-child process:
title: Ptrace Injection - Non-Child Attach
id: a7f3c1d2-5501-4e8a-b310-000000000001
status: experimental
description: >
Detects ptrace(PTRACE_ATTACH) called against a process that is not
a child of the calling process. Legitimate debuggers attach to children
or to processes the developer explicitly owns. Attacker tooling attaches
to unrelated targets.
logsource:
category: process_access
product: linux
detection:
selection:
syscall: ptrace
ptrace_request: PTRACE_ATTACH
filter_child:
target_pid|equals|field: parent_pid
condition: selection and not filter_child
falsepositives:
- gdb, strace, perf, lldb used by developers
- Security scanning and profiling tools
level: medium
tags:
- attack.t1055.008
- attack.defense_evasion
Direct /proc memory write:
title: Direct /proc/pid/mem Write
id: a7f3c1d2-5501-4e8a-b310-000000000002
status: experimental
description: >
Detects file open of /proc/[pid]/mem with write intent.
Legitimate software rarely writes directly to another process's
memory via the /proc filesystem.
logsource:
category: file_access
product: linux
detection:
selection:
file_path|re: '^/proc/\d+/mem$'
open_flags|contains:
- 'O_WRONLY'
- 'O_RDWR'
condition: selection
falsepositives:
- Memory profiling tools in development environments
level: high
tags:
- attack.t1055.009
- attack.defense_evasion
Process launch with non-standard LD_PRELOAD:
title: Process Launch with Non-Standard LD_PRELOAD
id: a7f3c1d2-5501-4e8a-b310-000000000003
status: experimental
description: >
Detects process execution where LD_PRELOAD is set to a path outside
standard system library directories. Legitimate LD_PRELOAD usage
(jemalloc, libfaketime) points to known paths.
logsource:
category: process_creation
product: linux
detection:
selection:
env_vars|contains: 'LD_PRELOAD='
filter_known_paths:
env_vars|contains:
- '/usr/lib/'
- '/usr/local/lib/'
- '/lib/'
condition: selection and not filter_known_paths
falsepositives:
- Developer workstations using custom allocators or profilers
level: medium
tags:
- attack.t1055
- attack.defense_evasion
Reducing noise without missing attacks
These rules will generate false positives in any non-trivial environment. The goal is not silence - it is manageable signal. Three practical tuning approaches:
Allowlist by process name with caution. gdb, strace, and lldb use ptrace legitimately. Add them to your filter, but note that attacker tooling sometimes adopts these names. Combine a process name allowlist with a parent process check (a gdb spawned from a CI runner is different from one spawned by a process that arrived over a network connection).
Correlate across the process tree. An isolated ptrace event is probably noise. The same process also writing to /proc/[pid]/mem and spawning a new child 500ms later is a high-confidence cluster. Real-time behavioural detection that correlates related events is far more precise than any single-event rule.
Segment by host role. Developer workstations will generate ptrace events constantly. Production servers running containerised workloads almost never should. Maintain separate alert thresholds for each host classification and escalate the production tier aggressively.
If you want to test your current Linux detection coverage against these injection paths, get in touch - we run detection gap assessments against MITRE ATT&CK sub-techniques as part of the LightEDR evaluation.