Book - HackTheBox

9 minute read

En este post se explicarán los pasos que se han seguido para conseguir vulnerar la seguridad de la máquina Book en Hack The Box, tal y como se refleja, es un sistema Linux con un nivel de dificultad medio (6.2).

Ilustración 1: Book.

La fase de enumeración dio comienzo haciendo uso de NMAP:

Ilustración 2: Comando de NMAP ejecutado.

Ilustración 3: Resultados de NMAP.

Analizando los resultados obtenidos, se puede apreciar que es un sistema Ubuntu, con el servicio SSH habilitado en el puerto 22 y el servicio web Apache 2.4.29 en el puerto 80.

Ilustración 4: Web en http://10.10.10.176.

Todo apuntaba a que la intrusión al sistema debía pasar por vulnerar la seguridad de la web, por tanto, se hizo un breve reconocimiento para determinar el funcionamiento de ésta, creando usuarios y visitando las diferentes páginas.

Ilustración 5: Creación de usuario.

Ilustración 6: Página inicial.

Ilustración 7: Página http://10.10.10.176/books.php.

Ilustración 8: Descarga de libros en https://10.10.10.176/download.php?file=1.

Una de las funcionalidades que poseía el usuario sin privilegios era la posibilidad de descargar los libros en formato PDF, que se listaban en la página http://10.10.10.176/books.php.

Se analizaron los metadatos en busca de usuarios o información relevante:

Ilustración 9: Búsqueda de metadatos.

Se encontró un posible nombre de usuario, derek. Pero se continuó realizando un reconocimiento de la web en busca de algún vector de ataque.

En la página http://10.10.10.176/collections.php era posible subir un fichero PDF, que podría ser buscado por nombre o autor en http://10.10.10.176/search.php, para su posterior descarga desde http://10.10.10.176/download.php?file=ID.

Ilustración 10: Subiendo un fichero PDF http://10.10.10.176/collections.php.

Ilustración 11: Búsqueda del fichero PDF subido en http://10.10.10.176/search.php.

Ilustración 12: Descarga del fichero PDF subido a la web, con nombre 87905.pdf.

Siempre que se subía un fichero el nombre era modificado por un número identificativo. En la página http://10.10.10.176/feedback.php se podían enviar comentarios sobre un libro.

Ilustración 13: http://10.10.10.176/feedback.php.

En el perfil del usuario se especificaba el rol que cumplía. Se probó a capturar la petición con BurpSuite e intentar cambiar el rol User por Admin, pero no funcionó, únicamente se podía modificar el nombre de usuario.

Ilustración 14: Perfil del usuario MrTux.

En la página http://10.10.10.176/contact.php era posible enviar mensaje directo al administrador de la web. Se podía visualizar su correo electrónico, por tanto, se deducía su nombre de usuario.

Ilustración 15: Correo de administrador de la web en http://10.10.10.176/contact.php.

Se ejecutaron las herramientas Wfuzz y Nikto en busca de más información y rutas relevantes en la Web.

  • Wfuzz:

Ilustración 16: Ejecución de Wfuzz.

  • Nikto:

Ilustración 17: Ejecución de Nikto.

El fichero db.php encontrado resultó ser un rabbit hole. También se identificó otro panel de login, exclusivamente para el administrador de la web.

Ilustración 18: Admin Panel en http://10.10.10.176/admin/index.php.

Un usuario sin privilegios en la web podía subir ficheros, pero no tenía acceso a ellos, solo se podían descargar, así que todo apuntaba que para realizar la intrusión al sistema primero se debía conseguir acceso como usuario administrador de la web.

En el formulario de registro de usuarios, se podía observar lo siguiente:

Ilustración 19: El campo nombre no debe tener más de 10 caracteres.

Ilustración 20: Código JavaScript que valida los campos name y email.

Los mensajes encontrados, fueron pistas para realizar un SQL Truncation Attack. Es decir, un usuario sin privilegios podría conseguir acceso como usuario administrador sin necesidad de conocer su contraseña.

Si el servicio MySQL está ejecutándose con la configuración por defecto, el usuario administrador es admin y la columna de la base de datos donde se almacena el nombre está limitada a 20 caracteres. Por defecto, MySQL truncará cadenas más largas que el ancho máximo de columna definido y solo emitirá una advertencia. Pero esas advertencias generalmente solo se ven en el back-end de la aplicación.

