12 KiB
Seguridad de ImageMagick
Durante nuestras auditorías, a veces nos encontramos con archivos de configuración de políticas de seguridad (policy.xml
) de ImageMagick, útiles para limitar el comportamiento predeterminado y los recursos consumidos por la biblioteca. En la práctica, estos archivos a menudo contienen una gran cantidad de recomendaciones recopiladas de diversas fuentes en Internet. Esto suele suceder por dos razones:
- Sus opciones solo se describen de manera general en la página de documentación en línea de la biblioteca, sin una clara descomposición de lo que regula cada directiva de seguridad permitida por la política. Si bien la complejidad arquitectónica y la granularidad de las opciones definibles por la política son los principales obstáculos para un novato, la base de conocimientos correspondiente podría ser más acogedora. Por defecto, ImageMagick viene con una política no restringida que debe ajustarse por los desarrolladores según su uso. Según la documentación, "esto proporciona la máxima utilidad para las instalaciones de ImageMagick que se ejecutan en un entorno aislado, quizás en una instancia de Docker, o detrás de un firewall donde los riesgos de seguridad se reducen en gran medida en comparación con un sitio web público". También se proporciona una política estricta y segura, sin embargo, como se señaló en el pasado, no siempre está bien configurada.
- ImageMagick admite más de 100 formatos de archivo principales (sin incluir subformatos) de tipos de formatos de imagen. Las infames vulnerabilidades que afectan a la biblioteca a lo largo de los años han producido una serie de correcciones de seguridad urgentes y soluciones alternativas que implican la adición de elementos de política que excluyen los formatos y características afectados (ImageTragick en 2016, RCE de @taviso a través de GhostScript en 2018, inyección de shell de @insertScript a través de la contraseña de PDF en 2020, de @alexisdanizan en 2021).
Hacia políticas más seguras
Con esto en mente, decidimos estudiar los efectos de todas las opciones aceptadas por el analizador de políticas de seguridad de ImageMagick y escribir una herramienta para ayudar tanto a los desarrolladores como a los equipos de seguridad a diseñar y auditar estos archivos. Debido al número de opciones disponibles y la necesidad de denegar explícitamente todas las configuraciones inseguras, esto suele ser una tarea manual, que puede no identificar subrepticios bypasses que socavan la fuerza de una política. También es fácil establecer políticas que parecen funcionar, pero que no ofrecen ningún beneficio real de seguridad. Las comprobaciones de la herramienta se basan en nuestra investigación destinada a ayudar a los desarrolladores a endurecer sus políticas y mejorar la seguridad de sus aplicaciones, para asegurarse de que las políticas proporcionen un beneficio de seguridad significativo y no puedan ser subvertidas por atacantes.
La herramienta se puede encontrar en imagemagick-secevaluator.doyensec.com/.
Enfoque de lista blanca vs lista negra
Se pueden encontrar en línea una serie de políticas aparentemente seguras, que especifican una lista de codificadores inseguros similares a:
...
<policy domain="coder" rights="none" pattern="EPHEMERAL" />
<policy domain="coder" rights="none" pattern="EPI" />
<policy domain="coder" rights="none" pattern="EPS" />
<policy domain="coder" rights="none" pattern="MSL" />
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="coder" rights="none" pattern="PDF" />
<policy domain="coder" rights="none" pattern="PLT" />
<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="PS2" />
<policy domain="coder" rights="none" pattern="PS3" />
<policy domain="coder" rights="none" pattern="SHOW" />
<policy domain="coder" rights="none" pattern="TEXT" />
<policy domain="coder" rights="none" pattern="WIN" />
<policy domain="coder" rights="none" pattern="XPS" />
...
En ImageMagick 6.9.7-7, se realizó un cambio no listado. El analizador de políticas cambió su comportamiento, pasando de no permitir el uso de un codificador si había al menos una regla de permiso none
en la política, a respetar la última regla coincidente en la política para el codificador. Esto significa que es posible adoptar un enfoque de lista de permitidos en las políticas modernas, denegando primero todos los derechos de los codificadores y habilitando solo los aprobados. Una política más segura especificaría:
...
<policy domain="delegate" rights="none" pattern="*" />
<policy domain="coder" rights="none" pattern="*" />
<policy domain="coder" rights="read | write" pattern="{GIF,JPEG,PNG,WEBP}" />
...
Sensibilidad a mayúsculas y minúsculas
Considere la siguiente directiva:
...
<policy domain="coder" rights="none" pattern="ephemeral,epi,eps,msl,mvg,pdf,plt,ps,ps2,ps3,show,text,win,xps" />
...
Con esto, las conversiones seguirán siendo permitidas, ya que los patrones de política distinguen entre mayúsculas y minúsculas. Los codificadores y módulos siempre deben estar en mayúsculas en la política (por ejemplo, "EPS" en lugar de "eps").
Límites de recursos
La denegación de servicio en ImageMagick es bastante fácil de lograr. Para obtener un conjunto fresco de payloads, es conveniente buscar “oom” u otras palabras clave similares en los problemas recientemente abiertos reportados en el repositorio Github de la biblioteca. Esto es un problema ya que una instancia de ImageMagick que acepta entradas potencialmente maliciosas (que a menudo es el caso) siempre estará propensa a ser explotada. Debido a esto, la herramienta también informa si no se establecen límites razonables explícitamente en la política.
Fragmentación de políticas
Una vez que se define una política, es importante asegurarse de que el archivo de política esté teniendo efecto. Los paquetes de ImageMagick incluidos en la distribución o instalados como dependencias a través de múltiples gestores de paquetes pueden especificar diferentes políticas que interfieren entre sí. Una búsqueda rápida con find
en su máquina local identificará múltiples ocurrencias de archivos policy.xml
:
$ find / -iname policy.xml
# Example output on macOS
/usr/local/etc/ImageMagick-7/policy.xml
/usr/local/Cellar/imagemagick@6/6.9.12-60/etc/ImageMagick-6/policy.xml
/usr/local/Cellar/imagemagick@6/6.9.12-60/share/doc/ImageMagick-6/www/source/policy.xml
/usr/local/Cellar/imagemagick/7.1.0-45/etc/ImageMagick-7/policy.xml
/usr/local/Cellar/imagemagick/7.1.0-45/share/doc/ImageMagick-7/www/source/policy.xml
# Example output on Ubuntu
/usr/local/etc/ImageMagick-7/policy.xml
/usr/local/share/doc/ImageMagick-7/www/source/policy.xml
/opt/ImageMagick-7.0.11-5/config/policy.xml
/opt/ImageMagick-7.0.11-5/www/source/policy.xml
Las políticas también se pueden configurar utilizando el argumento CLI -limit, los métodos de la API MagickCore o con variables de entorno.
Una política restrictiva inicial
A partir de la política más restrictiva descrita en la documentación oficial, diseñamos una política restrictiva que recopila todas nuestras observaciones:
<policymap xmlns="">
<policy domain="resource" name="temporary-path" value="/mnt/magick-conversions-with-restrictive-permissions"/> <!-- the location should only be accessible to the low-privileged user running ImageMagick -->
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="list-length" value="32"/>
<policy domain="resource" name="width" value="8KP"/>
<policy domain="resource" name="height" value="8KP"/>
<policy domain="resource" name="map" value="512MiB"/>
<policy domain="resource" name="area" value="16KP"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="resource" name="file" value="768"/>
<policy domain="resource" name="thread" value="2"/>
<policy domain="resource" name="time" value="10"/>
<policy domain="module" rights="none" pattern="*" />
<policy domain="delegate" rights="none" pattern="*" />
<policy domain="coder" rights="none" pattern="*" />
<policy domain="coder" rights="write" pattern="{PNG,JPG,JPEG}" /> <!-- your restricted set of acceptable formats, set your rights needs -->
<policy domain="filter" rights="none" pattern="*" />
<policy domain="path" rights="none" pattern="@*"/>
<policy domain="cache" name="memory-map" value="anonymous"/>
<policy domain="cache" name="synchronize" value="true"/>
<!-- <policy domain="cache" name="shared-secret" value="my-secret-passphrase" stealth="True"/> Only needed for distributed pixel cache spanning multiple servers -->
<policy domain="system" name="shred" value="2"/>
<policy domain="system" name="max-memory-request" value="256MiB"/>
<policy domain="resource" name="throttle" value="1"/> <!-- Periodically yield the CPU for at least the time specified in ms -->
<policy xmlns="" domain="system" name="precision" value="6"/>
</policymap>
Puedes verificar que una política de seguridad está activa usando el comando identify
:
identify -list policy
Path: ImageMagick/policy.xml
...
También puedes jugar con la política anterior usando nuestra herramienta de evaluación mientras desarrollas una personalizada.
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.