Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
FormatFuzzer — Fuzzer de formatos binarios basado en plantillas que genera y analiza entradas de prueba válidas a alta velocidad, con integración con AFL++ para fuzzing guiado por cobertura. | Kitploit
Herramientas/GitHubGitHub/uds-se/formatfuzzer
FuzzingAnálisis de Binarios
GitHubuds-se/formatfuzzer

FormatFuzzer

Fuzzer de formatos binarios basado en plantillas que genera y analiza entradas de prueba válidas a alta velocidad, con integración con AFL++ para fuzzing guiado por cobertura.

Ver RepositorioSitio web
446384hace 6 mesesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

FormatFuzzer

FormatFuzzer es un marco de trabajo para la generación y análisis de entradas binarias de alta eficiencia y alta calidad. Toma una plantilla binaria que describe el formato de una entrada binaria y genera un ejecutable que produce y analiza el formato binario dado. A partir de una plantilla binaria para GIF, por ejemplo, FormatFuzzer produce un generador de GIF, también conocido como fuzzer de GIF.

Los generadores producidos por FormatFuzzer son altamente eficientes, produciendo miles de entradas de prueba válidas por segundo, en marcado contraste con los fuzzers basados en mutación, donde la gran mayoría de las entradas son inválidas. Las entradas generadas por FormatFuzzer son independientes del programa bajo prueba (o, en realidad, de cualquier programa), por lo que también se pueden usar en entornos de caja negra. Sin embargo, FormatFuzzer también se integra con AFL++ para producir entradas válidas que también busquen la máxima cobertura. En nuestros experimentos, este enfoque de "lo mejor de dos mundos" supera a todos los demás entornos; consulte nuestro artículo para obtener más detalles.

Las plantillas binarias utilizadas por FormatFuzzer provienen del editor 010. Hay más de 170 plantillas binarias, que se pueden usar directamente para FormatFuzzer o adaptarse para su uso. De serie, FormatFuzzer produce formatos como AVI, BMP, GIF, JPG, MIDI, MP3, MP4, PCAP, PNG, WAV y ZIP; y seguimos ampliando esta lista cada semana.

¡Los colaboradores son bienvenidos! Visite la página del proyecto FormatFuzzer para plantear ideas y problemas, o agregar pull requests. Para obtener detalles sobre cómo funciona FormatFuzzer y cómo se compara, lea nuestro artículo para más información.

Obtención

FormatFuzzer está disponible en la página del proyecto FormatFuzzer. Puede descargar y descomprimir la última versión desde la página de versiones.

Para lo más reciente y mejor, también puede clonar su repositorio git:

root@kitploit:~
git clone https://github.com/uds-se/FormatFuzzer.git

Todas las acciones posteriores se realizan en su carpeta principal:

root@kitploit:~
cd FormatFuzzer

Prerrequisitos

Para ejecutar FormatFuzzer, necesita lo siguiente:

  • Python 3
  • Un compilador de C++ con bibliotecas GNU (notablemente getopt_long()) como clang o gcc
  • Los paquetes de Python py010parser, six e intervaltree
  • Una biblioteca zlib (para funciones de compresión)
  • Una biblioteca boost (para funciones de suma de comprobación)

Si planea editar los scripts de compilación y configuración (archivos .ac y .am), también necesitará

  • GNU autoconf
  • GNU automake

Instalación de Requisitos en Linux (Paquetes Debian, usando un entorno virtual de python)

root@kitploit:~
sudo apt install git g++ make automake python3-full zlib1g-dev libboost-dev
python3 -m venv ~/fuzz
source ~/fuzz/bin/activate
pip3 install py010parser six intervaltree

Instalación de Requisitos en MacOS (con Xcode y Homebrew)

root@kitploit:~
xcode-select --install
brew install python3 automake boost
pip3 install py010parser six intervaltree

Instalación de Solo Paquetes de Python (Todos los Sistemas Operativos)

En todos los sistemas, usando pip:

root@kitploit:~
pip install py010parser
pip install six
pip install intervaltree

Compilación

Nota: todos los comandos de compilación requieren que esté en la misma carpeta que este archivo README. La compilación de un fuzzer fuera de esta carpeta aún no es compatible.

Método 1: Usando el script build.sh

Hay un script build.sh que automatiza todos los pasos de construcción. Simplemente ejecute

root@kitploit:~
./build.sh gif

para crear un fuzzer de GIF.

Esto funciona para todos los formatos de archivo proporcionados en templates/; si hay un archivo templates/FOO.bt, entonces ./build.sh FOO compilará un fuzzer.

Método 2: Usando Make

Hay un Makefile (fuente en Makefile.am) que automatiza todos los pasos de construcción. (Requiere GNU make). Primero haga

