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
PHP-Fuzzer — Fuzzer guiado por cobertura de bordes para bibliotecas PHP que detecta errores mediante fallos, tiempos de espera y advertencias. Admite gestión de corpus, minimización de fallos e informes de cobertura de código. | Kitploit
Herramientas/GitHubGitHub/nikic/php-fuzzer
Análisis Dinámico (Sandboxing)Análisis de VulnerabilidadesAnálisis de CódigoFuzzing
GitHubnikic/php-fuzzer

PHP-Fuzzer

Fuzzer guiado por cobertura de bordes para bibliotecas PHP que detecta errores mediante fallos, tiempos de espera y advertencias. Admite gestión de corpus, minimización de fallos e informes de cobertura de código.

Ver Repositorio
44118hace 7 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

PHP Fuzzer

Esta biblioteca implementa un fuzzer para PHP, que se puede usar para encontrar errores en bibliotecas (particularmente bibliotecas de análisis sintáctico) alimentándolas con entradas "aleatorias". La retroalimentación de la instrumentación de cobertura de aristas se utiliza para guiar la selección de entradas "aleatorias", de modo que se visiten nuevas rutas de código.

Instalación

Phar (recomendado): Puede descargar un paquete phar de esta biblioteca desde la página de lanzamientos. Se recomienda usar el phar porque evita conflictos de dependencias con bibliotecas que usan PHP-Parser.

Composer: composer global require nikic/php-fuzzer

Uso

Primero, es necesario definir la función objetivo. Aquí hay un ejemplo de objetivo para encontrar errores en microsoft/tolerant-php-parser:

root@kitploit:~
<?php // target.php

/** @var PhpFuzzer\Config $config */

require 'path/to/tolerant-php-parser/vendor/autoload.php';

// Requerido: El objetivo acepta una única cadena de entrada y la ejecuta a través de la
//           biblioteca probada. Se permite que el objetivo lance Excepciones normales (que se ignoran),
//           pero las excepciones de Error se consideran un error encontrado.
$parser = new Microsoft\PhpParser\Parser();
$config->setTarget(function(string $input) use($parser) {
    $parser->parseSourceFile($input);
});

// Opcional: Muchos objetivos no presentan errores en entradas grandes que no se puedan
//           producir también con entradas pequeñas. Limitar la longitud puede mejorar el rendimiento.
$config->setMaxLen(1024);
// Opcional: Se puede usar un diccionario para proporcionar fragmentos útiles al fuzzer,
//           como palabras clave del lenguaje. Esto es particularmente importante si estos
//           no pueden ser descubiertos fácilmente por el fuzzer, porque son manejados
//           por una función de extensión PHP no instrumentada como token_get_all().
$config->addDictionary('example/php.dict');

El fuzzer se ejecuta contra un corpus de entradas iniciales "interesantes", que pueden por ejemplo ser sembradas basándose en pruebas unitarias existentes. Si no se especifica un corpus, se creará un directorio de corpus temporal en su lugar.

root@kitploit:~
# Ejecutar sin corpus inicial
php-fuzzer fuzz target.php
# Ejecutar con corpus inicial (una entrada por archivo)
php-fuzzer fuzz target.php corpus/

Si el fuzzing se interrumpe, se puede reanudar más tarde especificando el mismo directorio de corpus.

Una vez que se encuentra un fallo, se escribe en un archivo crash-HASH.txt. Se proporciona en la forma en que se encontró originalmente, que puede ser innecesariamente compleja y contener fragmentos no relevantes para el fallo. Por lo tanto, es probable que desee reducir primero la entrada del fallo:

root@kitploit:~
php-fuzzer minimize-crash target.php crash-HASH.txt

Esto producirá una secuencia de archivos minimized-HASH.txt sucesivamente más pequeños. Si desea verificar rápidamente el rastro de excepción producido para una entrada de fallo, puede usar el comando run-single:

root@kitploit:~
php-fuzzer run-single target.php minimized-HASH.txt

Finalmente, es posible generar un informe de cobertura de código HTML, que muestra qué bloques de código en el objetivo se ejecutan al procesar entradas de un corpus dado:

