Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
PHP-Fuzzer — Fuzzer guidé par la couverture d'arêtes pour bibliothèques PHP qui détecte les bugs via des plantages, des dépassements de temps et des avertissements. Prend en charge la gestion du corpus, la minimisation des plantages et les rapports de couverture de code. | Kitploit
Outils/GitHubGitHub/nikic/php-fuzzer
Analyse Dynamique (Sandboxing)Analyse des VulnérabilitésAnalyse de CodeFuzzing
GitHubnikic/php-fuzzer

PHP-Fuzzer

Fuzzer guidé par la couverture d'arêtes pour bibliothèques PHP qui détecte les bugs via des plantages, des dépassements de temps et des avertissements. Prend en charge la gestion du corpus, la minimisation des plantages et les rapports de couverture de code.

Voir le dépôt
4411843il y a 8 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Fuzzer PHP

Cette bibliothèque implémente un fuzzer pour PHP, qui peut être utilisé pour trouver des bugs dans des bibliothèques (notamment les bibliothèques d'analyse syntaxique) en leur fournissant des entrées « aléatoires ». Les retours de l'instrumentation de couverture par arête sont utilisés pour guider le choix des entrées « aléatoires », de manière à visiter de nouveaux chemins de code.

Installation

Phar (recommandé) : Vous pouvez télécharger un package phar de cette bibliothèque depuis la page des versions. L'utilisation du phar est recommandée car elle évite les conflits de dépendances avec les bibliothèques utilisant PHP-Parser.

Composer : composer global require nikic/php-fuzzer

Utilisation

Tout d'abord, une définition de la fonction cible est nécessaire. Voici un exemple de cible pour trouver des bugs dans microsoft/tolerant-php-parser :

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

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

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

// Required: The target accepts a single input string and runs it through the tested
//           library. The target is allowed to throw normal Exceptions (which are ignored),
//           but Error exceptions are considered as a found bug.
$parser = new Microsoft\PhpParser\Parser();
$config->setTarget(function(string $input) use($parser) {
    $parser->parseSourceFile($input);
});

// Optional: Many targets don't exhibit bugs on large inputs that can't also be
//           produced with small inputs. Limiting the length may improve performance.
$config->setMaxLen(1024);
// Optional: A dictionary can be used to provide useful fragments to the fuzzer,
//           such as language keywords. This is particularly important if these
//           cannot be easily discovered by the fuzzer, because they are handled
//           by a non-instrumented PHP extension function such as token_get_all().
$config->addDictionary('example/php.dict');

Le fuzzer est exécuté sur un corpus d'entrées initiales « intéressantes », qui peuvent par exemple être générées à partir de tests unitaires existants. Si aucun corpus n'est spécifié, un répertoire de corpus temporaire sera créé à la place.

root@kitploit:~
# Run without initial corpus
php-fuzzer fuzz target.php
# Run with initial corpus (one input per file)
php-fuzzer fuzz target.php corpus/

Si le fuzzing est interrompu, il peut être repris ultérieurement en spécifiant le même répertoire de corpus.

Une fois qu'un crash a été trouvé, il est écrit dans un fichier crash-HASH.txt. Il est fourni sous la forme où il a été trouvé initialement, ce qui peut être inutilement complexe et contenir des fragments non pertinents pour le crash. Ainsi, vous souhaiterez probablement réduire l'entrée qui provoque le crash en premier lieu :

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

Cela produira une séquence de fichiers minimized-HASH.txt de plus en plus petits. Si vous souhaitez vérifier rapidement la trace d'exception produite pour une entrée provoquant un crash, vous pouvez utiliser la commande run-single :

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

Enfin, il est possible de générer un rapport de couverture de code HTML, qui montre quels blocs de code dans la cible sont touchés lors de l'exécution d'entrées d'un corpus donné :

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

De plus, les options de configuration peuvent être affichées avec php-fuzzer --help.

Pendant son exécution, le fuzzer rapporte son état en continu sur une seule ligne de sortie. Cette ligne comprend les parties suivantes dans cet ordre :

  1. NEW ou REDUCED : L'action qui a déclenché cette ligne de statut. NEW indique qu'une nouvelle entrée a été ajoutée au corpus tandis que REDUCED indique qu'une entrée existante du corpus a été remplacée par une entrée plus courte.
  2. run: N : Le nombre total d'itérations de fuzzing (exécutions de cible) effectuées depuis le démarrage du fuzzer.
  3. (N/s) : La vitesse d'exécution actuelle, mesurée en runs par seconde.
  4. ft: N : Le nombre total de caractéristiques uniques découvertes jusqu'à présent.
  5. (N/s) : Le nombre moyen de nouvelles caractéristiques découvertes par seconde depuis le démarrage du fuzzer.
  6. corp: N : Le nombre d'entrées intéressantes actuellement stockées dans le corpus.
  7. (%s) : La taille totale de toutes les entrées dans le corpus.
  8. len: %d/%d : Le premier nombre est la longueur (en octets) de l'entrée actuelle qui a déclenché l'action, le second nombre est la longueur maximale autorisée actuelle.
  9. t : Le temps total écoulé depuis le démarrage du fuzzer, en secondes.
  10. mem : L'utilisation mémoire actuelle du processus PHP.

Types de bugs

Le fuzzer détecte par défaut trois types de bugs :

  • Les exceptions Error levées par la cible de fuzzing. Alors que les exceptions Exception sont considérées comme un résultat normal pour une entrée malformée, les exceptions Error non capturées indiquent toujours une erreur de programmation. Elles sont le plus souvent produites par PHP lui-même, par exemple lors de l'appel d'une méthode sur null.
  • Les notices et warnings levés (sauf s'ils sont supprimés). Le fuzzer enregistre un gestionnaire d'erreurs qui les convertit en exceptions Error.
  • Les dépassements de délai. Si la cible s'exécute plus longtemps que le délai spécifié (par défaut : 3s), on suppose que la cible est entrée dans une boucle infinie. Cela est réalisé en utilisant pcntl_alarm() et un gestionnaire de signal asynchrone qui lève une exception Error au délai dépassé.

Notamment, aucun de ces contrôles ne vérifie si la sortie de la cible est correcte, ils déterminent seulement que la cible ne se comporte pas de manière gravement erronée. Une façon de vérifier la correction de la sortie est de comparer deux implémentations différentes censées produire des résultats identiques :

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!');
    }
});

