Linux Capabilities for Privilege Escalation

What They Are, How to Find Them, and How to Abuse Them as a Pentester

In modern Linux systems, root isn’t always all-or-nothing anymore. Since kernel 2.2, Linux has supported a feature called Capabilities, which splits root privileges into fine-grained controls.

Why does that matter to you as a pentester?
Because some of these capabilities can be just as dangerous as full root access — if not more so — and they’re often overlooked during privilege escalation.

This post covers:

  • What Linux capabilities are
  • How to find binaries with capabilities
  • Common capabilities you should look for
  • How to abuse them for privilege escalation

Instead of giving a binary full root powers, Linux lets you assign specific privileges via capabilities.
For example:

  • Instead of root being able to load kernel modules, you can assign just that ability using CAP_SYS_MODULE.
  • Instead of full read access, you can give a binary CAP_DAC_READ_SEARCH to bypass file read restrictions.

Capabilities are usually applied to:

  • Binaries
  • Running processes
getcap -r / 2>/dev/null
# Recursively list all files with capabilities

Output looks like:

/usr/bin/ping = cap_net_raw+ep
/usr/bin/viewer = cap_dac_read_search+ep

Breakdown:

  • e = effective
  • p = permitted
  • i = inheritable
ps aux | grep <process>
getpcaps <PID>

Or for the current shell:

capsh --print

Let’s go over the most dangerous ones from a pentester’s view.

Allows changing user/group IDs.

Abuse:

Escalate to root by changing UID in a custom binary.

Example C code:

#include <unistd.h>
int main() {
    setuid(0);
    setgid(0);
    system("/bin/bash");
}

Compile and set capability:

gcc rootme.c -o rootme
sudo setcap cap_setuid+ep ./rootme
./rootme

Bypass file read and directory traversal permissions.

Abuse:

Read sensitive files like /etc/shadow even as a non-root user.

Test it:

cat /etc/shadow

If it works — you’re leaking password hashes.

Allows attaching to other processes (debugging).

Abuse:

Attach to and dump memory of any process (like sshd, bash, or even gpg-agent).

strace -p <PID>
gcore <PID>

You can even dump LSASS-equivalent memory if this is used in wine/crossover setups.

Load or remove kernel modules.

Abuse:

Load a custom kernel module that gives you root (e.g., rootkit.ko).

Very dangerous. Should never be given to user binaries.

Configure networking interfaces.

Abuse:

  • Create TUN interfaces
  • ARP poisoning
  • Change firewall rules
  • Enable packet forwarding (pivoting)

Use raw sockets (like for packet crafting).

Abuse:

Send spoofed packets using tools like ping, nmap, scapy, or custom exploits.

Perform chroot calls.

Abuse:

If you can run chroot as root, and control the filesystem structure, you can often escape confinement.

Pair this with CAP_DAC_READ_SEARCH or CAP_SETUID for full root breakout.

Basically root.

This one is a mess of powers. If you see this — just assume root is right around the corner.

Includes:

  • Mounting filesystems
  • Creating device nodes
  • Bypassing many other restrictions
CapabilityAbuse PotentialCommands/Usage
CAP_SETUIDRun as rootWrite binary with setuid(0)
CAP_DAC_READ_SEARCHRead sensitive filescat /etc/shadow
CAP_SYS_PTRACEDump process memorygcore <PID> / strace -p <PID>
CAP_SYS_MODULELoad malicious kernel modulesinsmod rootkit.ko
CAP_NET_RAWSend raw packetsping, nmap, scapy
CAP_NET_ADMINNetwork manipulation (pivoting)ip addr add, iptables, sysctl net.ipv4.ip_forward=1
CAP_SYS_CHROOTJail breakout via chrootchroot .
CAP_SYS_ADMINAll the thingsJust escalate — it’s basically root
echo -e '#include <unistd.h>\nint main() { setuid(0); system("/bin/bash"); }' > rootme.c
gcc rootme.c -o rootme
sudo setcap cap_setuid+ep ./rootme
./rootme

As a defender (or if you’re just cleaning up):

sudo setcap -r /path/to/binary

Capabilities are one of the most underused privesc vectors in Linux environments. They often slip through code reviews and hardening because they “aren’t technically SUID” — but many are just as dangerous.

As a pentester, add getcap -r / 2>/dev/null to your standard post-exploitation enumeration flow.

Scroll to Top