MySQL no compara cadenas en modo binario. Por defecto, se utilizan reglas de comparación más relajadas, una de estas relajaciones es que los caracteres de espacio final se ignoran durante la comparación. Esto significa que la cadena 'admin' sigue siendo igual a la cadena 'admin ' en la base de datos. Por tanto, si el atacante proporciona 'admin p' y la aplicación busca en la base de datos a este usuario, y no puede encontrarlo porque el nombre está limitado a 20 caracteres y el atacante proporcionó 21, la aplicación aceptará el nuevo nombre de usuario y lo insertará en la base de datos. Debido a la longitud de la columna de 20 caracteres, la aplicación truncará el nombre de usuario y lo insertará como 'admin'. Ahora la tabla contiene dos usuarios administradores, 'admin' y 'admin'.

El campo email, es el que está limitado a 20 caracteres, ergo es el que determina si una cuenta es administradora o no. Se procedió a capturar la petición con BurpSuite:

Ilustración 22: Petición modificada con 21 caracteres añadidos en el campo email.

Una vez enviada la petición modificada, ya se podía acceder como admin introduciendo en http://10.10.10.176/admin/index.php el correo electrónico del usuario administrador de la web y la contraseña que se había enviado en la petición.

Ilustración 23: Página inicial del panel del usuario administrador.

En http://10.10.10.176/admin/users.php se podía visualizar los usuarios registrados en la web. En http://10.10.10.176/admin/collections.phpera posible descargar dos PDF, uno con los usuarios registrados y otro con las colecciones de libros que había en la web, donde se incluían los que los usuarios podían subir.

Ilustración 24: Lista de usuarios en http://10.10.10.176/admin/users.php.

Ilustración 25: Descarga de PDFs en http://10.10.10.176/admin/collections.php.

Ilustración 26: PDF con los usuarios registrados en la web.

Ilustración 27: PDF con la colección de libros que existe en la web.

En el PDF que muestra la colección de libros existentes, se podía observar cómo se introduce en el campo "Title" y "Author" exactamente lo que el usuario pone en el formulario de http://10.10.10.176/collections.php, para proceder a la subida del fichero.

Así que se pensó que quizás la clave estaría en realizar algún tipo de inyección que fuese interpretada por el servidor. Se comenzó probando un XSS para ver como quedaba el PDF resultante.

Ilustración 28: Intento de inyección XSS.

Ilustración 29: Resultado de la inyección de XSS.

Las etiquetas HTML que encapsulan el código JavaScript eran interpretadas. Se decidió realizar un XXE, para poder leer un fichero de la máquina víctima.

Ilustración 30: Inyección de código XML para realizar un XXE.

Ilustración 31: Resultado del intento de XXE.

El código XML inyectado parecía que también había sido interpretado, pero no mostraba ningún resultado. Esto se debía a que el código se ejecutaba en el servidor, pero los resultados no se mostraban en el documento.

Por tanto, se usó la función document.write de JavaScript, para comprobar dicha teoría.

Ilustración 32: Haciendo uso de document.write en JavaScript.

Ilustración 33: Resultado de la inyección de código en JavaScript.

El PDF resultante mostraba la ruta de windows.location, por tanto, la inyección había funcionado. Habitualmente los XSS se ejecutan en el lado del cliente, es decir, en el navegador que usa el usuario para visitar la web, pero en este caso se había identificado un XSS en el lado del servidor, dado que el código se interpretaba y ejecutaba en la generación del documento PDF.

La dificultad se encontraba en leer un fichero del sistema desde JavaScript, para posteriormente usar la función document.write y visualizar el contenido. Para ello se usaron las siguientes fuentes:

Se generó el siguiente código JavaScript:

Ilustración 34: Código JavaScript que lee un fichero en local.

Se intentó leer el contenido del fichero /etc/passwd:

Ilustración 35: Petición POST con código JavaScript para leer el fichero /etc/passwd.

Ilustración 36: Obtención del fichero /etc/passwd en PDF.

En el fichero /etc/passwd se podía apreciar como existía un usuario denominado reader, dado que el servicio SSH estaba habilitado, se buscó una clave RSA en el directorio /home/reader/.ssh/.

Ilustración 37: Petición POST con código JavaScript para leer el fichero /home/reader/.ssh/id_rsa.

Ilustración 38: PDF obtenido con la clave RSA.

