
Un write-up sobre la máquina Steel Mountain de TryHackMe.com y el exploit para CVE-2014-6287
Un análisis de la máquina Steel Mountain de TryHackMe.com y el exploit para CVE-2014-6287
No me atribuyo el mérito del descubrimiento y la explotación originales de esta vulnerabilidad. ¡Gracias a las siguientes personas!
Descubrimiento:
Daniele Linguaglossa
Autor del módulo de Metasploit:
Muhamad Fadzil Ramli
Sala y autor de TryHackMe:
https://tryhackme.com/room/steelmountain
https://tryhackme.com/p/tryhackme
Referencias:
https://nvd.nist.gov/vuln/detail/CVE-2014-6287
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/http/rejetto_hfs_exec.rb
https://subscription.packtpub.com/book/networking_and_servers/9781786463166/1/ch01lvl1sec20/vulnerability-analysis-of-hfs-2-3
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6287
https://www.tutorialspoint.com/pascal/pascal_functions.htm
No soy, ni mucho menos, un profesional de la seguridad con experiencia. Esto significa que puedo proporcionar información incorrecta. Si eres un profesional con experiencia/investigador experimentado y ves algo incorrecto, por favor infórmamelo para poder volver, estudiar lo que hice mal y proporcionar la información correcta. Esto es beneficioso tanto para mí como para otros investigadores novatos que puedan tropezar con este análisis. Si encuentras información errónea que haya escrito, por favor contáctame en [email protected] para poder corregirla. ¡Gracias!
Rejetto file server (también conocido como HFS) es un programa para compartir archivos que se utiliza para publicar y compartir archivos a través de una red. En la versión 2.3, existía una vulnerabilidad que permitía a un atacante ejecutar comandos del sistema introduciendo un byte nulo en el parámetro de búsqueda, tal como se describe en CVE-2014-6287. El código no procesa correctamente un byte nulo con su configuración de regex (expresión regular) y, por lo tanto, conduce a una vulnerabilidad de ejecución remota de código.
La vulnerabilidad se puede encontrar en la función findMacroMarker, que se origina en el archivo parserLib.pas. .pas es la extensión de archivo para el lenguaje de programación Pascal. Al momento de escribir esto, no he programado nada en Pascal. ¡Echemos un vistazo al fragmento de código y analicemos lo que hace!
function findMacroMarker(s:string; ofs:integer=1):integer;
begin result:=reMatch(s, '{[.:]|[.:]}||', 'm!', ofs) end;
La primera línea de código es una declaración de una función llamada findMacroMarker que toma dos parámetros. En Pascal, el tipo de datos de los parámetros debe declararse, por lo tanto s:string significaría que la variable s es un string. Esto también es el caso de la variable ofs con un tipo de datos integer. A la derecha de los parámetros, vemos un carácter de dos puntos seguido de integer. Esto se conoce como el tipo de la función. El punto y coma marca el final de esa línea de código. La primera palabra en la siguiente línea de código es begin. Esto le dice al compilador dónde comienza la función. Continuando, vemos una variable llamada result seguida del operador de asignación :=. La variable result se asigna a la función reMatch. No pude encontrar nada sobre reMatch en Internet, así que supongo que es una función personalizada escrita en otro lugar de HFS. Por suerte para nosotros, la función se explica por sí misma. es claramente una abreviatura de coincidencia de expresión regular (regular expression match) seguida del patrón regex que está buscando, lo cual se tiene en cuenta en el parámetro de la función , así como en los parámetros variables iniciales definidos en la primera línea de código. Al final de la segunda línea, la palabra se usa para definir el final de la función para el compilador.
La vulnerabilidad se encuentra en el patrón regex, como se describió anteriormente en la función reMatch. La regex no maneja correctamente un byte nulo %00. Cuando pasamos un comando del sistema con un byte nulo antepuesto, la función encontrará el fallo y ejecutará el comando en la máquina host. Para explotar esta vulnerabilidad, todo lo que tenemos que hacer es pasar el byte nulo en el parámetro de búsqueda de una petición GET seguido de {.exec|code.} (siendo code el comando que quieras ejecutar) a través de la URL de esta manera:
http://(IP-Address/DomainName)/?search==%00{.exec|CommandGoesHere.}.
Comencemos con un escaneo de puertos mediante rustscan. Prefiero rustscan para obtener una vista rápida de la superficie de ataque.

Tenemos una gran cantidad de puertos abiertos aquí. Ahora vamos a profundizar con nmap y averiguar qué servicios están escuchando en esta variedad de puertos para encontrar nuestro servicio explotable.

Tenemos un servicio llamado Microsoft Windows RPC ejecutándose en los puertos altos. RPC es una llamada a procedimiento remoto (remote procedure call). Esto permite que los procesos de Windows se comuniquen a través de una red o internamente dentro de la propia computadora. Continuando, tenemos algunos servidores web diferentes ejecutándose en los puertos 80 y 8080. En los puertos 5985 y 47001, está presente Microsoft Httpapi Httpd, que permite que las aplicaciones se comuniquen a través de HTTP sin necesidad de Microsoft IIS (Internet Information Server). Nmap detecta un servidor web potencialmente ejecutándose en el puerto 3389; sin embargo, no pude conectarme a través de HTTP o SSL. Conectémonos al servidor web en el puerto 80, ya que es el puerto estándar para el protocolo HTTP.