root@kitploit:~
touch configure Makefile.in

luego

root@kitploit:~
./configure

y luego

root@kitploit:~
make gif-fuzzer

para crear un fuzzer de GIF.

Esto funciona para todos los formatos de archivo proporcionados en templates/; si hay un archivo templates/FOO.bt, entonces make FOO-fuzzer compilará un fuzzer.

Método 3: Pasos manuales

Si el método make anterior no funciona, o si desea más control, es posible que deba proceder manualmente.

Paso 1: Compilación de Archivos de Plantilla Binaria a código C++

Ejecute el compilador ffcompile para compilar la plantilla binaria en código C++. Toma dos argumentos: la plantilla binaria .bt y un archivo .cpp de C++ que se generará.

root@kitploit:~
./ffcompile templates/gif.bt gif.cpp

Paso 2: Compilación del código C++

Utilice los siguientes comandos para crear un fuzzer gif-fuzzer. Primero, compile el controlador de línea de comandos genérico:

root@kitploit:~
g++ -c -I . -std=c++17 -g -O3 -Wall fuzzer.cpp

(-I . denota la ubicación del archivo bt.h; -std=c++17 establece el estándar de C++).

Luego, compile el analizador/generador binario:

root@kitploit:~
g++ -c -I . -std=c++17 -g -O3 -Wall gif.cpp

Finalmente, enlace el analizador/generador binario con el controlador de línea de comandos para obtener un ejecutable. Si utiliza bibliotecas adicionales (como -lz), asegúrese de especificarlas aquí también.

root@kitploit:~
g++ -O3 gif.o fuzzer.o -o gif-fuzzer -lz

Ejecución del Fuzzer

FormatFuzzer se puede ejecutar como un analizador, generador o mutador independiente de formatos específicos. Además, puede ser llamado por fuzzers de propósito general como AFL++ para integrar esas capacidades específicas de formato en el proceso de fuzzing (consulte la sección a continuación sobre la integración con AFL++).

El fuzzer generado toma un comando como primer argumento, seguido de opciones y argumentos para ese comando.

El comando más importante es fuzz, para producir salidas. Sus argumentos son archivos que se generarán en el formato apropiado.

Ejecute el generador como

root@kitploit:~
./gif-fuzzer fuzz output.gif

para crear un archivo binario aleatorio output.gif, o

root@kitploit:~
./gif-fuzzer fuzz out1.gif out2.gif out3.gif

para crear tres archivos GIF out1.gif, out2.gif y out3.gif.

Tenga en cuenta que la plantilla gif.bt que proporcionamos ha sido aumentada con funciones especiales para facilitar la generación de archivos válidos. Si utiliza archivos de plantilla .bt originales sin adaptaciones, puede recibir advertencias durante la generación y crear archivos inválidos.

Ejecución de Analizadores

También puede ejecutar el fuzzer como un analizador de archivos binarios, usando el comando parse. Esto es útil si desea probar la precisión de la plantilla binaria, o si desea mutar una entrada (consulte 'Archivos de Decisión', a continuación).

Para ejecutar el analizador, use

root@kitploit:~
./gif-fuzzer parse input.gif

Verá mensajes de error si input.gif no se puede analizar correctamente.

Archivos de Decisión

Mientras analiza, también puede almacenar todas las decisiones de análisis (es decir, qué alternativas de análisis se tomaron) en un archivo de decisión. Esta es una secuencia de bytes que enumera las decisiones tomadas. Cada byte representa una única decisión de análisis. Un valor de byte 0 significa que se tomó la primera alternativa, un valor de byte 1 significa que se tomó la segunda alternativa, y así sucesivamente.

Puede generar dicho archivo de decisión al analizar una entrada:

root@kitploit:~
./gif-fuzzer parse --decisions input.dec input.gif

Aquí, input.dec almacena las decisiones tomadas para analizar input.gif.

También puede usar dicho archivo de decisión al generar entradas. El fuzzer tomará entonces las mismas decisiones exactas que se encontraron durante el análisis. El siguiente comando genera un nuevo archivo GIF usando las decisiones determinadas al analizar input.gif:

root@kitploit:~
./gif-fuzzer fuzz --decisions input.dec input2.gif

Si todo funciona bien, ambos archivos deberían ser idénticos:

root@kitploit:~
cmp input.gif input2.gif

Al mutar un archivo de decisión (por ejemplo, reemplazando bytes individuales), puede crear entradas que sean similares al archivo original analizado. Esto es útil para interactuar con estrategias de prueba específicas y fuzzers como AFL, donde puede usar gif-fuzzer y similares como traductores de archivos de decisión a archivos binarios y viceversa: AFL mutaría los archivos de decisión, y el programa bajo prueba se ejecutaría sobre los archivos binarios traducidos. En contraste con la mutación directa de archivos binarios (como AFL haría normalmente), esto tendría la ventaja de tener siempre entradas válidas, y por lo tanto progresar mucho más rápido hacia la cobertura.

