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
fpicker — Suite de fuzzing in-process basada en Frida con proxy AFL++, modos activo/pasivo independientes y comunicación por memoria compartida para descubrimiento de vulnerabilidades guiado por cobertura de alto rendimiento entre plataformas. | Kitploit
Herramientas/GitHubGitHub/ttdennis/fpicker
Análisis Dinámico (Sandboxing)Análisis de VulnerabilidadesExplotaciónFuzzingAnálisis de Binarios
GitHubttdennis/fpicker

fpicker

Suite de fuzzing in-process basada en Frida con proxy AFL++, modos activo/pasivo independientes y comunicación por memoria compartida para descubrimiento de vulnerabilidades guiado por cobertura de alto rendimiento entre plataformas.

Ver Repositorio
29634hace 1 añoRevisado 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

fpicker

Logotipo de Fpicker

fpicker es un conjunto de herramientas de fuzzing basado en Frida que ofrece una variedad de modos de fuzzing para fuzzing en proceso, como un modo AFL++ o un modo de rastreo pasivo. Debería funcionar en todas las plataformas compatibles con Frida.

  • Instrucciones de instalación
  • Compilación y ejecución
  • Creación de un Harness de Fuzzing
  • Modos y configuración

Alguna información de contexto y las ideas detrás de fpicker se pueden encontrar en un blogpost que escribí.

Fpicker se basa en esfuerzos anteriores como ToothPicker, que fue desarrollado durante mi tesis de maestría. La mayor parte de fpicker se desarrolló durante horas de trabajo en mi empleador (ERNW).

Requisitos e instalación

Requerido para ejecutar fpicker:

  • frida_compile para compilar el script del harness en un archivo JS
  • El frida-core-devkit para la plataforma respectiva que se encuentra en Lanzamientos de Frida en GitHub.
    • Dependiendo de la plataforma a la que desees apuntar, guarda la librería como libfrida-core-ios.a, libfrida-core-macos.a o libfrida-core-linux.a.
    • Lo mismo ocurre con los archivos de cabecera (frida-core.h). Guárdalos como frida-core-linux.h o frida-core-ios.h según la plataforma.
    • El Makefile se construyó de esta manera para que puedas compilar para diferentes sistemas en un mismo sistema (por ejemplo, tu sistema anfitrión y el teléfono).
    • Si prefieres usar una versión específica, ajusta el Makefile en consecuencia.
    • Para actualizar a la última versión, simplemente ejecuta update_frida_version.sh antes de compilar.

Requerido solo cuando se ejecuta en modo AFL++:

  • AFL++
    • en macOS:
      • Compilar con CFLAGS="-DUSEMMAP=1".
    • en iOS:
      • Compilar con CFLAGS="-DUSEMMAP=1 -DTARGET_OS_IOS".

Compilación y ejecución

Fpicker se puede compilar para macOS, iOS o Linux. El Makefile actualmente solo admite la compilación para iOS en macOS, pero debería ser totalmente posible compilar fpicker usando un toolchain de iOS en Linux.

Dependiendo del objetivo deseado, ejecute:

root@kitploit:~
make fpicker-macos
make fpicker-ios
make fpicker-linux

para compilar fpicker.

Una vez que fpicker está compilado, el harness de fuzzing debe compilarse a continuación:

Consulte la carpeta de ejemplos para diferentes casos de muestra de fuzzing. El enfoque general es el siguiente:

  • Cree un harness personalizado para el objetivo (por ejemplo, examples/test/test.js) (consulte aquí para obtener más información sobre los harnesses)
  • Compile el harness personalizado usando frida-compile frida-compile test.js -o harness.js

Ahora fpicker puede comenzar a fuzzear. El comando exacto depende en gran medida de la configuración y el entorno. A continuación se presentan algunos casos de ejemplo. Estos corresponden en su mayoría a los ejemplos en la carpeta de ejemplos.

  • Ejecutar fpicker como proxy de AFL++ adjuntándose a un proceso objetivo para fuzzear una función específica en proceso:
