jueves, marzo 19, 2020

XRayCode: Radiografiando el código fuente de aplicaciones con mapas de calor para buscar vulnerabilidades

El análisis de código fuente en busca de vulnerabilidades es una práctica habitual dentro de la seguridad informática. Y en concreto, las técnicas de Análisis de Código Estático son posiblemente las más extendidas, ya que nos permite buscar y localizar vulnerabilidades sin la necesidad de ejecutar la aplicación. De esto hemos hablado mucho por aquí. El trabajo que publicamos de Taint Analysis, y que hicimos para aplicar en profundidad a la búsqueda y detección de bugs en plugins de WordPress, con los que alimentamos nuestro proyecto de Faast for WordPress, y que dieron varios CVE como consecuencia.

Figura 1: XRayCode: Radiografiando el código fuente de aplicaciones
con mapas de calor para buscar vulnerabilidades

Para este tipo de análisis de código estático existen multitud de herramientas Open Source enfocadas a diferentes sistemas operativos (como  en el popular Python tan usado por los pentesters y researchers, Ruby, Lenguaje C, etcetera) las cuales nos permiten automatizar este proceso de análisis. La interpretación de los reportes generados por dichas aplicaciones es fundamental a la hora de detectar posibles amenazas de seguridad en nuestro código fuente. El problema aparece cuando la cantidad de ficheros a analizar es muy elevada o no se interpretan correctamente las vulnerabilidades, ya sea por desconocimiento o por una incorrecta interpretación de los resultados.

Figura 2: Libro de Docker: SecDevOps en 0xWord
escrito por Fran Ramírez, Elias Grande y Rafael Troncoso

Por supuesto, nosotros aplicamos SecDevOps a todos los productos y sistemas que desarrollamos, y justamente para facilitar esa búsqueda de todo tipo de vulnerabilidades cuando existe una gran cantidad de ficheros, o incluso para hacer más sencillo interpretar la información, en el departamento de Ideas Locas CDCO hemos estado experimentando con una técnica adicional para este proceso de análisis: los mapas de calor.

XRayCode: Mapas de calor en  el código fuente

La idea de utilizar los mapas de calor es que, de una manera visual, sea más sencillo detectar y localizar las posibles vulnerabilidades que pudieran aparecer en nuestro programa. Para ver un ejemplo práctico de esta “Idea Loca” hemos creado una pequeña PoC llamada XRayCode. Esta se encarga de realizar dichos mapas de calor partiendo de la información generada por uno de estos analizadores, en concreto Bandit (Python).

Figura 3: XRayCode en GitHub

Las fases de desarrollo de una aplicación segura (SecDevOps) suelen ser un proceso tremendamente complicado que va acompañado, la mayoría de las veces, de una presión extrema (en este artículo ya contamos en qué consiste SecDevOps). Desde los plazos de entrega hasta los posibles errores en el código, son sólo algunos de los contratiempos que podemos encontrar dentro de este proceso.

A veces, esta presión provoca la creación de código fuente inseguro, dando prioridad a la funcionalidad. Por eso es importante detectar a tiempo, y de la manera más rápida y sencilla posible, todos los problemas de seguridad dentro del código, y de esa forma, evitar que la aplicación finalmente funcione de una manera insegura, provocando todo tipo de incidentes de seguridad.

Figura 4: Ejemplo de mapa de calor con XRayCode

Para agilizar y ayudar a esta detección hemos pensado en los mapas de calor. Un mapa de calor es una técnica de representación de la información la cual nos permite visualizar la densidad de datos localizada en un punto concreto de su estructura. La información se almacena en una matriz la cual representa a su vez diferentes tonos de colores en función de un algoritmo para representar la concentración de la información, siempre focalizada en un punto central. Dicha densidad será mayor cuanto más cerca esté del punto central y menor a medida que nos vamos alejando del mismo. Los mapas de calor que representan temperaturas son un ejemplo de uso de esta técnica.

Figura 5: Ejemplo de mapa de calor de temperaturas