Integración con AFL++

Además de los fuzzers específicos de formato, como gif-fuzzer, FormatFuzzer también se puede compilar en bibliotecas compartidas específicas de formato, como gif.so (para eso, simplemente ejecute ./build.sh gif o make gif.so). Esas bibliotecas compartidas pueden ser cargadas por fuzzers de propósito general, como AFL++.

Para ejecutar AFL++ con FormatFuzzer, simplemente siga las instrucciones en nuestra versión modificada de AFL++. Admitimos diferentes estrategias de fuzzing, incluyendo:

  • AFL+FFMut: ejecuta AFL++ usando FormatFuzzer para proporcionar mutaciones inteligentes específicas de formato.

  • AFL+FFGen: usa FormatFuzzer como un generador específico de formato, mientras que AFL++ muta sus semillas de decisión.

Creación y Personalización de Plantillas Binarias

Para escribir sus propias plantillas binarias .bt (y así crear un fuzzer/analizador de alta eficiencia para ese formato), lea la sección Introducción a Plantillas y Scripts del Manual del Editor 010.

En muchos casos, ya puede existir una plantilla del formato que busca (o uno similar). Eche un vistazo a la colección de plantillas binarias del editor 010 para ver si hay algo que pueda usar o en lo que basar su formato.

Tenga en cuenta que los archivos .bt proporcionados en el repositorio generalmente están destinados a analizar archivos. También se pueden usar para generar archivos, pero a menudo carecen de información exacta sobre qué partes de la entrada son requeridas.

En esta sección, discutimos algunas de las formas en que puede personalizar los archivos .bt para que funcionen bien con FormatFuzzer.

Por ejemplo, para el formato GIF, el archivo templates/gif-orig.bt muestra la plantilla binaria original, que solo fue diseñada para análisis, mientras que el archivo templates/gif.bt es una versión modificada capaz de generar GIFs válidos. Comparando los dos archivos, vemos que se requirió un pequeño número de cambios para lograr esto.

Si ha creado un gif-fuzzer, ya sea ejecutando make gif-fuzzer o usando la herramienta ffcompile, ya ha obtenido un archivo C++ gif.cpp que contiene una implementación del generador y analizador GIF. Esto es útil para ver cómo los cambios que realice en la plantilla binaria se traducen en código ejecutable. Más detalles sobre el código C++ se presentan en la siguiente sección.

La plantilla binaria GIF utiliza funciones de preanálisis ReadUByte() y ReadUShort() para previsualizar los valores de los siguientes bytes en el archivo antes de analizarlos realmente en un campo de estructura. En tiempo de generación, permitimos que estas funciones reciban un argumento adicional que especifique un conjunto de valores conocidos buenos para elegir entre los bytes que preanalizamos. Además, también permitimos especificar un conjunto global de valores conocidos buenos para usar siempre al llamar a una función de preanálisis particular, como ReadUByte(). Estos se almacenan en el vector ReadUByteInitValues.

Por defecto, nuestro procedimiento de traducción ffcompile intenta extraer valores interesantes que se hayan utilizado en comparaciones contra bytes de preanálisis y usarlos como un conjunto global de valores conocidos. Al ejecutar

root@kitploit:~
./ffcompile templates/gif.bt gif.cpp

un mensaje impreso muestra las funciones de preanálisis identificadas, así como los valores interesantes extraídos:

root@kitploit:~
Finished creating cpp generator.

Lookahead functions found:

ReadUByte
ReadUShort

Mined interesting values:

GlobalColorTableFlag: ['1']
LocalColorTableFlag: ['1']
ReadUByte: ['0x3B', '0x2C']
ReadUShort: ['0xF921', '0xFE21', '0x0121', '0xFF21']
Signature: ['"GIF"']

Sin embargo, para la generación de GIF, es mejor especificar el conjunto de valores conocidos buenos para ReadUByte() individualmente en cada llamada a la función. Así que definimos un array vacío (tamaño 0)

root@kitploit:~
const local UBYTE ReadUByteInitValues[0];

para sobrescribir el conjunto de ReadUByteInitValues global y para cada llamada a ReadUByte(), usamos un argumento adicional para especificar el conjunto de valores buenos a usar para esa ubicación particular. El lenguaje de plantillas binarias también es lo suficientemente potente como para permitir que esta elección se realice en función de condiciones de tiempo de ejecución. Por ejemplo, en el siguiente código mostramos cómo la elección de valores apropiados para una llamada a ReadUByte() puede depender de la versión de GIF que estamos generando. Una versión de GIF 89a permite un valor extra posible para el byte (0x21).