En el puerto 80, se nos presenta una página web que muestra el logotipo de la empresa Steel Mountain y una foto etiquetada como empleado del mes. Si abrimos las herramientas de desarrollo web, podemos ver que la foto está etiquetada como BillHarper.png, lo que nos da la respuesta a nuestra primera pregunta. Conectémonos a los otros servicios en escucha y veamos qué podemos encontrar.

Cuando nos conectamos al servicio en el puerto 5985, obtenemos el código de error HTTP 404. El código de error 404 significa que el servidor no puede encontrar el recurso solicitado. No hay nada de interés aquí. Pasemos al siguiente.

¡SÍ! Ahora esto parece interesante. En el puerto 8080, tenemos algún tipo de servicio para compartir archivos. Miremos a nuestro alrededor y veamos si podemos encontrar más información sobre este servicio. Si miramos en la esquina inferior izquierda, podemos ver un nombre y lo que parece ser un número de versión como este: HttpFileServer 2.3. Sigamos enumerando.

Si hacemos clic en el enlace etiquetado como HttpFileServer 2.3, seremos dirigidos a una página web con el nombre del software que se ejecuta en el puerto 8080. En este caso, tenemos Rejetto HFS HTTP File Server. Revisemos el otro puerto, el 47001, para cubrir todos los frentes. Si no encontramos nada útil, podemos volver a Rejetto y comenzar a buscar CVEs conocidos.

Parece que tenemos otro 404 en el puerto 47001. Comencemos a buscar CVEs para Rejetto HFS 2.3.

Una búsqueda rápida revela que tenemos una lista de CVEs conocidos para HFS 2.3. Nos vamos a apartar de la guía de THM y nos mantendremos alejados del Metasploit habitual. He programado un exploit que nos dará una shell. Para usarlo, necesitas ir a revshells.com, ingresar la información de red adecuada y seleccionar PowerShell #3 (Base 64). Cuando tengas el payload, cópialo y pégalo en la variable payload en la línea 13 y ejecuta el exploit. Se abrirá un listener automáticamente y deberías tener acceso al sistema. Nota: Es posible que necesites ejecutar el exploit varias veces para capturar la shell.

¡Boom! Estamos dentro del sistema y, como bonus, tenemos una shell de PowerShell. Esto significa que tendremos acceso a los cmdlets de .NET. Podemos ser mucho más peligrosos con esto que con la shell estándar del símbolo del sistema. Pasemos a la escalada de privilegios. La guía de THM nos proporciona una herramienta útil llamada PowerSploit, que tiene una herramienta para enumerar la máquina en busca de posibles vectores de escalada de privilegios. Vamos a colocar PowerUp.ps1 en la máquina y usarlo para ayudarnos a obtener el control de la máquina.

Primero, iniciamos un simple servidor HTTP en el directorio que contiene nuestro archivo PowerUp.ps1 en nuestro sistema. Luego, en nuestro sistema objetivo, usamos el cmdlet Invoke-Webrequest para descargar el archivo desde nuestro servidor a la máquina objetivo. Ahora instalaremos y ejecutaremos uno de los cmdlets que vienen con PowerUp.

Para instalar PowerUp.ps1, ejecuta este comando: . .\PowerUp.ps1. A continuación, necesitaremos usar nuestro nuevo cmdlet Invoke-AllChecks. Después de ejecutarlo, se nos presenta una gran cantidad de resultados. Lo he reducido al importante, el que queremos. Podemos ver que PowerUp nos ha indicado que tenemos permisos para modificar el archivo. Revisemos los servicios en ejecución para poder detenerlo si está corriendo. Necesitamos hacer esto porque no podemos hacer nada con el archivo si un servicio lo está usando.

Al usar el cmdlet Get-Service, se nos presenta una lista de los servicios presentes en la máquina. Dado que nuestro servicio objetivo se está ejecutando, tendremos que detenerlo para poder modificar y sobrescribir el binario.

Para detener el servicio, usamos el cmdlet Stop-Service seguido del nombre del servicio. Ahora debemos verificar dos veces que el servicio se haya detenido con el cmdlet Get-Service. Como se muestra arriba, podemos confirmar que el servicio se ha detenido. Entremos en el directorio que contiene nuestro binario objetivo. El directorio es C:\Program Files (x86)\IObit\Advanced SystemCare.

Toma nota del tamaño del archivo del binario, que está a la izquierda del nombre del binario en la columna más a la derecha.

Crea un payload de meterpreter y súbelo con el módulo de servidor web de Python, como hicimos antes.

Inicia un listener de meterpreter usando la misma información de red que usaste para crear el payload.

Usa el cmdlet Invoke-Webrequest para descargar nuestro payload de meterpreter al sistema objetivo desde nuestra máquina. Asegúrate de nombrarlo ASCService.exe para que podamos explotar los permisos de archivo débiles y sobrescribir el binario normal con nuestro binario malicioso.

Confirma que el binario ha sido sobrescrito listando el directorio y verificando si el tamaño del archivo ha cambiado. En este caso, ha cambiado de un número de 6 dígitos a un número de 5 dígitos, lo que confirma que hemos subido con éxito nuestro binario malicioso.

Cuando el binario malicioso haya reemplazado al normal, todo lo que tenemos que hacer es reiniciar el servicio con el cmdlet Start-Service. Cuando hagamos eso, la máquina ejecutará nuestro payload y nos dará una shell de meterpreter. Podemos ejecutar getuid en meterpreter para verificar si tenemos NT AUTHORITY/SYSTEM. Cuando ejecutamos getuid, de hecho podemos ver que hemos comprometido esta máquina. ¡Qué tengas un excelente día!
reMatchreMatchend