Par Geluchat, ven. 06 février 2015, dans la catégorie Journal de geluchat
Après les SQL truncations, passons à l'étude de son homologue PHP, les PATH truncations.
Pour comprendre le problème, revenons à la base de la construction du moteur PHP. PHP est basé sur le moteur Zend engine écrit en C, il dispose donc des contraintes mémoires et de la gestion parfois chaotique de la mémoire liée à ce langage.
Il parait donc tout à fait naturel que pour palier à ce problème les créateurs de ce langage aient dû s'orienter vers une gestion simplifiée de la mémoire paradoxalement au PHP qui est lui-même un langage très faiblement typé
Passons donc au vif du sujet, les strings PHP, jusqu’à la version 5.3, peuvent supporter une chaîne de longueur maximum égal à 2^12 soit 4096 caractères.
Que se passe-t-il si l'on dépasse cette limite?
Eh bien, PHP tronque tout simplement la chaîne. Comme à l’accoutumé, voici un exemple pour illustrer le principe et mettre en avant le problème:
if(isset($_GET['path']) && !preg_match('/\x00/im',$_GET['path']))
{
include($_GET['path'].".php");
}
Ce code comporte une LFI, on peut inclure n’importe quel fichier PHP ou lire le code via les wrappers php.
De plus, le null byte étant filtré, on ne peut pas inclure un fichier qui ne comporte pas l'extension .php
Comment faire?
C'est là qu'intervient la PATH truncation, si l'on envoie une chaîne supérieure à 4096 le .php ne sera pas ajouter à la fin.
A ce moment vous êtes sûrement en train de vous poser des questions sur l’intérêt d'une telle faille. En effet, comment une chaîne de plus de 4096 pourrait contenir notre chemin qui fait entre 50 et 100 caractères.
En fait, la solution est très simple, il suffit d'analyser comment PHP fonctionne.
PHP cherche à interpréter une chaîne basique:
include("admin.php");
Il va tout d'abord chercher le fichier admin.php puis l'inclure, cette procédure, rappelons-le, utilise des fonctions du langage C.
Le C possède des conditions d'accès au fichier et de recherche de chemin très poussé et adaptative, il suffit donc de trouver un bypass fonctionnant en C.
Après quelques recherches on résout le problème:
/etc/passwd/./././././././././././././[4096 plus tard]/.
Qui est traduit par:
include("/etc/passwd");
Note:
De plus, veillez bien à regarder la taille du chemin, elle doit rester impaire, admin.php fait 9 caractères, mais admin.php3 en fait 10. Cela implique que vous devez équilibrer le nombre de caractères du chemin sinon la troncation ne se fera pas correctement (par exemple: x/../admin.php3) Sous Windows on peut exploiter via les points (admin.php.............[4096]............)
On a donc complètement bypass la pseudo vérification d'extension mise en place par le programmeur.
Il faut bien sûr retenir de cette faille qu'elle n'est disponible que sur les versions inférieurs à 5.3 .
Pour patcher cette faille il suffit donc tout simplement de mettre à jour son PHP par une version supérieure à la 5.3 .
Voilà, c’est déjà terminé, n’hésitez pas à rejoindre mon Twitter pour avoir des news sur le site et mon point de vue sur l’actualité de la sécurité informatique.
Geluchat.