root@kitploit:~
	if(GifHeader.Version == "89a")
		local UBYTE values[] = { 0x3B, 0x2C, 0x21 };
	else
		local UBYTE values[] = { 0x3B, 0x2C };

	while (ReadUByte(FTell(), values) != 0x3B) {
		...
	}

Las ediciones restantes requeridas para la plantilla binaria GIF son similares. Por ejemplo, para cada campo de estructura también se puede especificar un conjunto de valores conocidos buenos. Por ejemplo, esto especifica los valores correctos para el campo Version: 87a y 89a.

root@kitploit:~
	char	Version[3] = { {"87a"}, {"89a"} };

Comprensión del Código C++ Generado

Con fines de depuración, así como para comprender cómo hacer cambios apropiados para mejorar sus generadores y analizadores, puede ser útil entender algunos de los mecanismos internos del código C++ generado. Idealmente, debería poder editar los archivos de plantilla binaria hasta que puedan usarse para generar archivos válidos con alta probabilidad, de modo que no tenga que editar el código C++ generado.

El código C++ crea una clase para cada struct y union definido en la plantilla binaria, así como para tipos nativos, como int.

En tiempo de construcción, al inicializar una variable, podemos definir un conjunto de valores conocidos buenos que esta variable puede asumir. Por ejemplo, la llamada al constructor

root@kitploit:~
char_array_class cname(cname_element, { "IHDR", "tEXt", "PLTE", "cHRM", "sRGB", "iEXt", "zEXt", "tIME", "pHYs", "bKGD", "sBIT", "sPLT", "acTL", "fcTL", "fdAT", "IHDR", "IEND" });

especificaría 17 valores buenos para usar en la variable cname. Pero esto a menudo no es suficiente, ya que la elección de tipos de chunk apropiados depende del contexto. Así que también permitimos especificar un conjunto de valores buenos en tiempo de generación al generar un nuevo chunk. Por ejemplo, esta llamada podría usarse para generar una instancia de chunk para el primer chunk, que debe tener tipo IHDR.

root@kitploit:~
GENERATE(chunk, ::g->chunk.generate({ "IHDR" }, false));

Al generar el segundo chunk, podríamos usar esta larga lista de chunks posibles que pueden venir entre el chunk IHDR y el chunk PLTE:

root@kitploit:~
GENERATE(chunk, ::g->chunk.generate({ "iCCP", "sRGB", "sBIT", "gAMA", "cHRM", "pHYs", "sPLT", "tIME", "zTXt", "tEXt", "iTXt", "eXIf", "oFFs", "pCAL", "sCAL", "acTL", "fcTL", "fdAT", "fRAc", "gIFg", "gIFt", "gIFx", "sTER" }, true));

El generador elegirá entonces uniformemente uno de los valores conocidos buenos para usar en la nueva instancia. También permitimos la elección de un valor malicioso que no sea uno de los valores conocidos buenos con una probabilidad pequeña de 1/128. Esta característica se puede habilitar o deshabilitar en cualquier momento usando el método set_evil_bit.

Todas las elecciones aleatorias realizadas por el generador se hacen llamando al método rand_int().

root@kitploit:~
long long rand_int(unsigned long long x, std::function<long long (unsigned char*)> parse);

Cuando se ejecuta el programa como generador, este método muestra un entero de 0 a x-1 leyendo bytes del búfer aleatorio. Cuando se ejecuta el programa como analizador, este método utiliza la función parse() para descubrir qué bytes aleatorios deben estar presentes en el búfer aleatorio para generar el archivo objetivo, y luego escribe esos bytes en el búfer aleatorio. La función parse recibe como argumento el búfer en la posición actual del archivo y debe devolver qué valor tendría que ser devuelto por la llamada actual a rand_int() para generar esta configuración exacta del archivo.

Autores

FormatFuzzer fue diseñado y escrito por Rafael Dutra <[email protected]>.

El concepto de un compilador de fuzzer fue introducido por Rahul Gopinath <[email protected]> y Andreas Zeller <[email protected]>.

Derechos de Autor y Licencias

FormatFuzzer es Copyright © 2020, 2021 por CISPA Helmholtz Center for Information Security. Se aplican las siguientes licencias:

  • El código de FormatFuzzer (notablemente, todo el código C++ y el código relacionado con su generación) está sujeto a la GNU GENERAL PUBLIC LICENSE, como se encuentra en COPYING.

  • Como excepción a lo anterior, el código C++ generado por FormatFuzzer (es decir, fuzzers y analizadores para formatos específicos) es de dominio público.

  • El código pfp original, en el que se basa FormatFuzzer, está sujeto a una licencia MIT, como se encuentra en LICENSE-pfp.

Descargar herramienta