root@kitploit:~
afl-fuzz -i examples/test-network/in -o ./examples/test-network/out -- \\
    ./fpicker --fuzzer-mode afl -e attach -p test-network -f ./examples/test-network/harness.js
  • Ejecutar fpicker en modo independiente adjuntándose a un servidor y ejecutando un programa cliente para enviar la entrada de fuzzing:
root@kitploit:~
./fpicker --fuzzer-mode standalone -e attach -p server-process -f harness.js --input-mode cmd \\
    --command "./client-send @@" -i indir -o outdir
  • Ejecutar fpicker en modo independiente adjuntándose a un servidor, fuzzeando en proceso con un comando mutador personalizado:
root@kitploit:~
./fpicker --fuzzer-mode active --communication-mode shm -e attach -p server-process -f harness.js \\
    -i indir -o outdir --standalone-mutator cmd --mutator-command "radamsa"
  • Ejecutar fpicker en modo pasivo adjuntándose a un servidor recolectando cobertura y payloads:
root@kitploit:~
./fpicker --fuzzer-mode passive --communication-mode send -e attach -p server-process -o outdir -f harness.js
  • Ejecutar fpicker en modo independiente adjuntándose a un proceso en ejecución en un dispositivo remoto, fuzzeando en proceso con un comando mutador personalizado:
root@kitploit:~
./fpicker --fuzzer-mode active -e attach -p test -D remote -o examples/test/out/ -i examples/test/in/ \\
    -f fuzzer-agent.js --standalone-mutator cmd --mutator-command "radamsa"

Creación de un Harness de Fuzzing

Cada objetivo requiere su propio harness de fuzzing. La parte más importante de este harness es definir la función de entrada de Stalker de Frida, que determina efectivamente en qué punto se inserta la instrumentación. En el modo in-process esto es simple. La función suele ser la que se llama en cada iteración de fuzzing. Sin embargo, también podría ser una diferente.

Una implementación mínima de harness (en modo command) podría ser esta:

root@kitploit:~
// Import the fuzzer base class
const Fuzzer = require("harness/fuzzer.js");

// The custom fuzzer needs to subclass the Fuzzer class to work properly
class TestFuzzer extends Fuzzer.Fuzzer {
    constructor() {
        // The constructor needs to specify the address of the targeted function and a NativeFunction
        // object that can later be called by the fuzzer.

        const FUZZ_FUNCTION_ADDR = Module.getExportByName(null, "FUZZ_FUNCTION");
        const FUZZ_FUNCTION = new NativeFunction(
            FUZZ_FUNCTION_ADDR,
            "void", ["pointer", "int64"], {
        });

        super("test", FUZZ_FUNCTION_ADDR, FUZZ_FUNCTION);
    }
}

const f = new TestFuzzer();
exports.fuzzer = f;

Este harness configura la instrumentación para seguir la función FUZZ_FUNCTION. La instrumentación comenzará cuando se ingrese a esta función y se detendrá cuando la función retorne. Esta función debe elegirse con cuidado, ya que es costosa y cuantas más partes (potencialmente sin importancia) del proceso se instrumenten, más lento se vuelve el fuzzer. Por supuesto, esto es una consideración entre velocidad y cobertura deseada. Además, el fuzzer actualmente solo admite funciones que se ingresan solo una vez durante una iteración de fuzzing, es decir, la función no debe ser llamada más de una vez durante un caso de fuzz, de lo contrario, la información de cobertura podría volverse poco confiable.

Cuando se usa el modo in-process, se requiere otra función en el script del fuzzer: el método fuzz. Se llamará en cada iteración. Se llamará con dos parámetros: un puntero a un búfer y la longitud del búfer. Nuestra función objetivo de ejemplo toma dos parámetros: un puntero a un búfer y su longitud. Por lo tanto, podemos pasar los parámetros que recibimos en el método fuzz.

root@kitploit:~
fuzz(payload, len) {
    this.target_function(payload, parseInt(len));
}