root@kitploit:~
php-fuzzer report-coverage target.php corpus/ coverage_dir/

Además, las opciones de configuración se pueden mostrar con php-fuzzer --help.

Mientras el fuzzer está en ejecución, informa su estado continuamente usando una sola línea de salida. Esta línea comprende estas partes en el siguiente orden:

  1. NEW o REDUCED: La acción que desencadenó esta línea de estado. NEW indica que se agregó una nueva entrada al corpus, mientras que REDUCED indica que una entrada existente del corpus fue reemplazada por una entrada más corta.
  2. run: N: El número total de iteraciones de fuzzing (ejecuciones del objetivo) realizadas desde que se inició el fuzzer
  3. (N/s): La velocidad de ejecución actual, medida en ejecuciones por segundo
  4. ft: N: El número total de características únicas descubiertas hasta ahora
  5. (N/s): El número promedio de nuevas características descubiertas por segundo desde que se inició el fuzzer
  6. corp: N: El número de entradas interesantes almacenadas actualmente en el corpus
  7. (%s): El tamaño total de todas las entradas en el corpus
  8. len: %d/%d: El primer número es la longitud (en bytes) de la entrada actual que desencadenó la acción, el segundo número es la longitud máxima permitida actual

Tipos de errores

El fuzzer por defecto detecta tres tipos de errores:

  • Excepciones Error lanzadas por el objetivo de fuzzing. Mientras que las excepciones Exception se consideran un resultado normal para entrada mal formada, las excepciones Error no capturadas siempre indican un error de programación.
  • Avisos y advertencias lanzados (a menos que se supriman). El fuzzer registra un manejador de errores que los convierte en excepciones Error.
  • Tiempos de espera. Si el objetivo se ejecuta durante más tiempo que el tiempo de espera especificado (predeterminado: 3 s), se asume que el objetivo ha entrado en un bucle infinito. Esto se realiza usando pcntl_alarm() y un manejador de señales asíncrono que lanza un Error al agotar el tiempo de espera.

Notablemente, ninguno de estos verifica si la salida del objetivo es correcta, solo determinan que el objetivo no se comporta de manera gravemente incorrecta. Una forma de verificar la corrección de la salida es comparar dos implementaciones diferentes que se supone producen resultados idénticos:

root@kitploit:~
$fuzzer->setTarget(function(string $input) use($parser1, $parser2) {
    $result1 = $parser1->parse($input);
    $result2 = $parser2->parse($input);
    if ($result1 != $result2) {
        throw new Error('Results do not match!');
    }
});

Técnico

Muchos de los detalles técnicos de este fuzzer se basan en libFuzzer del proyecto LLVM. A continuación se describen algunos de los detalles de implementación.

Instrumentación

Para funcionar eficientemente, el fuzzing requiere retroalimentación sobre las rutas de código que se ejecutaron al probar una entrada de fuzzing particular. Esta retroalimentación de cobertura se recopila "instrumentando" el objetivo de fuzzing. La biblioteca include-interceptor se utiliza para transformar el código de todos los archivos incluidos sobre la marcha. La biblioteca PHP-Parser se utiliza para analizar el código y encontrar todos los lugares donde se necesita insertar código de instrumentación adicional.

Dentro de cada bloque básico, se inserta el siguiente código, donde BLOCK_INDEX es un entero único por bloque:

root@kitploit:~
$___key = (\PhpFuzzer\FuzzingContext::$prevBlock << 28) | BLOCK_INDEX;
\PhpFuzzer\FuzzingContext::$edges[$___key] = (\PhpFuzzer\FuzzingContext::$edges[$___key] ?? 0) + 1;
\PhpFuzzer\FuzzingContext::$prevBlock = BLOCK_INDEX;

Esto asume que el índice del bloque es de a lo sumo 28 bits y cuenta el número de pares (prev_block, cur_block) que se observan durante la ejecución. El código generado es desafortunadamente bastante costoso, debido a la necesidad de manejar contadores de aristas no inicializados y al uso de propiedades estáticas. En el futuro, sería posible crear una extensión de PHP que pueda recopilar la retroalimentación de cobertura de manera mucho más eficiente.

