La faille nullbyte

Auteur : palkeo
Créé le : le 15/11/2008 à 14:50
Visualisations : 3678
Ce tutoriel est composé des parties suivantes :

Introduction

La faille nullbyte consiste à injecter un caractère nul dans un paramètre pour que la fin de ce paramètre ne soit pas prise en compte, ce qui peut permettre de contourner des protections.

Qu'est-ce que c'est ?

Prenons l'exemple d'un système d'include non sécurisé :
Code : index.php
include($_GET['page'] . '.inc');
Ainsi, si on envoie "index.php?page=forums", le script inclura forums.inc.
Si on souhaite utiliser la faille include, on sera limité, puisqu'on pourra inclure seulement des fichier ayant l'extension inc. Et il suffit que le script bloque les URL absolues pour qu'on ne puisse plus faire grand chose…

Détrompez-vous, il est possible d'inclure des fichiers ayant n'importe quelle extension !
Il suffit simplement d'injecter un caractère nul !
Devant vos visages ébahis, je crois qu'une petite explication s'impose :))

Dans un ordinateur, une chaîne de caractères (une variable contenant du texte, si vous préférez), est représentée par un tableau (une suite) de nombres. Et chaque nombre correspond a un caractère (par exemple la lettre "a" a pour code 97).
Étant donné qu'une chaîne de caractère peut changer de taille (en fonction du nombre de lettres), on définit donc un grand tableau, de 200 "cases" par exemple, qui pourra donc contenir une chaîne de caractère de 1 à 199 caractères (non, pas 200, vous verrez pourquoi ;) ).
Le problème, c'est qu'il faut bien savoir quand la chaîne finit :
Si la chaîne fait seulement 20 caractères, on va pas afficher une chaîne de 200 caractères avec des résidus illisibles se trouvant dans les 180 "cases" restantes…
Pour cela, on a inventé un système tout simple : Pour savoir quand une chaîne finit, on ajoute à le fin un caractère nul, ayant pour code 0. Dès qu'on rencontre ce caractère, ça veut dire que la chaîne est terminée. Il faut donc prévoir un espace supplémentaire, ce qui explique qu'une chaîne de 200 "cases" ne peut contenir que 199 caractères :)
Hé bien figurez-vous que si une fonction PHP reçoit un paramètre qui contient un caractère nul, elle croit que c'est la fin de la chaîne et ne prend pas ce qui suit en compte !

Si vous n'avez pas bien compris le principe, vous pouvez lire ceci. Bien sûr, sur cette page, c'est uniquement la théorie qui peut aider à comprendre.

Notez aussi qu'il est aussi possible d'envoyer au programme une chaîne de caractère plus grande que la taille maximum attendue (dans l'exemple précédent, on pourrait prendre une chaîne de 300 caractères, alors qu'on en attend 200 au maximum), ce qui aura pour effet d'écrire par dessus de la mémoire dédié à autre chose.
Si la mémoire à cet endroit contient du code exécutable, on pourra faire exécuter du code malveillant par le programme. Cet attaque s'appelle le « buffer overflow » (« dépassement de tampon »).
Mais je m'égare, là :o)

Revenons à nos moutons nullbytes :
Dans notre exemple : si on envoie "index.php?page=test.php%00" on obtiendra ça :
Code : PHP
include('test.php\0.inc');
Le %00, dans le protocole HTTP, veut dire qu'on insère le caractère de code 00 c'est a dire le caractère nul. Idem dans le code PHP, la notation n'est simplement pas la même.
Bref, donc la fonction include() lira le paramètre, verra le caractère nul inséré par le client… et croira que c'est la fin de la chaîne, donc ignorera le ".inc" !

Exploitation

Comme nous venons de le voir, ce problème de sécurité est principalement utilisé pour tronquer une chaîne.
Combiné à la faille include, cette technique peut donc être très pratique !
Elle peut aussi être utilisée avec d'autres fonctions manipulant les fichiers.

Protection

Pour vous protéger, c'est très simple : Il suffit de regarder si la chaîne envoyée contient un caractère null :
Code : PHP
if(strpos($_GET['page'],'\0') !== false)
 die('Tentative d\'attaque nullbyte !');
Attention, c'est "!==", car la fonction strpos doit retourner false pour continuer.
Si on mettait "!=" la fonction pourrait aussi retourner 0, par exemple, et le script continuerait, car 0 est considéré comme équivalent à false.

Conclusion

Ainsi, cette faille peut être très pratique pour inclure des fichiers n'ayant pas l'extension prévue.
Toutefois, ne sombrez pas dans la paranoïa : Les possibilités d'exploitation sont assez restreintes !