En modo passive, se debe especificar un callback que procese los datos requeridos. El fuzzer espera recibir un búfer de payload y su longitud. Dependiendo de la función objetivo que se esté fuzzeando, estos datos deben extraerse. En el siguiente ejemplo, nuevamente tenemos una función que tiene dos parámetros: un puntero a un búfer y su longitud. El parámetro args contiene todos los parámetros potenciales que recibe la función objetivo, por lo que el parámetro de longitud (que es el segundo en nuestro caso) se puede acceder con args[1]. Luego leemos el búfer como Uint8Array y lo enviamos de vuelta al fuzzer usando el método sendPassiveCorpus.

root@kitploit:~
passiveCallback(args) {
    const len = args[1];
    const data = new Uint8Array(Memory.readByteArray(args[0], parseInt(len)));

    // this encodes the data and sends it back to the fuzzer
    this.sendPassiveCorpus(data, len);
}

En caso de que el objetivo necesite algún tipo de preparación antes de que el fuzzer pueda comenzar, fpicker proporciona un método prepare que se llama durante la inicialización del fuzzer. La preparación podría ser el establecimiento de estado, por ejemplo, instanciando un objeto. Tal función de preparación podría verse así:

root@kitploit:~
prepare() {
  // the object can be attached to the fuzzer instance so that it can be used within the
  // fuzz() method later on.
  this.required_object = call_native_function_that_creates_object();
}

Modos y configuración

pficker ofrece un gran conjunto de modos y configuraciones que se explican a continuación. La mayoría de estos modos se pueden combinar de diferentes maneras. Al final de esta sección hay una tabla que muestra qué opciones se pueden combinar y cuál es su estado de implementación.

Modo de Fuzzer

Fpicker tiene tres modos de fuzzing diferentes: Modo AFL++, Modo Activo Independiente y Modo Pasivo Independiente:

  • Modo AFL++: En el modo AFL++, fpicker actúa como un proxy entre AFL++ y el proceso objetivo. Usando las capacidades de instrumentación de Frida, el mapa de bits de cobertura de AFL se completa mientras el objetivo se fuzzea con datos de entrada generados por AFL++.

  • Modo Activo Independiente: En el modo activo independiente, el fuzzer utiliza los resúmenes de llamadas de Stalker de Frida para recopilar cobertura en forma de bloques básicos que se ejecutan durante una iteración. Esto no es nuevo y se ha implementado de varias formas antes. Sin embargo, en combinación con otras configuraciones del fuzzer, esto puede tener varios beneficios. También es una buena alternativa si AFL++ no es aplicable o deseable en un entorno o caso determinado.

  • Modo Pasivo Independiente: El modo pasivo es menos un fuzzer y más un trazador. Esencialmente, hace lo mismo que el modo activo independiente. Sin embargo, no envía sus propias entradas. Simplemente se adjunta a una función determinada y recopila cobertura. Una vez que se observa nueva cobertura, se almacenan tanto la cobertura como la entrada.

Modo de entrada

Si bien fpicker está diseñado principalmente como un fuzzer en proceso, también admite fuzzing a través de un comando externo. Para esto, fpicker ofrece dos modos de entrada.

  • Modo de entrada en proceso: En el modo de entrada en proceso, el harness llama directamente a una función especificada en el proceso objetivo. El fuzzer envía el payload al harness y el harness prepara el payload de manera que pueda llamar a la función objetivo.

  • Modo de entrada CMD: En el modo de entrada por comando, el payload se redirige a un comando externo. Esto es útil cuando es demasiado complejo preparar los parámetros u otro estado al llamar directamente a la función objetivo. La recolección de cobertura aún debe adjuntarse a una función determinada. Quizás hay un cliente al que se le puede suministrar un payload que luego activa la función objetivo.

Modo de comunicación

