Vulnhub es un portal que ofrece máquinas vulnerables hechas por la comunidad para ser explotadas. El objetivo es claro: aprender diferentes técnicas y poner en práctica lo aprendido en un entorno seguro. Ellos mismos definen esta plataforma así: “VulnHub fue creado para cubrir las máximas máquinas de entrenamiento posible, creando un catalogo de ‘cosas’ que legalmente se pueden romper, hackear y explotar, permitiendo aprender en un entorno seguro”.
En esta entrada veremos el recorrido de la explotación de una máquina boot2root de Vulnhub: Toppo. Como se explicó en el post anterior, se trata de un tipo de reto cuyo objetivo es explotar una máquina para conseguir la bandera o banderas, que son unos ficheros de texto que contienen un código o hash. Por lo general suele haber una bandera de usuario (user.txt) y una vez se consiguen privilegios de administrador y se tiene control total sobre la máquina se tiene acceso a la bandera de root (root.txt). Esto en la mayoría de los casos, pero no siempre tiene porque ser así. En este caso nos encontraremos solo con una bandera al conseguir rootear la máquina.
Reconocimiento: conectividad y escaneo de puertos
El primer paso es el de reconocimiento mediante el escaneo de puertos. Como en este caso ya sabemos la IP de la máquina, comprobamos que existe conectividad entre la víctima y el atacante:
![]() |
Figura 1: Comprobando conectividad con el objetivo |
Mediante nmap se realizará un escaneo de la máquina objetivo:
nmap -sC -sV -o nmap.tcp 10.0.2.10
En el comando incluiremos la opción -sC para que ejecute los scripts que tiene nmap por defecto, -sV para que enumere las versiones de los servicios encontrados en los puertos abiertos, y por último, la opción -o permite exportar la salida a un fichero para poder consultarlo posteriormente.
![]() |
Figura 2: Resultados de nmap |
Como puertos abiertos encontramos:
- 22 con el servicio ssh: Versión OpenSSH 6.7p1
- 80 con el servicio http: Apache 2.4.10 (Debian)
- 111 con el servicio rpcbind.
Enumeración
El procedimiento que sigo en este punto es el siguiente: ver qué servicios están corriendo y si no conozco alguno investigar acerca de él para entenderlo: qué versión está corriendo, qué aporta de manera global a la arquitectura de la máquina, analizar cómo está funcionando, de qué manera puede ser vulnerable dicho servicio, cómo nos puede posibilitar la entrada a la máquina objetivo, etc. El análisis es realizado de manera individual por cada servicio. Esto permite aislar cada uno de ellos para realizar un análisis más profundo y con mayor concentración, pero, cómo se ha comentado, nunca hay que perder de vista el foco total de la máquina y qué aporta el servicio analizado a la fotografía completa de la misma.
Como nos había indicado el script de nmap se trata de un servidor Apache 2.4.10. Esta información será útil si en algún momento hay que buscar algún exploit o vulnerabilidad asociada la versión del servidor web.
Banner grabbing
Puerto 22: SSH
Empezamos con SSH. Comprobamos que es posible conectarnos a la máquina mediante este servicio. Como vemos nos permite autenticarnos a través de contraseña, no es necesario aportar ninguna clave privada:![]() |
Figura 3: Testing de ssh |
Puerto 80: http
Se realizará un análisis de las cabeceras de la respuesta al realizar una petición para ver si podemos sacar algún tipo de información acerca del servidor. En este ocasión se utilizará curl:Figura 4: Cabeceras http |
Como nos había indicado el script de nmap se trata de un servidor Apache 2.4.10. Esta información será útil si en algún momento hay que buscar algún exploit o vulnerabilidad asociada la versión del servidor web.
Accedemos con el navegador y observamos la funcionalidad del sitio. En este caso se trata un blog con una plantilla de Bootstrap 4. Navegando por la plataforma no parece que haya gran cosa ni nada que explotar, aparentemente.
gobuster -u http://10.0.2.10 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -o gobuster.medium
Mediante -u le indicamos la url, con -w el diccionario, con -t (opcional) el número de hilos y con -o (opcional) el fichero de salida. El resultado es el siguiente:
![]() |
Figura 5: Sitio web a través del navegador |
Listado por fuerza bruta de directorios
Lo siguiente que haremos será realizar un listado de fuerza bruta de directorios para ver si encontramos algo jugoso, algún directorio perdido o página que nos sea útil y nos sirva como vector de entrada. Existen muchas herramientas para realizar esta tarea, en esta ocasión usaremos Gobuster:gobuster -u http://10.0.2.10 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -o gobuster.medium
Mediante -u le indicamos la url, con -w el diccionario, con -t (opcional) el número de hilos y con -o (opcional) el fichero de salida. El resultado es el siguiente:
![]() |
Figura 6: Resultados de gobuster |
A simple vista, el directorio que más llama la atención es /admin. Los otros directorios a los que se puede acceder no tienen nada interesante, albergan ficheros del servidor que en este caso no nos son útiles. En /admin encontramos un índice de directorios con un fichero que tiene como nombre notes.txt. Al acceder al mismo nos encontramos con el siguiente mensaje:
![]() |
Figura 7: Mensaje al acceder a /admin/notes.txt |
Como vemos el administrador del blog no es muy cuidadoso con la seguridad (prefiere ir a pescar o ver fútbol) y nos deja una contraseña: 12345ted123.
Explotación: acceso al sistema
En la aplicación web no hemos encontrado ninguna funcionalidad que nos permita iniciar sesión. Por lo tanto, vamos a probar mediante ssh. Pero para ello tenemos que proporcionar, además de la contraseña, el nombre del usuario del equipo al que queremos conectarnos. La contraseña es 12345ted123, viendo que prefiere ir a pescar o ver fútbol que preocuparse por la seguridad... ¿qué tal probar con el usuario ted?
![]() |
Figura 8: Acceso mediante ssh |
Post-explotación: escalada de privilegios
Lo primero de todo recabamos información acerca de a qué grupos pertenece el usuario, cuál es la versión del sistema operativo, qué puede ejecutar el usuario con el que tenemos acceso con privilegios de administrador, etc. Es decir: toda información que nos pueda ser de utilidad para explotar un vulnerabilidad o fallo de configuración que nos permita una escalada de privilegios en el sistema. Examinando el fichero /etc/sudoers encontramos que el usuario ted puede ejecutar el binario /usr/bin/awk como root sin tener que proporcionar su contraseña:
![]() |
Figura 9: Acciones post-explotación |
Esto nos será útil posteriormente para escalar privilegios. De momento, seguimos recabando información.
![]() |
Figura 10: Bit SUID en /usr/bin/passwd |
Nota: El bit SGID actúa conceptualmente de la misma manera que el SUID pero se aplica al grupo dueño del binario, representado también con una “s” pero en los permisos de ejecución del grupo creador del binario.
find / -perm -4000 2>/dev/null
![]() |
Figura 11: Búsqueda de binarios con bit SUID activo |
Escalada de privilegios mediante mawk
Awk es un lenguaje de programación nacido ni más ni menos que en 1977. Mawk es una implementación más rápida de awk. Debido a este error de configuración, tendremos la posibilidad de ejecutar cualquier script escrito en este lenguaje con el usuario “ted” con privilegios de root, gracias al bit SUID.awk 'BEGIN{system("[comando]")}'
![]() |
Figura 12: Ejecución de comandos con awk |
Por tanto, como el binario mawk tiene el bit SUID activo, si invocamos una shell mediante mawk, esta tendrá privilegios de root y habremos conseguido la escalada de privilegios y nuestra preciada bandera:
![]() |
Figura 13: Escalada de privilegios mediante mawk y lectura de la flag |
sudo awk 'BEGIN{system("/bin/sh")}'
Escalada de privilegios mediante python
Como hemos visto, al igual que con awk, cualquier script ejecutado en Python2.7 tendrá privilegios de root debido al bit SUID. Los pasos son los mismos: ejecutar mediante Python un comando que nos permita obtener una shell como root:
/usr/bin/pyton2.7 -c 'import os; os.system("/bin/sh")'
ó
/usr/bin/pyton2.7 -c 'import pty; pty.spawn("/bin/sh")'
![]() |
Figura 14: Escalada de privilegios mediante Python |
Conclusiones
- El punto de entrada ha sido muy sencillo, mostrando la contraseña del usuario en un fichero del servidor, algo poco realista y que no será tan fácil en otras máquinas.
- Subrayar la importancia del bit SUID y los permisos de superusuario mediante el fichero /etc/sudoers, que nos han permitido la escalada de privilegios, los cuales serán de alto interés desde un punto de vista ofensivo en el resto de intrusiones. Por otro lado, desde un punto de vista defensivo, hay que tener cuidado prestando atención a qué binarios les damos este tipo de permisos o qué binarios pueden ser ejecutados mediante sudo sin proporcionar contraseña, aplicando siempre el principio del mínimo privilegio. Se deben contemplar el uso de las capabilities de Linux siempre que sea posible, las cuales permiten diseccionar los privilegios de root en diferentes valores asignándolos a procesos de manera independiente sin tener que asumir la identidad de superusuario.
Referencias:
https://www.vulnhub.com/entry/toppo-1,245/
https://es.wikipedia.org/wiki/AWK
https://www.incibe-cert.es/blog/linux-capabilities
Comentarios
Publicar un comentario