Marco para automatizar el descubrimiento de objetivos difuso con análisis estático
Los investigadores de vulnerabilidad que realicen evaluaciones de seguridad en el software a menudo aprovechen las capacidades de la confusión guiada por cobertura a través de herramientas potentes como AFL ++ y Libfuzzer. Esto es importante ya que automatiza el proceso de sumidero y revela condiciones de explotación en objetivos rápidamente. Sin embargo, al encontrar bases de código grandes y complejas o binarios de código cerrado, los investigadores tienen que dedicar minuciosamente tiempo para auditar e invertir manualmente la ingeniería para identificar funciones donde la exploración basada en confuso puede ser útil.
Fuzzable es un marco que integra tanto con el código fuente de C/C ++ como con los binarios para ayudar a los investigadores de vulnerabilidad a identificar objetivos de función que son viables para la confusión. Esto se realiza aplicando varias heurísticas basadas en análisis estáticos para identificar comportamientos de riesgo en el software y las funciones que las ejecutan. Los investigadores pueden utilizar el marco para generar plantillas básicas de arnés, que luego pueden usarse para buscar vulnerabilidades o para integrarse como parte de una tubería confusa continua, como el proyecto OSS-Fuzz de Google.
Además de ejecutar como una herramienta independiente, Fuzzable también está integrado como un complemento para el desascado binario ninja, con soporte para otros retroceder de desmontaje que se está desarrollando.
Consulte la publicación de blog original que detalla la herramienta aquí, que resalta las especificaciones técnicas de las heurísticas de análisis estático y cómo surgió esta herramienta. Esta herramienta también aparece en Black Hat Arsenal USA 2022.
Algunos objetivos binarios pueden requerir cierta desinfectación (es decir, coincidencia de firma, o identificar funciones de la enlinición), y por lo tanto difuso utiliza principalmente ninja binaria como un backend de desmontaje debido a su capacidad para resolver estos problemas de manera efectiva. Por lo tanto, se puede utilizar tanto como una herramienta y un complemento independientes.
Dado que Binary Ninja no es accesible para todos y puede haber una demanda para utilizar para evaluaciones de seguridad y potencialmente ampliar en la nube, también se admite un backend de alternativa Angr. Anticipo incorporar a otros desestimadores en el futuro (Prioridad: Ghidra).
Si tiene un comercial de Ninja Binary, asegúrese de instalar la API para un uso independiente sin cabeza:
$ python3 /Applications/Binary Ninja.app/Contents/Resources/scripts/install_api.py
Instalar con pip :
$ pip install fuzzable
Utilizamos poesía para la gestión de dependencias y la construcción. Para hacer una construcción manual, clone el repositorio con los módulos de terceros:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
Para instalar manualmente:
$ cd fuzzable/
# without poetry
$ pip install .
# with poetry
$ poetry install
# with poetry for a development virtualenv
$ poetry shell
¡Ahora puede analizar binarios y/o código fuente con la herramienta!
# analyzing a single shared object library binary
$ fuzzable analyze examples/binaries/libbasic.so
# analyzing a single C source file
$ fuzzable analyze examples/source/libbasic.c
# analyzing a workspace with multiple C/C++ files and headers
$ fuzzable analyze examples/source/source_bundle/
Fuzzable se puede instalar fácilmente a través del mercado de complementos Ninja Binary yendo a Binary Ninja > Manage Plugins y buscandolos. Aquí hay un ejemplo del complemento difuso que se ejecuta, la precisión de identificación de objetivos para la evaluación de vulnerabilidad de Fuzzing y una mayor vulnerabilidad:

