
Ha habido artículos sobre el Habré un par de veces que plantean el tema de American Fuzzy Lop (AFL) (
1 ,
2 ). Pero en este artículo no hablaremos del AFL clásico, sino de las utilidades auxiliares y sus modificaciones, que, en nuestra opinión, pueden mejorar significativamente la calidad del fuzzing. Si está interesado en aprender cómo actualizar AFL y buscar vulnerabilidades más rápidas y más, ¡bienvenido al corte!
¿Qué es AFL y por qué es tan bueno?
AFL: fuzzer guiado por cobertura o fuzzer basado en feedback. Puede obtener más información sobre estos conceptos en un artículo tan genial como
Fuzzing: Arte, Ciencia e Ingeniería . Si resumimos la información sobre AFL, entonces podemos decir lo siguiente:
- Herramientas de un ejecutable para recopilar información de cobertura
- Muta la entrada para maximizar la cobertura.
- Repite el paso anterior para encontrar bloqueos del programa.
- En la práctica, demostrado ser muy efectivo
Gráficamente, esto se puede representar de la siguiente manera:

Si no sabe qué es AFL, para comenzar le recomendamos:
- Página oficial del proyecto
- afl-training : una breve excursión a AFL
- afl-demo - una demostración simple de cómo difuminar un programa C ++ usando AFL
- afl-cve - Colección de vulnerabilidades descubiertas usando AFL (no actualizado desde 2017)
- El hecho de que AFL se suma al programa durante su montaje se puede encontrar aquí.
- Algunos consejos útiles para aplicaciones de red fuzzing aquí
Al momento de escribir, la última versión de AFL era la versión
2.52b . Fazzer se está desarrollando activamente y, con el tiempo, algunos desarrollos de terceros se incluyen en la rama principal de AFL y se vuelven irrelevantes por sí mismos. Actualmente hay varias herramientas auxiliares útiles que se pueden identificar: se enumeran en la siguiente sección.
Rode de competencia0 díaPor separado, vale la pena mencionar la competencia mensual
Rode0day , donde hay una competencia entre fases que encontrarán vulnerabilidades más rápido y más en casos preparados previamente con acceso al código fuente y sin él. Y en general es una confrontación de varias modificaciones y bifurcaciones AFL.
Al mismo tiempo, algunos usuarios de AFL
señalan que el autor del phaser Michal Zalewski calificó una campaña para apoyar su creación, ya que los últimos cambios datan del 5 de noviembre de 2017. Esto supuestamente está asociado con su salida de Google y nuevos proyectos. En este sentido, las personas comenzaron a recolectar y hacer
parches de forma independiente
para la última versión actual 2.52b.

