Break Process Trees
An adversary may attempt to evade process tree-based analysis by modifying executed malware's parent process ID (PPID). If endpoint protection software leverages the parent-child relationship for detection, breaking this relationship could result in the adversary's behavior not being associated with previous process tree activity. On Linux systems, adversaries may execute a series of Native API calls to alter malware's process tree. For example, adversaries can execute their payload without any arguments, call the fork() API call twice, then have the parent process exit. This creates a grandchild process with no parent process that is immediately adopted by the init system process (PID 1), which successfully disconnects the execution of the adversary's payload from its previous process tree. Another example is using the daemon syscall to detach from the current parent process and run in the background.
Syslog
| where Timestamp > ago(24h)
| where Facility == "authpriv" or Facility == "auth" or Facility == "daemon"
| where SyslogMessage has_any ("fork", "daemon", "setsid", "double fork")
| project Timestamp, Computer, Facility, SyslogMessage;
let OrphanedProcesses = Syslog
| where Timestamp > ago(24h)
| where ProcessName !in ("systemd", "init", "cron", "atd", "sshd", "dockerd", "containerd")
| where SyslogMessage has "PPID=1" or SyslogMessage has "ppid=1"
| project Timestamp, Computer, ProcessName, SyslogMessage;
let AuditFork = Syslog
| where Timestamp > ago(24h)
| where Facility == "authpriv"
| where SyslogMessage has "type=SYSCALL" and SyslogMessage has_any ("syscall=57", "syscall=58", "syscall=56")
| project Timestamp, Computer, SyslogMessage;
union OrphanedProcesses, AuditFork
| sort by Timestamp desc Data Sources
Required Tables
False Positives
- Legitimate Linux daemons that intentionally double-fork during startup (e.g., Apache httpd, nginx, postfix, named) — these are expected to run with PPID=1
- System administration scripts that use 'nohup' or 'disown' to detach long-running background processes from the controlling terminal
- Container runtimes (Docker, containerd, CRI-O) that fork child processes which naturally become orphaned when the parent container process exits
- Cron jobs and at-scheduled tasks that fork child processes — the cron daemon itself runs with PPID=1
References (7)
- https://attack.mitre.org/techniques/T1036/009/
- https://0xjet.github.io/3OHA/2022/04/11/post.html
- https://sandflysecurity.com/blog/bpfdoor-an-evasive-linux-backdoor-technical-analysis/
- https://www.microsoft.com/en-us/security/blog/2022/05/19/rise-in-xorddos-a-deeper-look-at-the-stealthy-ddos-malware-targeting-linux-devices/
- https://man7.org/linux/man-pages/man2/fork.2.html
- https://man7.org/linux/man-pages/man3/daemon.3.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1036.009/T1036.009.md
Unlock Pro Content
Get the full detection package for T1036.009 including response playbook, investigation guide, and atomic red team tests.