Detect Bind Mounts in Splunk
Adversaries may abuse bind mounts on Linux file structures to hide malicious process activity from native utilities such as ps, top, and /proc filesystem inspection. A bind mount maps a directory or file from one location to another using mount --bind, mount -B, or mount -o bind. By overlaying a benign process's /proc entry on top of a malicious process's /proc directory (e.g., mount --bind /proc/<benign_pid> /proc/<malicious_pid>), adversaries cause the kernel to present false process metadata to monitoring utilities. This technique requires root or sudo privileges and has been observed in active campaigns including Commando Cat (Docker container abuse) and cryptomining attacks documented by AhnLab.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Technique
- T1564 Hide Artifacts
- Sub-technique
- T1564.013 Bind Mounts
- Canonical reference
- https://attack.mitre.org/techniques/T1564/013/
SPL Detection Query
index=linux sourcetype="linux:audit"
| eval a0=coalesce(a0,""), a1=coalesce(a1,""), a2=coalesce(a2,""), a3=coalesce(a3,""), a4=coalesce(a4,"")
| eval cmdline=a0." ".a1." ".a2." ".a3." ".a4
| eval bind_flag=case(
a1="--bind", 1,
a1="-B", 1,
(a1="-o" AND a2="bind"), 1,
a1="-obind", 1,
match(cmdline, "(--bind|-obind)"), 1,
1=1, 0
)
| eval proc_target=if(match(cmdline, "/proc/\d+"), 1, 0)
| where type="EXECVE" AND a0="mount" AND bind_flag=1 AND proc_target=1
| eval target_pid=replace(replace(cmdline, ".*(/proc/\d+).*", "\1"), ".*(\d+).*", "\1")
| eval source_path=replace(cmdline, "mount[^/]*(/[^\s]+)\s+/proc.*", "\1")
| eval is_empty_dir_mount=if(NOT match(source_path, "/proc/"), 1, 0)
| eval is_proc_over_proc=if(match(source_path, "/proc/\d+"), 1, 0)
| join type=left pid [
search index=linux sourcetype="linux:audit" type=SYSCALL
| table pid, uid, auid, exe, comm, key, ppid
]
| table _time, host, pid, ppid, uid, auid, exe, comm, cmdline, source_path, target_pid, is_empty_dir_mount, is_proc_over_proc, key
| sort - _time Detects bind mount operations targeting /proc process directories using Linux auditd EXECVE records. Joins EXECVE argument data with SYSCALL context to enrich with UID, AUID (audit user ID), parent PID, and executable path. Flags two high-risk patterns: is_empty_dir_mount=1 (mounting an empty/benign directory over a process entry to completely hide it) and is_proc_over_proc=1 (swapping one /proc entry for another to substitute fake process metadata). Requires auditd rule: -a exit,always -F arch=b64 -S execve -F exe=/usr/bin/mount -k bind_mount_proc
Data Sources
Required Sourcetypes
False Positives & Tuning
- Container runtimes invoking bind mounts for volume mapping — filter by comm!="containerd" AND comm!="dockerd" AND comm!="runc"
- System initialization scripts during boot that set up namespace mounts in /proc — filter by auid=4294967295 (unset AUID) if baseline confirms this
- Kubernetes node agents (kubelet) performing bind mounts for pod volume provisioning
- Legitimate chroot setup scripts used by hosting providers or jail environments
Other platforms for T1564.013
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 1Bind Mount Empty Directory Over Process /proc Entry
Expected signal: auditd EXECVE: type=EXECVE msg=audit(...): argc=4 a0="mount" a1="--bind" a2="/tmp/empty_proc_decoy" a3="/proc/<pid>". auditd SYSCALL: syscall=mount uid=0 auid=<real_user_uid> exe=/usr/bin/mount comm=mount. Sysmon for Linux (if deployed): EventCode=1, Image=/usr/bin/mount, CommandLine='mount --bind /tmp/empty_proc_decoy /proc/<pid>'. DeviceProcessEvents: FileName=mount, ProcessCommandLine containing '--bind' and '/proc/<numeric_pid>'.
- Test 2Bind Mount Benign Process /proc Entry Over Malicious Process
Expected signal: auditd EXECVE: a0=mount a1=--bind a2=/proc/<benign_pid> a3=/proc/<malicious_pid>. auditd SYSCALL: syscall=mount, uid=0, auid=<escalated_user_uid>. DeviceProcessEvents: ProcessCommandLine='mount --bind /proc/<benign_pid> /proc/<malicious_pid>', both paths matching /proc/\d+ pattern. Kernel audit trail will show two numeric /proc paths as arguments.
- Test 3Bind Mount Using -B Short Flag (Alternative Syntax)
Expected signal: auditd EXECVE: a0=mount a1=-B a2=/tmp/df00tech_decoy a3=/proc/<pid>. Note: -B must be detected separately from --bind. DeviceProcessEvents: ProcessCommandLine containing ' -B ' with /proc/<pid>. Detection queries that only match on '--bind' will miss this variant — verify both patterns fire.
- Test 4Simulate Commando Cat Docker Container Bind Mount Pattern
Expected signal: DeviceProcessEvents: FileName=mount, InitiatingProcessFileName=bash (inside container namespace), ProcessCommandLine='mount --bind /decoy /host_proc/<pid>'. Container runtime logs: docker run event with --privileged and --pid=host flags. auditd on host: SYSCALL mount from container namespace, uid=0, auid may be 4294967295 (unset) if running fully inside container — key differentiator for container-origin attacks. Docker events: `docker events --filter event=start` will show the container invocation.
References (9)
- https://attack.mitre.org/techniques/T1564/013/
- https://www.cadosecurity.com/blog/the-nine-lives-of-commando-cat-analysing-a-novel-malware-campaign-targeting-docker
- https://asec.ahnlab.com/en/51908/
- https://man7.org/linux/man-pages/man8/mount.8.html
- https://man7.org/linux/man-pages/man2/mount.2.html
- https://www.kernel.org/doc/html/latest/filesystems/sharedsubtree.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1564.013/T1564.013.md
- https://learn.microsoft.com/en-us/azure/sentinel/connect-syslog
- https://docs.splunk.com/Documentation/AddOns/released/LinuxAudit/Configureinputs
Unlock Pro Content
Get the full detection package for T1564.013 including response playbook, investigation guide, and atomic red team tests.