La clave no se podía visualizar correctamente, debido a que el PDF no la mostraba completamente, así que era necesario extraer el texto del fichero. Se encontraron diferentes métodos en el siguiente enlace:

  • https://stackoverflow.com/questions/34837707/how-to-extract-text-from-a-pdf-file

Ilustración 39: Programa en Python utilizado para extraer el texto del PDF.

Se ejecutó un pequeño script en Python que extraía el texto del PDF y se obtuvo la clave RSA, posteriormente era necesario usar un editor de texto para eliminar las tabulaciones, que aparecían en las frases que indican el comienzo y final de la clave, sustituyéndolas por espacios, finalizado el proceso se podía usar la clave.

Ilustración 40: Clave RSA obtenida en texto con tabulaciones en las frases de inicio y final de la clave.

Ilustración 41: Iniciando sesión como usuario reader mediante SSH.

Se obtuvo acceso al sistema como usuario reader mediante SSH y se consiguió la flag user.txt. Se analizó el estado de la base de datos para entender la vulnerabilidad SQL Truncation Attack.

En el fichero db.php se encontraban las credenciales de acceso a la base de datos del usuario admin.

Ilustración 42: Credenciales del usuario admin.

Ilustración 43: Mostrando las diferentes tablas de la base de datos book.

Se pueden observar los diferentes usuarios que fueron insertados en la base de datos, entre ellos, el usuario mrtux_poc con el correo electrónico admin@book.htb y la contraseña pocpoc.

Ilustración 44: Usuario admin original.

Ilustración 45: Usuario mrtux_poc con el correo del administrador.

En el fichero index.php se puede apreciar la sentencia SQL que se ejecuta para realizar la validación del usuario y su contraseña.

Ilustración 46: Sentencia SQL en index.php.

Ilustración 47: Resultado de ejecutar la sentencia SQL de index.php.

Para comenzar a realizar la escalada de privilegios se hizo un breve reconocimiento del contenido del directorio del usuario reader. Se identificó un directorio /home/reader/backups/ donde se almacenaban los logs de acceso. Además, había un script llamado lse.sh que permitía realizar una enumeración del sistema.

  • https://github.com/diego-treitos/linux-smart-enumeration

Ilustración 48: Contenido de directorio /home/reader/.

Ilustración 49: Resultados de la ejecución del script lse.sh parte 1.

Ilustración 50: Resultados de la ejecución del script lse.sh parte 2.

Ilustración 51: Contenido del fichero access.log.

Todo apuntada a que había un proceso que se ejecutaba automáticamente, y posiblemente fuese el que escribiera o leyera de los ficheros que se encontraban en el directorio /home/reader/backups/. Se analizaron los procesos que se estaban ejecutando como usuario administrador en el sistema, donde se identificaron algunos scripts lanzados desde el directorio /root/.

Ilustración 52: Procesos que se están ejecutando como root parte 1.

Ilustración 53: Procesos que se están ejecutando como root parte 2.

Dado que parecía que la clave estaba en conocer el proceso vulnerable que se estaba ejecutando, se usó pspy64 para obtener más detalles:

Ilustración 54: Descarga de pspy64.

Ilustración 55: Ejecución de logrotate.

Ilustración 56: Versión y fichero de configuración de logrotate.

Se identificó el demonio logrotate y su versión, su finalidad es permitir rotar, comprimir y renovar los ficheros de log de forma automatizada para no saturar el sistema.

Existe un exploit que permite la escalada de privilegios explotando una condición de carrera. Se deben cumplir las siguientes condiciones:

  • Que logrotate se ejecute como root.
  • Que el usuario que ejecute el exploit tenga permisos de escritura en la ruta donde se almacenan los logs.
  • Y que la opción de crear ficheros esté habilitada en el fichero de configuración de logrotate.

Para realizar la escalada de privilegios se siguieron los pasos que se indicaban en:

Ilustración 57: Descarga y compilación del exploit.

Ilustración 58: Creación y ejecución del payload.

Ilustración 59: Inserción de datos en el log para proceder a su rotación a través de logrotate.

Ilustración 60: Shell como root y flag root.txt.

La ejecución del payload no siempre funcionaba y se realizaron varios intentos hasta que finalmente se logró.

Como conclusión se podría decir que es de las mejores máquinas, con entorno Linux, de Hack The Box que he realizado, donde se han adquirido múltiples conocimientos en la intrusión y es bastante realista.