La última charla en la quinceava edición de Ekoparty estuvo a cargo de Ryan Speers, quien presentó 20 devices in 45 seconds: Automated Bug Hunting in IoT Devices: una introspección hacia la utilización del análisis automático para la rápida identificación de fallas de seguridad en el firmware de dispositivos IoT. Tanto él como su compañera de investigación, Sophia d’Antoine –quien desafortunadamente no pudo asistir al evento–, son investigadores de Pilot Security.
Esta charla sobre automatización del descubrimiento de bugs en firmware embebido no puede ser más apropiada en un contexto donde se prevé que unos 15 mil millones de nuevos equipos se unirán a Internet para el 2022, año en el que además se estima que habrá unas 1.8 millones de posiciones de ciberseguridad vacantes en el mercado laboral.
Aproximaciones al análisis de equipos IoT
El primer paso al momento de intentar identificar fallos de seguridad en IoT es definir cuál es la superficie de ataque de estos equipos. Lo cierto es que las vulnerabilidades pueden aparecer por diversos factores: el backend (servidores y componentes de control central y registro de datos), el firmware (es decir, el software, librerías y código en general que controla las operaciones del dispositivo) o el hardware (circuitos, armazón, y otras partes físicas).
¿Cuáles son los métodos que usualmente se utilizan para analizar equipos IoT en la actualidad? Pues bien, existen diferentes enfoques que sirven a los investigadores con este propósito. El primero consiste en encarar el análisis como si fuese un pentesting de redes. Aunque intuitiva y fácil de implementar, esta aproximación podría boicotearse ante redes inestables, imposibilidad de alcanzar los servicios de interés, protocolos personalizados, o el hecho de que pasa por alto una enorme cantidad de información sobre el sistema referida a componentes físicos y otros vectores de ataque.
El segundo esquema es el análisis manual del firmware. En este sentido, aunque existen herramientas de código abierto como binwalk muy útiles para hallar claves hardcodeadas, archivos de configuración, binarios y librearías desactualizadas o de interés para descompilar, lo cierto es que existen numerosas limitaciones que pueden rápidamente incrementar la complejidad y duración del análisis hasta el descubrimiento exitoso de fallos de seguridad.
Otra técnica es la examinación física del dispositivo mediante herramientas libres para, por ejemplo, encontrar y acceder a JTAG (e.g. JTAGenum, JTAGulator, GoodFET), descargar memorias SPI flash (e.g. GoodFET), o interactuar con RF (e.g. ApiMote, Ubertooth One, YARD Stick One). Sin embargo, esto implica la necesidad de tener el dispositivo físico, y aun así muchas herramientas se quedan cortas cuando se las exige fuera de determinados casos de uso.
Introducción al análisis automático de firmware
La automatización en el marco de una auditoría de software incluye múltiples ventajas. Los seres humanos no somos perfectos y el auditor bien podría estar pasando por alto algún bug, quizás en la medida que algunos puntos de interés o caminos de análisis son priorizados ante otros por cuestiones de tiempo o de la subjetividad asociada al analista. Por el contrario, la automatización aplica los controles de la misma manera a cada potencial fallo y cada vez que se ejecuta, siendo la meta lograr codificar el conocimiento del experto en un algoritmo eficiente.
La (¿buena?) noticia es que el firmware suele tener mayormente vulnerabilidades triviales que ya conocemos muy bien: overflows de memoria, falta de protecciones como ASLR, DEP o stack cookies, tamaños de buffer constantes, falta de chequeo de variables fuera de rango, funciones en C vulnerables, entradas no sanitizadas, etcétera. Todos estos bugs frecuentes además pueden simplificarse en operaciones de lectura y escritura, por lo que el primer paso hacia la automatización de su detección sería deconstruir esos bugs en sus respectivas primitivas.
Lo anterior permitiría saltar algunos problemas usuales en el análisis de código fuente. Si bien este puede ser bueno para encontrar bugs asociados a la lógica del programa o inyecciones de código, puede mostrar limitaciones al momento de detectar problemas introducidos por librerías externas o por optimizadores de código al momento de compilación. Además, el análisis de código fuente suele arrojar muchos falsos positivos debido a código muerto.
Una vez que se han desmembrado los bugs comunes en sus primitivas, llega el problema de la aplicación a gran escala. Dentro de las técnicas que pueden utilizarse para ello se encuentran el análisis estático, la emulación y el fuzzing, utilizando algoritmos SAT e integrando el análisis dentro del ciclo de desarrollo del firmware. Esto último es sumamente importante acorde a Speers ya que, aún si se tuviese una cantidad suficiente de auditores para hacer el proceso de forma manual, la automatización permite hallar bugs con mayor rapidez, lo que a su vez permite solucionar esos errores con anterioridad en el ciclo de desarrollo del producto y no inmediatamente antes de su liberación al mercado.
Cabe destacar que estas técnicas tradicionales de análisis exigen de un esfuerzo extra para ser implementadas sobre firmware embebido en equipos IoT, debido a que las herramientas existentes están pensadas para arquitecturas tradicionales. Tras explicar los obstáculos que debieron sobrepasar, Speers demostró un conjunto de vulnerabilidades que logró encontrar sobre una veintena de dispositivos previamente escaneados a su alrededor, aplicando las técnicas mencionadas a lo largo de la charla en un entorno personalizado de análisis.
El título de esta ponencia no es ninguna casualidad: hace clara referencia a la charla Hack All The Things: 20 Devices in 45 Minutes que pudimos observar hace algunos años en DEFCON 22. Por otra parte, otros recursos muy interesantes que se mencionaron durante la charla en lo que a automatización refiere fueron:
- The Spirit of the 90s is Alive in Brooklyn
- Automation Techniques in C++ Reverse Engineering
- Automatic Generation of Control Flow Hijacking Exploits for Software Vulnerabilities
- Automatic Exploit Generation
- Be a Binary Rockstar
Como bien resaltó el orador, la creación de entorno de auditoría de firmware es clave si consideramos la enorme cantidad de equipos IoT que poco a poco se cuelan en nuestras vidas. Además de servir a propósitos de bug bounties, la rápida identificación de bugs y la retroalimentación constante con el equipo de desarrollo podría ser vital para reducir la cantidad de productos inseguros que se liberan a los mercados globales y así asegurar a los usuarios finales.