2016-02-19 1 views
2

J'ai récemment trébuché à travers ce qui suit dans notre base de code:Pas sûr de concaténation de chaîne php 5.6 exploit

$func = $_GET['func'] . '_xyz123'; 
if(function_exists($func)){ 
    $result = $func($_GET); 
    echo(json_encode($result)); 
} 

Je me demande s'il serait possible de passer dans une fonction php builtin + des ordures à $_GET['func'], de sorte qu'il annulerait _xyz123 provoquant un exploit RCE. Est-ce possible, ou suis-je simplement paranoïaque?

+0

Un caractère nul pourrait le faire, mais ça me fait me demande pourquoi ils se donnent la peine. Cela semble vraiment étrange de construire un exploit, mais "impair" est la façon dont beaucoup d'exploits passent inaperçus. – samlev

+0

Un caractère \ 0 ne fera pas: https://3v4l.org/6vsmJ – VolkerK

+0

Aucun autre caractère dans la plage unicode 0x0 ... 0xFFFF: https://3v4l.org/3MlSg – trincot

Répondre

2

Il est en effet risqué de laisser ce code tel quel.

I tried pour trouver un caractère qui pourrait couper prématurément une chaîne. Mais bien que je ne trouve aucun moyen de le faire, ce n'est pas concluant, et il pourrait y avoir d'autres façons d'altérer les noms de fonctions. Comme PHP offre une syntaxe d'espace de noms (en utilisant \), cela pourrait aussi être exploité par des utilisateurs créatifs.

Mais il n'y a aucune raison de prendre le risque et de permettre à l'entrée utilisateur de contenir des caractères qui ne devraient pas apparaître dans les noms de fonctions. Les noms de fonction doivent suivre rules:

Les noms de fonctions suivent les mêmes règles que les autres libellés de PHP. Un nom de fonction valide commence par une lettre ou un trait de soulignement, suivi d'un nombre quelconque de lettres, de chiffres ou de traits de soulignement. Comme une expression régulière, il serait exprimé ainsi: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

Ainsi, vous pouvez vous assurer que tout argument qui a un caractère violant est rejeté (y compris la barre oblique inverse dans la syntaxe d'espace de noms). En utilisant l'expression régulière cité, vous pouvez le faire comme suit:

function isValidName($name) { 
    return preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $name); 
} 

$func = $_GET['func'] . '_xyz123'; 

if(isValidName($func) && function_exists($func)){ 
    $result = $func($_GET); 
    echo(json_encode($result)); 
} 

Une autre façon d'assurer l'application, est de définir toutes les fonctions qui peuvent être appelées ainsi que des méthodes statiques d'une classe. Supposons que la classe est appelée _xyz123 et vos fonctions ne doivent pas ce suffixe, le code pourrait ressembler à ceci, en utilisant method_exists:

$func = $_GET['func']; 
if(isValidName($func) && method_exists('_xyz123', $func)){ 

Ou vous pouvez définir toutes ces fonctions dans un espace de noms spécifique, par exemple _xyz123, et faire ceci:

if(isValidName($func) && function_exists('\\_xyz123\\$func')){ 
+0

Merci d'avoir enquêté! Très utile – jjb