El modo de comunicación determina cómo el harness inyectado se comunica con el fuzzer. Esto depende en gran medida de la aplicación objetivo. Frida ofrece una API para enviar y recibir mensajes desde el script del agente inyectado. Este tipo de comunicación es bastante costoso. Uno de los factores es que el mensaje transportado debe codificarse en JSON. Por lo tanto, enviar datos binarios es sencillo. Por lo tanto, fpicker ofrece un segundo modo de comunicación sobre memoria compartida. Sin embargo, esto solo funciona si es posible establecer memoria compartida entre el fuzzer y la aplicación objetivo, lo que significa que este modo no se puede usar cuando el objetivo está conectado al host del fuzzer a través de USB. En el modo de entrada CMD, el modo de comunicación solo se refiere a cómo se comunica la información de cobertura de vuelta al fuzzer, no cómo se envía el payload, ya que esto se delega a un comando externo.

  • Modo de comunicación Send: En el modo de comunicación send, el payload se envía mediante el mecanismo de llamada RPC de Frida. Esto permite que el fuzzer ejecute una función de JavaScript dentro del script del harness inyectado. Esta función dentro del harness puede entonces realizar todas las preparaciones necesarias para llamar a la función objetivo. Una vez que la función objetivo retorna, la recolección de cobertura se detiene y el harness puede señalar al fuzzer que la iteración ha finalizado. Esto se hace enviando la información de cobertura de vuelta al fuzzer usando la API send de Frida.

  • Modo de comunicación SHM: En el modo de comunicación SHM, el fuzzer y el script del harness se comunican a través de memoria compartida y semáforos. Se utiliza un búfer en memoria compartida para enviar el payload y recibir la información de cobertura. En lugar de enviar y recibir, los dos componentes usan espera y publicación en el semáforo. Dependiendo del sistema y el objetivo, esto introduce bastantes ganancias de rendimiento. Especialmente porque el payload binario se escribe en memoria una vez y no tiene que ser codificado y decodificado o copiado a otras ubicaciones de memoria. Desafortunadamente, este modo a veces conduce a una baja estabilidad cuando se ejecuta con AFL++. No estoy seguro de por qué todavía.

Modo de ejecución

El modo de ejecución puede ser spawn o attach. Esto es bastante autoexplicativo. fpicker puede adjuntarse a un proceso en ejecución o crear un proceso. Una diferencia importante entre los dos modos es que, si el objetivo adjunto falla, fpicker no intentará reiniciarlo.

Mutador independiente

En modo independiente, fpicker ofrece tres estrategias diferentes de mutación de entrada. Dicho de manera elegante, la mutación de entrada ciertamente tiene mucho margen de mejora.

  • Mutador independiente NULL: Este mutador no muta el payload y simplemente devuelve una copia del mismo payload. Principalmente para fines de prueba. Por lo demás, no es realmente útil.

  • Mutador independiente Rand: Un mutador aleatorio muy malo. Todo lo que hace es reemplazar valores aleatoriamente en ubicaciones aleatorias del payload original. No cambia la longitud del payload.

  • Mutador independiente Personalizado: Este mutador puede llamar a un comando externo para mutar payloads. Escribe el payload en stdin y recibe el payload mutado desde stdout. Debido a su implementación superficial, tiene un impacto significativo en el rendimiento.

Dispositivos USB

Usando la opción de dispositivo -D usb, Frida seleccionará el primer dispositivo USB local, por ejemplo, un iPhone o un teléfono Android.

Dispositivos de red

Con la opción -D remote es posible fuzzear un proceso que se ejecuta en un dispositivo de red. Para esto, el dispositivo remoto debe estar ejecutando frida-server. Como configuración de ejemplo, use SSH con reenvío de puertos para vincular el puerto de escucha predeterminado 27042 de frida-server en el dispositivo remoto a un socket en el cliente local.

root@kitploit:~
ssh -N [email protected] -L 127.0.0.1:27042:127.0.0.1:27042

En un iPhone, también se puede usar iproxy para reenviar el puerto desde una conexión USB. Esto puede ser especialmente útil si se ejecuta Frida en un puerto no estándar en un dispositivo sin jailbreak con el gadget de Frida. Al trabajar con el gadget de Frida, el único proceso disponible tendrá el nombre Gadget, independientemente del nombre de la aplicación objetivo.

root@kitploit:~
iproxy 27042 27042

Luego use frida-ps para validar la configuración listando los procesos en el dispositivo remoto:

root@kitploit:~
frida-ps -R
Descargar herramienta