La estructura de un programa o un código fuente, sobre todo su formato de líneas nos permite perfectamente aprovechar esta característica de los mapas de calor para integrarla en nuestro proyecto de visualización de este tipo de información a la hora de detectar vulnerabilidades en el código. En los siguientes apartados se explica en profundidad la técnica utilizada. La principal ventaja que nos ofrece un mapa de calor es la posibilidad de detectar, de un golpe de vista, los puntos calientes que se haya detectado durante la fase de análisis, sea cual sea su naturaleza.

De esta forma es posible descartar aquellos que no han detectado ninguna anomalía y centrarnos en aquellos que sí se ha detectado algún tipo de problema. Volviendo al proyecto presentado de mapas de calor aplicados al código fuente, podemos detectarlos simplemente pre-visualizando la imagen generada por la aplicación.

En nuestro objetivo de crear una PoC para demostrar este concepto de mapa de calor aplicado a la seguridad, y en concreto al análisis estático de código, hemos implementado una herramienta Open Source llamada XRayCode, creada en Python 3. Esta herramienta utiliza como motor principal para el análisis estático Bandit, centrada en el lenguaje Python. De todas formas, es relativamente sencillo cambiar el motor y utilizar cualquier otro que ofrezca la posibilidad exportar la información a un formato estándar como por ejemplo JSON (Bandit utiliza este formato para su exportación).

La fase de presentación de resultados también es importante, así que XRayCode incluye la generación de un PDF en el cual se detallan las diferentes vulnerabilidades detectadas con Bandit así como un pequeño gráfico con el mapa de calor. Si fuera necesario, es sencillo incluir más información por cada positivo detectado, dando más información a la detección.

Figura 6 : Fichero JSON generado por Bandit

XRayCode es una PoC sencilla escrita en Python 3 la cual pretende implementar de un modo práctico, el concepto de los mapas de calor llevados al análisis de código. Utiliza Matplotlib como librería principal para la creación de los mapas de calor además de Seaborn. La aplicación permite analizar un directorio completo en el cual existen ficheros en Python (extensión .py), descargar un fichero concreto también en Python desde una URL o directamente analizar un único fichero creado en este lenguaje de programación.

XRayCode: Ejemplos de uso

XRayCode se ejecuta desde la línea de comandos (CLI), y este ofrece varias opciones que pasamos a describir:
-h, --help muestra el mensaje de ayuda
-i I Carpeta a analizar
-o O Carpeta de salida para ubicar los mapas de calor
-l L Severidad (ALL, LOW, MEDIUM, HIGH)
-r R Nombre y ruta del reporte PDF
-s S Muestra el mapa de calor en pantalla (on/off)
Una ejecución típica, en concreto para mostrar el mapa de calor de un único fichero Python directamente desde una URL, sería la siguiente:
python3 xraycode.py -i https://website.com/file.py
               -o outputheatmap/ -l LOW -s on -r pdfreport2.pdf
Vamos a ver el significado de cada uno de los parámetros. La aplicación detecta de forma automática si es una URL o una carpeta, por lo tanto, sólo es necesario indicar la ubicación del fichero a analizar después del parámetro “-i”, en este caso una URL. El parámetro “-o” indica la ruta donde se almacenará la información generada (mapas de calor). En caso de no existir, se creará de forma automática.

Figura 7: PoC de XRayCode

El siguiente parámetro es “-l”, el cual indica qué nivel de severidad de la vulnerabilidad queremos visualizar. Bandit ofrece tres niveles de severidad, LOW, MEDIUM y HIGH. XRayCode permite visualizar sólo uno de estos tres niveles en el mapa de calor indicándolo con este parámetro, en el ejemplo, LOW. Es decir, sólo se visualizará un mapa de calor específico para las vulnerabilidades tipo “LOW” detectadas. En caso de necesitar una visualización global de los posibles puntos con vulnerabilidad en el código, entonces podemos utilizar la opción "ALL", la cual unificará todas las vulnerabilidades bajo un mismo tipo de color.

Figura 8: Paleta del mapa de calor en función de la serveridad
de la vulnerabilidad, LOW, MEDIUM y HIGH

