Linux capabilities grant specific privileges to a binary without making it fully setuid. Some of them, notably cap_setuid, cap_dac_read_search, cap_dac_override and cap_sys_admin, are equivalent to root when held by an interpreter or file utility (T1548). Attackers enumerate with getcap, run the binary with a one-line escalation, and sometimes add capabilities to keep access. Each step can be audited.
Signals at a Glance
| Signal | Where | ATT&CK |
|---|---|---|
| getcap -r / run by a non-administrator | auditd execve, EDR | T1548 |
| setcap executed or security.capability extended attribute set | auditd, FIM | T1548 |
| Interpreter (python, perl, php, node, ruby) holding cap_setuid | Capability inventory | T1548 |
| setuid(0) or setresuid by a process started by a non-root audit user | auditd syscall records | T1548 |
| Interpreter one-liner calling setuid and spawning a shell | Process command line | T1059.006 |
Auditing Enumeration and Change
Capabilities are stored as extended attributes, so changes are rare and easy to inventory. Audit the tools that read and write them, and the syscall an escalation depends on:
# /etc/audit/rules.d/capabilities.rules -w /usr/sbin/setcap -p x -k cap_set -w /usr/sbin/getcap -p x -k cap_enum -a always,exit -F arch=b64 -S setuid,setresuid,setreuid -F a0=0 -F auid>=1000 -F auid!=-1 -k setuid_zero # tune/validate: confirm the getcap and setcap paths on your distribution (/sbin or /usr/sbin).
Inventory and Command Lines
A scheduled inventory is the highest-value control, because few binaries should hold capabilities at all. Diff the output against a baseline per host class, and treat any interpreter or file-reading capability as a finding:
# Capability inventory: run daily, ship output to your SIEM, alert on additions getcap -r / 2>/dev/null | sort > /var/tmp/caps.$(date +%F) # Highest-risk grants to review first: grep -E 'cap_setuid|cap_setgid|cap_dac_override|cap_dac_read_search|cap_sys_admin|cap_sys_ptrace|cap_chown' /var/tmp/caps.$(date +%F) # tune/validate: ping and some network tools legitimately hold cap_net_raw.
title: Interpreter Escalation via setuid(0) One-Liner
logsource:
product: linux
category: process_creation
detection:
selection_img:
Image|endswith:
- '/python'
- '/python3'
- '/perl'
- '/php'
- '/node'
- '/ruby'
selection_cmd:
CommandLine|contains:
- 'setuid(0)'
- 'posix.setuid(0)'
- 'process.setuid(0)'
condition: selection_img and selection_cmd
level: high
# tune/validate: legitimate administrative scripts rarely pass a literal setuid(0) on the command line.
- Remove capabilities from interpreters entirely. If a script needs privileged operations, give a purpose-built binary only the specific capability required.
- Alert on any new security.capability extended attribute on a file in a user-writable or application directory.
- Container runtimes add capabilities at start time. Review the capability set of privileged and hostPath-mounted containers separately from host binaries.
Use GTFOBins, which lists capability escalation methods per binary, the SigmaHQ Linux process-creation and auditd rules, Elastic’s prebuilt rules for capability enumeration and modification, and Atomic Red Team Linux tests for validation. Baseline your own environment — network utilities and containers use capabilities legitimately.
Build Detections That Fire
Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.
- Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
- Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
- 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Stay ahead of emerging threats. Get notified when we publish new intelligence reports and advisories.
Subscribe to Alerts