Technique

La plupart des détails techniques de ce fuzzer sont basés sur libFuzzer du projet LLVM. Ce qui suit décrit certains détails d'implémentation.

Instrumentation

Pour fonctionner efficacement, le fuzzing nécessite un retour sur les chemins de code qui ont été exécutés lors du test d'une entrée de fuzzing particulière. Ce retour de couverture est collecté en « instrumentant » la cible de fuzzing. La bibliothèque include-interceptor est utilisée pour transformer le code de tous les fichiers inclus à la volée. La bibliothèque PHP-Parser est utilisée pour analyser le code et trouver tous les endroits où du code d'instrumentation supplémentaire doit être inséré.

Dans chaque bloc de base, le code suivant est inséré, où BLOCK_INDEX est un entier unique par bloc :

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

Cela suppose que l'index de bloc est au maximum sur 28 bits et compte le nombre de paires (prev_block, cur_block) observées lors de l'exécution. Le code généré est malheureusement assez coûteux, en raison de la nécessité de gérer les compteurs d'arêtes non initialisés et de l'utilisation de propriétés statiques. À l'avenir, il serait possible de créer une extension PHP qui pourrait collecter le retour de couverture beaucoup plus efficacement.

Dans certains cas, les blocs de base font partie d'expressions, auquel cas nous ne pouvons pas insérer facilement du code supplémentaire. Dans ces cas, nous insérons à la place un appel à une méthode qui contient le code ci-dessus :

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

À l'avenir, il serait bénéfique d'instrumenter également les comparaisons, afin de pouvoir déterminer automatiquement les entrées de dictionnaire à partir de comparaisons comme $foo == "SOME_STRING".

Caractéristiques

Les entrées de fuzzing sont considérées comme « intéressantes » si elles contiennent de nouvelles caractéristiques qui n'ont pas été observées avec d'autres entrées déjà présentes dans le corpus. Cette bibliothèque utilise des compteurs de hits d'arêtes à granularité grossière comme caractéristiques :

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

Le nombre de hits approximatif réduit le nombre réel de hits à 8 catégories (basées sur AFL) :

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

Ainsi, chaque entrée est associée à un ensemble d'entiers représentant des caractéristiques. De plus, elle possède un ensemble de « caractéristiques uniques », qui sont des caractéristiques non vues dans aucune autre entrée du corpus au moment où l'entrée a été testée.

Si une entrée a des caractéristiques uniques, elle est ajoutée au corpus (NEW). Si une entrée B a été créée par mutation d'une entrée A, mais que B est plus courte et possède toutes les caractéristiques uniques de A, alors A est remplacée par B dans le corpus (REDUCE).

Mutation

À chaque itération, une entrée aléatoire du corpus courant est choisie, puis mutée à l'aide d'une séquence de mutateurs. Les mutateurs suivants (tirés de libFuzzer) sont actuellement implémentés :

  • EraseBytes : Supprime un certain nombre d'octets.
  • InsertByte : Insère un nouvel octet aléatoire.
  • InsertRepeatedBytes : Insère un octet aléatoire répété plusieurs fois.
  • ChangeByte : Remplace un octet par un octet aléatoire.
  • ChangeBit : Inverse un seul bit.
  • ShuffleBytes : Mélange une petite sous-chaîne.
  • ChangeASCIIInt : Modifie un entier ASCII en l'incrémentant/décrémentant/doublant/divisant par deux.
  • ChangeBinInt : Modifie un entier binaire en ajoutant une petite quantité aléatoire.
  • CopyPart : Copie une partie de la chaîne dans une autre partie, soit en écrasant soit en insérant.
  • CrossOver : Croisement avec une autre entrée du corpus avec plusieurs stratégies.
  • AddWordFromManualDictionary : Insère ou écrase avec un mot du dictionnaire (s'il y en a un).

La mutation est soumise à une contrainte de longueur maximale. Bien qu'une longueur maximale globale puisse être spécifiée par la cible (setMaxLength()), le fuzzer effectue également un contrôle automatique de la longueur (--len-control-factor). La longueur maximale est initialement définie à une valeur très basse, puis augmentée de log(maxlen) chaque fois qu'aucune action (NEW ou REDUCE) n'a été prise depuis les len_control_factor * log(maxlen) dernières exécutions.

Plus le facteur de contrôle de longueur est élevé, plus le fuzzer explorera agressivement les entrées courtes avant d'autoriser des entrées plus longues. Cela réduit considérablement la taille du corpus généré, mais rend l'exploration initiale plus lente.

Résultats

  • 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
Télécharger l’outil