En algunos casos, los bloques básicos son parte de expresiones, en cuyo caso no podemos insertar fácilmente código adicional. En estos casos, en su lugar insertamos una llamada a un método que contiene el código anterior:

root@kitploit:~
if ($foo && $bar) { ... }
// se convierte en
if ($foo && \PhpFuzzer\FuzzingContext::traceBlock(BLOCK_INDEX, $bar)) { ... }

En el futuro, sería beneficioso instrumentar también las comparaciones, para poder determinar automáticamente entradas de diccionario a partir de comparaciones como $foo == "SOME_STRING".

Características

Las entradas de fuzzing se consideran "interesantes" si contienen nuevas características que no se han observado con otras entradas que ya forman parte del corpus. Esta biblioteca utiliza recuentos de aciertos de aristas de grano grueso como características:

root@kitploit:~
ft = (approx_hits << 56) | (prev_block << 28) | cur_block

El recuento de aciertos aproximado reduce el recuento real de aciertos a 8 categorías (basadas en AFL):

root@kitploit:~
0: 0 aciertos
1: 1 acierto
2: 2 aciertos
3: 3 aciertos
4: 4-7 aciertos
5: 8-15 aciertos
6: 16-127 aciertos
7: >=128 aciertos

Por lo tanto, cada entrada se asocia con un conjunto de enteros que representan características. Además, tiene un conjunto de "características únicas", que son características no vistas en ninguna otra entrada del corpus en el momento en que se probó la entrada.

Si una entrada tiene características únicas, entonces se agrega al corpus (NEW). Si una entrada B se creó mutando una entrada A, pero la entrada B es más corta y tiene todas las características únicas de A, entonces A se reemplaza por B en el corpus (REDUCE).

Mutación

En cada iteración, se elige una entrada aleatoria del corpus actual y luego se muta usando una secuencia de mutadores. Actualmente se implementan los siguientes mutadores (tomados de libFuzzer):

  • EraseBytes: Elimina una cantidad de bytes.
  • InsertByte: Inserta un nuevo byte aleatorio.
  • InsertRepeatedBytes: Inserta un byte aleatorio repetido varias veces.
  • ChangeByte: Reemplaza un byte por un byte aleatorio.
  • ChangeBit: Voltea un solo bit.
  • ShuffleBytes: Baraja una pequeña subcadena.
  • ChangeASCIIInt: Cambia un entero ASCII incrementando/decrementando/doblando/reduciendo a la mitad.
  • ChangeBinInt: Cambia un entero binario agregando una pequeña cantidad aleatoria.
  • CopyPart: Copia parte de la cadena en otra parte, ya sea sobrescribiendo o insertando.
  • CrossOver: Cruza con otra entrada del corpus con múltiples estrategias.
  • AddWordFromManualDictionary: Inserta o sobrescribe con una palabra del diccionario (si existe).

La mutación está sujeta a una restricción de longitud máxima. Si bien el objetivo puede especificar una longitud máxima general (setMaxLength()), el fuzzer también realiza un control automático de longitud (--len-control-factor). La longitud máxima se establece inicialmente en un valor muy bajo y luego se incrementa en log(maxlen) cada vez que no se ha realizado ninguna acción (NEW o REDUCE) durante las últimas len_control_factor * log(maxlen) ejecuciones.

Cuanto mayor sea el factor de control de longitud, más agresivamente explorará el fuzzer entradas cortas antes de permitir entradas más largas. Esto reduce significativamente el tamaño del corpus generado, pero hace que la exploración inicial sea más lenta.

Hallazgos

  • tolerant-php-parser: #305
  • PHP-CSS-Parser: #181 #182 #183 #184
  • league/uri: #150
  • amphp/http-client #236
  • amphp/hpack #8
  • phpmyadmin/sql-parser: #508 #510
  • club-1/sphinx-inventory-parser: #7
Descargar herramienta
  • t: El tiempo total transcurrido desde que se inició el fuzzer, en segundos
  • mem: El uso actual de memoria del proceso PHP