Cada nivel de severidad tiene su propia paleta de colores a la hora de visualizarlo. El siguiente parámetro, “-s” simplemente es un flag que nos indica si XRayCode debe o no mostrar en pantalla el mapa de calor. Independientemente de estar o no activado, XRayCode siempre guarda una captura de imagen en la carpeta de salida. Vamos a ver las diferentes opciones que tenemos al utilizar este parámetro:
• “on”: Muestra el mapa de calor en pantalla. Esta visualización nos permite interactuar con el gráfico, por ejemplo, haciendo zoom de las diferentes zonas que nos interese ver en profundidad o ampliando su tamaño en general, permitiendo una mejor visualización de los números de líneas. Finalmente, además de visualizarlo, almacena una captura general del mapa de calor en la carpeta de salida.
• “off”: En este caso no se muestra por pantalla el mapa de calor referente al fichero analizado, en cambio sí se almacena, como ya hemos comentado antes, una captura de dicho mapa de calor. Esta opción es recomendable cuando tenemos un número elevado de ficheros a analizar y queremos agilizar el proceso de este.
Finalmente, la opción “-r” genera un informe general, separado por ficheros, en el cual se muestra una captura del mapa de calor asociado a dicho fichero, además de un listado de todas las vulnerabilidades detectadas y su descripción detallada.

Si queremos ejecutar el análisis a una carpeta concreta, de todas las vulnerabilidades (ALL) y mostrándolas en pantalla, este podría ser el comando para ejecutar:
python3 xraycode.py -i /folder -o outputheatmap/ -l ALL -s on -r pdfreport2.pdf
Una vez ya hemos ejecutado el comando correctamente con todos los parámetros, XRayCode envía a Bandit el código fuente a analizar. Este código fuente se convierte en una matriz la cual tiene como número de filas el mismo número de filas que tiene el fichero de texto .py original. De esta forma, obtenemos una dimensión correcta del gráfico a mostrar. El número de columnas, al no tener efectos en principio, se ha utilizado simplemente como factor de definición para la resolución del punto de calor a mostrar.

El código fuente a analizar (sin convertir) se envía directamente a Bandit para su análisis. En vez de implementar nuestro propio motor de análisis de código, y siendo el concepto del mapa de calor lo que realmente queremos demostrar con este proyecto, hemos optado por la solución de Bandit. Una vez se ha realizado el análisis, Bandit genera un fichero JSON el cual será procesado a continuación para generar el mapa de calor.

Figura 9: Arquitectura simplificada de XRayCode

Este fichero JSON se contrasta con la matriz generada a partir del código original para marcar las líneas las cuales contienen algún tipo de vulnerabilidad. Alrededor de estas líneas es donde se dibuja la “nube” de colores que da forma al mapa de calor. Este mapa de calor indica la densidad de errores localizada en el código fuente, usando como referencia siempre la línea de código en la cual se detectó el código. Finalmente, la información obtenida se envía a la librería que genera el informe en PDF, para de esta forma, ofrecer un informe detallado del análisis junto al mapa de calor.

Figura 10: Accediendo simplemente a la carpeta de salida con los mapas de calor
ya podemos observar qué ficheros contienen alguna anomalía o vulnerabilidad.

Como ya se ha comentado varias veces en este artículo, el objetivo de esta PoC es dar un enfoque práctico a la idea principal, usar mapas de calor en la detección de vulnerabilidades de código fuente. Creemos que este nuevo enfoque puede ofrecer una nueva herramienta/técnica que ayude a detectar de la forma más rápida y fiable posible, todo tipo de vulnerabilidades. La integración de esta visualización en el proceso SecDevOps puede ser interesante abriendo un nuevo camino centrado en la visualización para detectar anomalías en el código, facilitando la tarea de la securización del código.

Happy Hacking Hackers!

Autor: Fran Ramírez, (@cyberhadesblog) es investigador de seguridad y miembro del equipo de Ideas Locas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps", también de "Machine Learning aplicado a la Ciberseguridad” además del blog CyberHades. Puedes contactar con Fran Ramirez en MyPublicInbox.


 Contactar con Fran Ramírez en MyPublicInbox

No hay comentarios:

Entrada destacada

Cibercriminales con Inteligencia Artificial: Una charla para estudiantes en la Zaragoza

Hoy domingo toca ir a participar en un evento, con una charla y una pequeña demo. Ahora mismo sí, así que el tiempo apremia, os dejo una cha...

Entradas populares