Fuzzable viene con varias opciones para ayudar a ajustar mejor su análisis. Más serán compatibles con planes futuros y cualquier solicitud de función realizada.
Para determinar la fuzzabilidad, Fuzzable utiliza varias heurísticas para determinar qué objetivos son los más viables para el objetivo para el análisis dinámico. Estas heurísticas se ponderan de manera diferente utilizando la biblioteca de criterios Scikit, que utiliza un análisis de decisión de criterios múltiples para determinar los mejores candidatos. Estas métricas y los pesos se pueden ver aquí:
| Heurístico | Descripción | Peso |
|---|---|---|
| Nombre amigable con fuzz | El nombre del símbolo implica un comportamiento que ingiere la entrada de archivo/búfer | 0.3 |
| Sumideros arriesgados | Argumentos que fluyen a llamadas riesgosas (es decir, memcpy) | 0.3 |
| Bucles naturales | Número de bucles detectados con la frontera de dominio | 0.05 |
| Complejidad ciclomática | Complexidad del objetivo de función basado en bordes + nodos | 0.05 |
| Profundidad de cobertura | Número de calles El objetivo se atraviesa | 0.3 |
Como se mencionó, consulte la publicación de blog técnico para obtener una mirada más profunda de por qué y cómo se utilizan estas métricas.
Muchas métricas se inspiraron en gran medida en el trabajo original de Vincenzo Iozzo en 0-conocimientos de conocimiento.
Todos los objetivos que desea analizar es diverso, y Fuzzable no podrá tener en cuenta cada comportamiento de caso de borde en el objetivo del programa. Por lo tanto, puede ser importante durante el análisis sintonizar estos pesos adecuadamente para ver si diferentes resultados tienen más sentido para su caso de uso. Para sintonizar estos pesos en la CLI, simplemente especifique el argumento --score-weights :
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
Por defecto, Fuzzable filtrará objetivos de función en función de los siguientes criterios:
static y no están expuestas a través de encabezados. Para ver las llamadas que Fullable se filtró, establezca el indicador --list_ignored :
$ fuzzable analyze --list-ignored <TARGET>
En Binary Ninja, puede convertir esta configuración en Settings > Fuzzable > List Ignored Calls .
En el caso de que Fuzzable filma falsamente llamadas importantes que deben analizarse, se recomienda utilizar los argumentos --include-* para incluirlas durante la ejecución:
# include ALL non top-level calls that were filtered out
$ fuzzable analyze --include-nontop <TARGET>
# include specific symbols that were filtered out
$ fuzzable analyze --include-sym <SYM> <TARGET>
En Binary Ninja, esto se admite a través de Settings > Fuzzable > Include non-top level calls Symbols to Exclude .
Ahora que ha encontrado a sus candidatos ideales para Fuzz, Fuzzable también lo ayudará a generar arneses difusos que están (casi) listos para instrumentar y compilar para su uso con un fuzzer basado en archivos (es decir, AFL ++, Honggfuzz) o Fuzzer in-Memory (LibFuzzer). Para hacerlo en el CLI:
# generate harness from a candidate
$ fuzzable create-harness target --symbol-name=some_unsafe_call
# make minimal and necessary modifications to the harness
$ vim target_some_unsafe_call_harness.cpp
# example compilation for AFL-QEMU, which is specified in the comments of the generated harness
$ clang target_some_unsafe_call_harness.cpp -no-pie -o target_some_unsafe_call_harness -ldl
# create your base seeds, ideally should be more well-formed for input
$ mkdir in/
$ echo "seed" >> in/seed
# start black box fuzzing
$ afl-fuzz -Q -m none -i in/ -o out/ -- ./target_some_unsafe_call_harness
Si este objetivo es una base de código fuente, se utilizará la plantilla de origen genérico.
Si el objetivo es un binario, se utilizará la plantilla genérica de caja negra, que idealmente se puede usar con un modo de emulación difuso como AFL-QEMU. También se creará una copia del binario como un objeto compartido si el símbolo no se exporta directamente para ser dlopen usando lief.
Por el momento, esta característica es bastante rudimentaria, ya que simplemente creará un arnés de C ++ independiente poblado con los parámetros apropiados, y no se necesita un código automático para cualquier comportamiento de tiempo de ejecución (es decir, estructuras instanciantes y liberadoras). Sin embargo, las plantillas creadas para Fuzzable deberían hacer que se ejecute rápidamente. Aquí hay algunas características ambiciosas que me gustaría implementar en el futuro:
Fuzzable admite los informes de generación en varios formatos. Los actuales que son compatibles son JSON, CSV y Markdown. Esto puede ser útil si está utilizando esto como parte de la automatización donde desea ingerir la salida en un formato serializable.
En la CLI, simplemente pase el argumento --export con un nombre de archivo con la extensión apropiada:
$ fuzzable analyze --export=report.json <TARGET>
En Binary Ninja, vaya a Plugins > Fuzzable > Export Fuzzability Report > ... y seleccione el formato al que desea exportar y la ruta a la que desea escribirlo.
¡Esta herramienta se desarrollará continuamente, y se agradecerá cualquier ayuda de manteneros externos!
Fuzzable tiene licencia bajo la licencia MIT.