10 minutes
linux privilege escalation basics
hi!
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 likehashcat
orjohn
) - 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
- can we read
- environment variables
- current
$PATH
env
information
- current
- 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
- basic system information
-
exploitation
- world-writable files
- credential reuse
- sudo rights
- vulnerable software
- vulnerable kernel
- setuid binaries
- misconfigured cron jobs
enumeration
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.
environment
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.
exploitation
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
SGB28vgY8Us8Y
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.
end
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!