¿Cómo escalar privilegios en Linux?
Table of Contents
ToggleIntroducción
Luego de ganar acceso al sistema, el siguiente paso será escalar privilegios para tener permisos elevados como superusuario, o usuario root. En este apartado estaremos escalando privilegios a través de permisos incorrectos en Sudoers, SUID y Capabilities.
Como bien sabrá, el usuario root es aquel que posee todos los privilegios y puede tener acceso total, o a gran parte de un sistema, equipo o servidor. Por lo tanto, nuestra misión aquí es ver qué tanto podemos llegar a comprometer a una empresa o entidad con permisos elevados. Ya que esto nos dará el “poder” para tratar de acceder a otros equipos futuros, recopilar información confidencial, modificar ficheros a nuestro gusto, entre otras cosas.
Una herramienta fundamental que debemos tener a mano para estudiar lo que vamos a estar viendo, es GTFobins. Este sitio web nos ofrece los binarios con vulnerabilidades o fallos de seguridad que podemos usar para ganar acceso al sistema
Abuso de sudoers
En este caso lo que se intenta hacer es ganar acceso a través de malas configuraciones del archivo /etc/sudoers o binarios que nos permitan la posibilidad de escritura en dicho archivo. Recordemos que en este fichero se establecen las reglas de aquellos usuarios que pueden utilizar el comando “sudo” y el nivel de privilegios del mismo.
En el encontramos las siguientes líneas:
Descripción del archivo
1) En la fila 19 se colocan los usuarios pertenecientes al archivo sudoers. Por lo tanto, en caso de poder escribir en dicho fichero, solo debemos especificar nuestro usuario de la siguiente forma: user ALL=(ALL:ALL) ALL por debajo del usuario root y obtendremos acceso total al sistema vía el comando sudo.
2) En la fila 20 se especifican los privilegios de los usuarios pertenecientes al grupo sudo. En la imagen podemos ver que, todo usuario dentro del grupo sudo, tiene privilegio total del sistema.
Como podemos ver, el usuario ‘kali’ pertence al grupo sudo. Por tanto, posee dichos privilegios.
3) El archivo sudoers admite por defecto la ruta segura de los binarios. En este caso, una vez tengamos acceso al sistema, podemos ejecutar el comando sudo -l y verificar qué binarios posee el usuario con respecto al acceso a dicho archivo, o con cuáles, mediante algún script, podemos ganar acceso.
Veamos el siguiente ejemplo:
Vemos que no tenemos acceso al archivo /etc/sudoers y tampoco pertenecemos al grupo sudo. Sin embargo, cuando ejecutamos sudo -l vemos que podemos correr el binario /usr/bin/zip con permisos elevados.
Por lo tanto, llegados a este punto, deberemos buscar información sobre cómo ganar acceso con dicho binario. Si nos fijamos en la página gtfobins veremos que a través de unas tres simples líneas de código, podemos ganar acceso. Veamos a continuación:
Primero hemos desarrollado un script cuyo contenido es el código de gtfobins (recordar darle permisos de ejecución) y luego lo hemos ejecutado. Como podemos ver, automáticamente nos convertimos en usuario root.
Tener en cuenta
Puede existir el caso que, por una mala configuración del archivo sudoers, se encuentre con los permisos -rw -r- – -w- donde no podemos escribir ni ejecutar. Sin embargo, los usuarios “otros” si pueden hacerlo, y esto, no es impedimento para ganar acceso.
Entonces al ejecutar echo “user = ALL=(ALL) NOPASSWD:ALL” » /etc/sudoers podremos ganar acceso. Podemos comprobar esto tratando de visualizar el archivo con cat /etc/sudoers o haciendo sudo -u root whoami y deberíamos tener como respuesta root.
Permiso SUID
Los permisos suid (Set-User-ID) y sgid (Set-Group-ID) son aquellos que el sistema nos otorga para ejecutar determinadas acciones con permisos elevados. Por ejemplo, como vimos anteriormente podemos usar el binario /usr/bin/sudo para ejecutar ciertos programas con privilegios. También, el binario /usr/bin/passwd nos permite cambiar la contraseña. Para saber más sobre el tema puede informarse con nuestra página de permisos y propietarios
Justamente, estas permisos son especiales porque solo puede realizarlos dicho usuario en su propio sistema, es decir, no podemos usar el binario /usr/bin/passwd para cambiar la contraseña a otro usuario del sistema, o al propio usuario root. Sin embargo, si existen malas configuraciones en algún binario, podremos escalar privilegios.
Por lo tanto, una vez hemos obtenido acceso al sistema, lo que se recomienda siempre es saber qué clase de permisos posee el usuario con el que nos encontramos en dicha máquina. Para ello ejecutamos:
find / -perm -4000 2>/dev/null | xargs ls -la
Con este comando especificamos los permisos que contienen una ‘s’ en lugar de una ‘x’. Es decir, aquellos binarios que tengan privilegios SUID.
Como vemos en la imagen, nos encontramos con el binario /usr/bin/pkexec y /usr/bin/python3.11. Por lo tanto, llegados a este punto, buscaremos algún exploit de los mismos:
Con respecto a pkexec, representa la vulnerabilidad CVE-2021-4034 ya que ha sido de público conocimiento su fallo de seguridad. Por lo tanto, si la distribución de linux que estamos corriendo no tiene los parches de seguridad o posee una versión vieja, la cual podemos saber ejecutando uname –a o lsb_release -a, y explotarla.
En cuanto a al binario de python, si buscamos en gtfobins, podemos ver que nos recomienda ejecutar la siguiente línea:
python -c “import os; os.execl(“/bin/sh”, “sh”, “-p”)”
cuyo resultado será el siguiente:
Dato Importante
En el caso que tengamos permisos SUID con algún binario de editor de texto (por ejemplo vim, nano, emacs, etc..) podríamos realizar lo siguiente:
1) Tener acceso al archivo /etc/shadow y utilizar los hashes de las contraseñas de los usuarios para realizar fuerza bruta. O mejor aún, generar un hash de contraseña con la herramienta mkpasswd, y cambiarlo por la contraseña por defecto que tiene el usuario root.
2) Tener acceso al fichero /etc/passwd, donde encontramos los nombre de usuarios del sistema, y modificar el valor X (lugar del hash de password) por una nueva contraseña nuestra con hash. Esto lo hacemos vía la herramienta openssl de la siguiente manera:
openssl passwd -1 -salt new_password
De esta forma, si hemos cambiado el hash del usuario root, cuando intentemos acceder a través de un “su o su root”, el sistema buscará el usuario en el archivo /etc/passwd, y, una vez lo haya encontrado, en vez de dirijirse al archivo /etc/shadow para ver el hash de la contraseña (que es lo que haría por defecto si estuviese la x). El sistema utilizará el propio hash que hemos creado. De esta forma, la contraseña del usuario root se habrá cambiado debido que nuestro cambio está un “un paso antes” que el original.
Uso de Capabilites
Hemos visto que a través del archivo sudoers podemos modificar ciertos permisos y hacer uso del comando sudo, como así también, utilizar los permisos SUID de ciertos binarios y aprovecharnos de fallos o configuraciones que nos permiten ganar acceso al sistema. Por lo tanto, hemos intentado hacernos de sudo y binarios asignados a un usuario. Sin embargo, esto no es lo que buscaremos precisamente a continuación.
Las capabilities son aquellas funciones que aportan un sistema de seguridad, el cual, permite dividir los privilegios del usuario o programas de nivel del kernel en pequeñas partes con distintos valores. Estos, pueden ser asignados de forma independiente a procesos de modo que, para realizar una operación privilegiada, ese proceso cuente únicamente con el permiso necesario sin tener que asumir la identidad de superusuario.
Tipos de Capabilites
Existen muchos tipos de capabilities. No obstante, vamos a mencionar las más relevantes y que estaremos ejecutando. Estas son:
- CAP_SETUID: Nos permite manipular el bit SUID del fichero.
- CAP_SETGID: Nos permite manipular el bit SGID del fichero.
Por lo tanto, haciendo uso de las capabilities es posible conseguir que usuarios o procesos realicen tareas privilegiadas con una mayor granularidad a la hora de asignar los permisos necesarios. Entonces, en el caso de usar setuid para conceder privilegio a, por ejemplo /usr/bin/date, si una vulnerabilidad en el binario permitiese a un atacante obtener una shell en la ejecución: el resultado sería una shell con privilegios de root.. así de simple.
Valores de Capabilites
Los valores de las capabilites son:
P (Permitted): Marca la capability como habilitada. Es decir, ahora esta podrá tener el valor de Effective o Inheritable.
E (Effective): Aplica la capability al proceso definido.
I (Inheritable): La pueden heredar los subprocesos.
Por tanto, en el caso anterior, únicamente se obtendría el privilegio cap_sys_time o incluso ninguno, al no especificar como heredado dicho privilegio.
Para no entrar en muchos detalles, lo que nos interesa a nosotros para elevar privilegios son aquellas capabilities asignadas al fichero como PE que posea el usuario y no tenga procesos heredados.
Capabilites del Sistema
Para saber las capabilites que hay en el sistema podemos ejecutar:
getcap -r / 2>/dev/null
A modo de ejemplo, le asignaremos los valores PE al binario /usr/bin/perl de la siguiente manera:
setcap get_cap+ep /usr/bin/perl
Ahora bien, si volvemos a gtfobins veremos que existe una forma de ganar acceso a través de la siguiente función:
cp $(which perl) . ; perl -e ‘use POSIX qw (setuid); POSIX::setuid(0); exec “/bin/sh”; ’
Como vemos, hemos tenido éxito y logrado el acceso como superusuario.
Ahora bien, en estos casos cuando ganamos acceso a una máquina podemos realizar el tratamiento de tty o terminal. Esto es, modificar ciertos valores para tener una mejor “vista” y manipulación del sistema de archivos del sistema como se muestra en la siguiente imagen:
Lo que hemos hecho aquí es, mediante la línea script /dev/null -c bash hemos creado una pseudoconsola. También, podríamos retornar a la consola indicándole que reinicie la terminal con stty raw -echo ; fg luego de ejecutar el comando anterior. Y finalmente, verificar que por lo menos la variable $TERM=xterm y $SHELL=bash (en nuestro caso la Shell=zsh) como vimos en la imagen anterior.