También hay diferentes opciones y derivados de AFL que permiten difuminar Python, Go, Rust, OCaml, GCJ Java, syscalls del kernel o incluso máquinas virtuales completas.
Herramientas auxiliares
En esta sección, hemos seleccionado varios scripts y herramientas para trabajar con AFL y los hemos dividido en varias categorías:
Procesamiento de kresh- afl-utils : un conjunto de utilidades para el procesamiento / análisis automático de accidentes y para minimizar los casos de prueba.
- afl-crash-analyzer : otro analizador de bloqueos AFL.
- fuzzer-utils : un conjunto de scripts para analizar los resultados.
- atriage es una herramienta de triaje simple.
- afl-kit : reescrito en python afl-cmin.
- AFLize es una herramienta que genera automáticamente compilaciones de paquetes de Debian amigables con AFL.
- afl-fid : un conjunto de herramientas para trabajar con datos de entrada.
Cobertura de código- afl-cov : proporciona datos de cobertura legibles por humanos.
- count-afl-calls - Puntuación de proporción. El script cuenta el número de bloques instrumentados en el binario.
- afl-sancov : como afl-cov, pero usa desinfectante clang.
- covnavi es un script de análisis y cobertura de código del Grupo Cisco Talos.
- LAF LLVM Passes es una colección de parches para afl que modifican el código para facilitar que los fuzzers pasen por las ramas
Varios scripts para minimizar los casos de prueba- afl-pytmin es un contenedor para afl-tmin que intenta acelerar el proceso de minimizar el caso de prueba mediante el uso de múltiples núcleos de CPU.
- afl-ddmin-mod : una variación de afl-tmin basada en el algoritmo ddmin.
- halfempty es una utilidad rápida basada en paralelización para minimizar los casos de prueba de Tavis Ormandy.
Para inicio distribuido- disfuzz-afl : fuzzing distribuido para afl.
- AFLDFF es un marco para la distribución difusa con AFL.
- afl-launch es una herramienta para lanzar muchas instancias afl.
- afl-motherhip : administre y lance múltiples fuzzers AFL sincronizados en la nube de AWS.
- afl-in-the-cloud es otro script para ejecutar afl en AWS.
- VU_BSc_project - Fuzz que prueba bibliotecas de código abierto con libFuzzer y AFL.
Además, recientemente se publicó un muy buen artículo sobre
“Escalar AFL a una máquina de 256 hilos” sobre este tema, que describe el lanzamiento de AFL en 256 hilos.
Despliegue, gestión, seguimiento, informes.- afl-other-arch : un conjunto de parches y scripts para agregar fácilmente soporte para varias arquitecturas (no x86) en AFL.
- afl-trivia : algunos scripts pequeños para simplificar la administración de AFL.
- afl-monitor : un script para monitorear el funcionamiento de AFL.
- afl-manager : un servidor web de Python para administrar multi-afl.
- afl-tools : imagen acoplable con afl-latest, afl-dyninst y Triforce-afl.
- afl-remote : un servidor web para la gestión remota de instancias afl.
Modificaciones AFL
AFL ha influido enormemente en la comunidad de búsqueda de vulnerabilidades y en la industria difusa en sí. Y no es sorprendente que con el tiempo, varias modificaciones inspiradas en el AFL original comenzaron a aparecer sobre la base de su idea. En esta sección los consideraremos. Cada una de estas modificaciones tiene sus ventajas y desventajas en comparación con la versión original de AFL en diferentes situaciones.
Simplemente diga que si hay problemas con la instalación o si no desea
perder tiempo, se puede encontrar casi cualquier modificación en
hub.docker.comPor qué
- Aumente la velocidad y / o la cobertura del código
- Algoritmos
- El medio ambiente
- Trabaja en condiciones sin código fuente
- Emulación de código
- Instrumentación de código
Modos AFL incorporadosAntes de proceder a la discusión de las diversas modificaciones y horquillas de AFL, es necesario hablar sobre dos modos importantes que una vez también fueron modificaciones, y que finalmente se convirtieron en modos incorporados. Este es el modo Syzygy y el modo Qemu.
Modo
Syzygy : es el modo operativo en instrument instrument.exe
instrument.exe --mode=afl --input-image=test.exe --output-image=test.instr.exe
Para este modo es necesario: reescribir estáticamente los binarios de PE32 con AFL, se requieren símbolos, requiere un desarrollo adicional para que el núcleo WinAFL sea consciente.
Modo Qemu: cómo funciona bajo QEMU se puede encontrar aquí
"Internals of AFL fuzzer - QEMU Instrumentation" . El soporte para trabajar con archivos binarios que usan QEMU apareció en el flujo ascendente AFL de la versión 1.31b. El modo Afl qemu funciona con la funcionalidad adicional de instrumentación de código binario en el motor de traducción binario qemu tcg (generador de código pequeño). Para hacer esto, afl tiene un script de compilación qemu que descarga el código fuente de una versión específica (2.10.0) de qemu, les impone varios parches pequeños y los compila para una arquitectura dada. Después de eso, se devuelve el archivo afl-qemu-trace, que en realidad es una qemu-emulación en modo de usuario (emulación de solo archivos ejecutables ELF). Gracias a esto, puede usar fuzzing con comentarios sobre binarios de elfos y para un montón de arquitecturas diferentes compatibles con qemu. Además, obtienes todas las herramientas afl geniales, comenzando con una pantalla conveniente con información sobre la sesión actual y terminando con cosas avanzadas como afl-analyse. Pero tenga en cuenta que también obtiene restricciones de qemu. Además, por ejemplo, si el archivo es compilado por una cadena de herramientas que utiliza características de hardware SoC, en el que se inicia el binario y que no es compatible con qemu, el fuzzing se interrumpirá tan pronto como se encuentre una instrucción específica o, por ejemplo, se use un MMIO específico.
También hay
una bifurcación
tan interesante del modo qemu, donde la velocidad aumentó 3x-4x veces debido a la instrumentación del código TCG y el almacenamiento en caché.
TenedoresLa apariencia de las horquillas AFL se asocia principalmente con cambios, mejoras en los algoritmos de operación de los AFL clásicos.
- afl-cygwin es un intento de portar AFL clásico a Windows utilizando Cygwin. Desafortunadamente, este intento es bastante confuso, lento, y se puede decir que el desarrollo está abandonado.
- AFLFast (extiende AFL con Power Schedules): uno de los primeros tenedores de AFL, se agregaron todo tipo de heurísticas, gracias a las cuales podría ir más lejos en un corto período.
- FairFuzz es una extensión AFL cuyo objetivo es tratar de pasar más tiempo en sucursales más raras.
- AFLGo es una extensión para AFL, que está destinada principalmente al logro específico de ciertas secciones del código, en lugar de la cobertura general del código del programa. Esto se puede usar para probar parches o secciones de código recién agregadas.
- PerfFuzz es una extensión AFL que busca casos de prueba que podrían ralentizar el programa tanto como sea posible.
- Pythia es una extensión para AFL que tiene como objetivo agregar elementos de predicción al proceso de fases con respecto a la dificultad de descubrir nuevos caminos.
- Angora es uno de los fuzzers lanzados más recientemente, escrito en óxido. Utiliza sus nuevas estrategias para la mutación y para aumentar la cobertura.
- Neuzz : un intento de fuzzing utilizando redes neuronales.
- UnTracer-AFL : integración afl con UnTracer, para un seguimiento eficiente.
- Qsym : práctico motor de ejecución concólico adaptado para fuzzing híbrido. De hecho, es un motor de ejecución de símbolos (los componentes principales se implementan como un complemento de pin de Intel), que, en combinación con afl, implementa fuzzing híbrido. Esta es una evolución adicional en el tema de fuzzing basado en comentarios y merece una discusión por separado. Su principal mérito es que puede realizar muy rápidamente (en relación con el resto) la ejecución concólica. Esto ocurre debido a la ejecución nativa de comandos sin presentación intermedia del código, eliminando el mecanismo de instantánea y una serie de heurísticas. Utiliza el pin anterior de Intel (debido a una serie de problemas de soporte entre libz3 y otros DBT), y actualmente puede trabajar con arquitecturas elf x86 y x86_64.
Vale la pena decir que hay una gran cantidad de trabajos académicos relacionados con la implementación de nuevos enfoques, técnicas de fuzzing, donde se toma y modifica AFL. Además del documento técnico, no hay nada más disponible, por lo que ni siquiera mencionamos tales implementaciones. Si estás interesado, entonces son fáciles de google. Por ejemplo, este último es
CollAFL: Path Sensitive Fuzzing ,
EnFuzz ,
Smart Greybox Fuzzing ,
ML para afl.
Modificaciones basadas en Qemu- TriforceAFL : fuzz AFL / QEMU con emulación completa del sistema . Horquilla de nccgroup. Permite difuminar todo el sistema operativo en modo qemu. Implementado a través de una instrucción especial (aflCall (0f 24)), que se agregó a la CPU QEMU x64. Desafortunadamente, ya no es compatible, la última versión de afl es 2.06b.
- TriforceLinuxSyscallFuzzer - Llamadas fuzzing del sistema Linux.
- afl-qai es un pequeño proyecto de demostración con QEMU Augmented Instrumentation (qai).
Modificación basada en KLEEkleefl : para generar casos de prueba mediante ejecución simbólica (muy lento en programas grandes).
Modificaciones basadas en Unicornioafl-unicorn : le permite
confundir fragmentos de código, emulándolo en el
Unicorn Engine . También utilizamos con éxito esta variación AFL en nuestra práctica, es decir, en las secciones de código de un RTOS, que se ejecutó en SOC, y era imposible utilizar el modo QEMU. Es aconsejable usar esta modificación cuando no hay fuentes (no puede ensamblar binarios independientes para el análisis del analizador sintáctico) y el programa no acepta datos de entrada directamente (por ejemplo, están encriptados o representan muestras de señales como en un binario CGC), entonces puede usarlo retroceda y encuentre las funciones de lugares propuestas donde estos datos se procesan en un formato conveniente para el difusor y que se pueden difuminar. Esta es la modificación AFL más común. En el sentido de que te permite literalmente difuminar todo. Es decir, no depende de la arquitectura, la disponibilidad de los códigos fuente, el formato de los datos de entrada y el formato del binario en sí (el ejemplo más llamativo es simplemente de metal, solo piezas de código de la memoria del controlador). El investigador examina preliminarmente este binario y escribe un fuzzer que emula el estado en la entrada del procedimiento del analizador, por ejemplo. Se puede ver que, a diferencia de AFL, necesita hacer algún tipo de investigación sobre el binario. Para el firmware de metal desnudo, como Wi-Fi o banda base, simplemente hay una serie de desventajas que debe tener en cuenta:
- Es necesario de alguna manera localizar las sumas de verificación.
- Debe tenerse en cuenta que el estado del fuzzer es el estado de la memoria que se almacenó en el volcado de memoria, esto puede evitar el logro de ciertas rutas para el fuzzer.
- No hay un saneamiento de los accesos a la memoria dinámica, pero se puede implementar manualmente (también con esfuerzos) y dependerá de RTOS (también debe investigarse de antemano).
- La interacción entre tareas de RTOS no se emula: también puede evitar que el fuzzer encuentre ciertas rutas.
Un ejemplo de trabajo con esta modificación es
"afl-unicorn: Fuzzing Arbitrary Binary Code" y
"Afl-unicornio: Parte 2 - Fuzzing the 'Unfuzzable'" .
Antes de pasar a las modificaciones basadas en los marcos de instrumentación binaria dinámica (DBI), recordamos de inmediato que el más rápido de estos marcos es DynamoRIO, luego DynInst y finalmente PIN.
Modificaciones PIN- aflpin - AFL con Intel PIN Instrumentation.
- afl_pin_mode : otra instrumentación AFL implementada a través de Intel PIN.
- afl-pin - AFL con PINtool.
- NaFl : un clon (del núcleo básico) de AFL fuzzer.
- PinAFL : el autor de la herramienta intentó transferir AFL a Windows para difuminar binarios ya compilados. Aparentemente, se hizo más en el ventilador en una noche, y luego el proyecto no se desarrolla. El repositorio no contiene fuentes, solo binarios recopilados e instrucciones para comenzar. La versión AFL en la que se basa esta herramienta no se especifica y solo admite aplicaciones de 32 bits.
Como puede ver, hay muchas modificaciones diferentes, pero en la práctica no hay mucho uso en la vida real.
Modificaciones basadas en Dyninstafl-dyninst - American Fuzzy Lop + Dyninst == AFL blackbox fuzzing. La característica de esta versión es que el programa inicialmente estudiado (sin código fuente) está instrumentado estáticamente (instrumentación binaria estática, reescritura binaria estática) usando DynInst, y luego se difunde con el clásico AFL, que cree que el programa fue construido usando afl-gcc / afl -g ++ / afl-as;) Al final, nos da la oportunidad de trabajar sin código fuente y con muy buen rendimiento. Solía ser a una velocidad de 0.25x en comparación con una compilación nativa. Hay una ventaja significativa sobre QEMU, que es la capacidad de instrumentar bibliotecas vinculadas dinámicamente. Si bien QEMU solo puede instrumentar el archivo ejecutable principal vinculado estáticamente a las bibliotecas. Desafortunadamente, ahora esto es relevante solo para el sistema operativo Linux. Para admitir Windows, se necesitan cambios en DynInst y
se está
trabajando allí .
También puede prestar atención a tal
bifurcación donde se bombeó bien sobre varias capacidades (soporte para arquitecturas AARCH64 y PPC) y velocidad;)
Modificaciones basadas en DynamoRIO- drAFL - AFL + DynamoRIO = fuzzing sin fuente en Linux.
- afl-dr : una implementación más sobre la base de DynamoRIO, que ya está pintada con gran detalle en espacios abiertos de Habr.
- afl-dynamorio : modificación de vanhauser-thc (un ventilador para bombear y estabilizar AFL). dice acerca de esta versión: "ejecute AFL con DynamoRIO cuando afl-dyninst normal está bloqueando el binario y el modo qemu -Q no es una opción". Desde agradable, aquí se agrega soporte para ARM y AARCH64. Respecto al rendimiento: DynamoRIO es aproximadamente ~ 10 más lento que Qemu, ~ 25 más lento que dyninst, sin embargo, ~ 10 más rápido que Pintool.
- WinAFL es la bifurcación más famosa de afl para Windows. (DynamoRIO, también tiene modo syzygy). La aparición de esta modificación fue solo cuestión de tiempo, ya que el deseo de probar AFL bajo Windows en aplicaciones para las que no hay códigos fuente apareció para muchos. En este momento, la herramienta se está desarrollando activamente y, a pesar de utilizar la base de código AFL ligeramente retrasada (2.43b en el momento de la redacción), ya se han encontrado varias vulnerabilidades (CVE-2016-7212, CVE-2017-0073, CVE-2017- 0190, CVE-2017-11816). Cabe señalar que los principales desarrolladores son especialistas del equipo del Proyecto Google Zero y del Equipo de Vulnerabilidades y Mitigaciones de MSRC, lo que da motivos para esperar un mayor desarrollo activo del proyecto. Para implementar el fuzzer, los desarrolladores han pasado de compilar instrumentación de tiempo a usar instrumentación dinámica (basada en DynamoRIO), que se esperaba que ralentizara la ejecución del software en estudio, pero la sobrecarga resultante (dos veces) es comparable al AFL clásico en modo binario. Los desarrolladores también resolvieron el problema de un largo inicio del proceso, llamándolo modo de fuzzing persistente, seleccionan la función que necesita ser difuminada (por desplazamiento dentro del archivo o por nombre si la función se presenta en la tabla de exportación) y la instrumentan de tal manera que se pueda llamar en un bucle, iniciando así varias muestras de datos de entrada sin reiniciar el proceso. Recientemente apareció un artículo interesante en el que los investigadores mostraron cómo encontraron ~ 50 vulnerabilidades con ~ 50 días usando winafl. Además, casi antes de la publicación del artículo en WinAFL, también se agregó el modo Intel PT (más sobre esto más adelante) - los detalles están aquí .
Un lector avanzado / sofisticado puede notar que hay modificaciones con todos los marcos de instrumentación populares, con la excepción de
Frida , de hecho lo es. La única mención del uso de Frida con AFL se encontró solo en
Chizpurfle: un Fuzzer de Android Gray-Box para personalizaciones de servicios de proveedores . La versión de AFL con Frida fue realmente útil ya que Frida admite varias arquitecturas RISC.
Muchos investigadores también esperan con ansias el lanzamiento del marco Scorpio DBI del creador de Capstone, Unicorne, Keystone. En base a este marco, los propios autores ya han creado un fuzzer (Darko) y, según ellos, lo han utilizado con éxito para difuminar dispositivos integrados. Para obtener más información, consulte
Excavación profunda: búsqueda de 0 días en sistemas integrados con fuzzing guiado de cobertura de código .
Modificaciones basadas en las capacidades de hardware del procesadorCuando se trata de modificaciones AFL con soporte para las capacidades de hardware del procesador, esto indica principalmente la posibilidad de difuminar el código del kernel y, en segundo lugar, una mayor velocidad de difuminado para aplicaciones sin código fuente.
Y, por supuesto, antes que nada estamos hablando de capacidades de hardware del procesador como
Intel PT (Processor Tracing). Que está disponible a partir de la sexta generación de procesadores (esto es de aproximadamente 2015). Naturalmente, para usar los siguientes fuzzers, necesitará hardware con el soporte Intel PT adecuado.
Conclusión
Como habrás notado, este tema se está desarrollando activamente. Al mismo tiempo, hay mucho espacio para la creatividad para crear una modificación nueva, interesante y útil de AFL.
¡Gracias por su atención y su exitoso fuzzing!
Coautor: Nikita Knizhov
PD: Gracias a todo el equipo del centro de investigación por su ayuda en la preparación de este material, sin su experiencia y ayuda, sería imposible prepararlo.