Ce que tu vas faire
Une injection SQL arrive quand un programme fabrique une question pour la base de données en collant dans son texte ce qu’un visiteur a tapé. Le visiteur peut alors terminer la question plus tôt et écrire la sienne. Tu vas faire des recherches dans une petite boutique, faire en sorte que sa page de recherche affiche des données qu’elle ne devrait pas montrer, corriger la ligne de code qui le permet, et montrer que l’attaque ne marche plus.
La règle à retenir
Attention
Ce lab fait tourner un site web vulnérable exprès. Attaque-le, lui et rien d’autre. C’est ta copie privée, sans accès à l’internet : personne d’autre ne peut être touché. N’essaie jamais ces choses sur un site qui n’est pas à toi. Au Royaume-Uni, c’est une infraction pénale selon le Computer Misuse Act 1990.
Avant de commencer
Remarque
Appuie sur Démarrer le lab dans la barre en haut de cette leçon et attends qu’il indique qu’il tourne. La boutique est le service appelé app, et le terminal l’atteint par ce nom. Chaque bouton Exécuter ci-dessous tape sa commande dans le terminal de ton lab, l’une après l’autre, dans la même session. Pour les voir agir, ou pour taper tes propres commandes, appuie sur Ouvrir le terminal (nouvel onglet) dans la barre.
1. Cherche dans la boutique
La recherche de la boutique est une adresse web. curl -s la demande, et -G --data-urlencode met ce que tu cherches après l’adresse, en protégeant les guillemets et les espaces. Si tu cherches pen, une seule ligne s’affiche, Pen 1.2 : le nom et le prix.
curl -s -G --data-urlencode "q=pen" http://app:8000/searchAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
2. Sors de la question
Dans le programme, ta recherche est collée entre deux guillemets simples. Un guillemet dans ta recherche les termine trop tôt. OR 1=1 est vrai pour chaque ligne, et -- transforme le reste de la question en commentaire. La boutique liste alors sept produits, dont Staff discount card et Unreleased drone, qui ne sont pas en vente et ne devraient jamais s’afficher. La même astuce avec UNION SELECT peut interroger une tout autre table. Essaie toi-même : la boutique a une table users.
curl -s -G --data-urlencode "q=x' OR 1=1 --" http://app:8000/searchAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
3. Corrige la ligne
Le programme est dans le conteneur, et la ligne faible est celle qui commence par rows =. Elle colle ta recherche dans la question avec +. Une requête paramétrée envoie séparément à la base la question et ta recherche. Ce que tu as tapé ne peut donc jamais être qu’une valeur, jamais un morceau de la question. Le ? marque la place de la valeur, et la recherche est passée à côté. Pour le faire à la main, ouvre le programme avec docker exec -it app vi /tmp/app/app.py et remplace cette ligne (i pour écrire, Esc puis :wq pour enregistrer). La commande suivante fait la même modification à ta place, avec cette ligne :
rows = db.execute("SELECT name, price FROM products WHERE public = 1 AND name LIKE ?", ("%" + term + "%",)).fetchall()
4. Fais la modification et redémarre
Cette commande remplace cette seule ligne. La boutique lit son programme une seule fois, au démarrage, donc docker restart lance la nouvelle version. Cela prend environ dix secondes, puis app s’affiche. Si le bouton indique qu’il tourne encore, attends de voir app dans le terminal avant de continuer.
docker exec app sed -i 's|^ rows = .*| rows = db.execute("SELECT name, price FROM products WHERE public = 1 AND name LIKE ?", ("%" + term + "%",)).fetchall()|' /tmp/app/app.pyAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
docker restart appAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
5. Attaque de nouveau
La même attaque qu’à l’étape 2 n’affiche maintenant plus rien du tout : la base a cherché un produit dont le nom contient tout x' OR 1=1 --, et il n’y en a aucun.
curl -s -G --data-urlencode "q=x' OR 1=1 --" http://app:8000/searchAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
6. Vérifie que l’usage normal marche encore
Une correction qui casse la boutique n’est pas une correction. lab-check essaie une recherche normale, une recherche de Baker's (un produit qui a un guillemet dans son nom, ce qui faisait échouer le programme vulnérable avec une erreur de base de données), les attaques OR et UNION, puis affiche PASS ou FAIL pour chacun. Les quatre disent PASS et la dernière ligne est All checks pass. Appuie sur Arrêter le lab puis sur Démarrer le lab dans la barre du lab, et relance la vérification : ta correction est toujours là, parce que le programme vit dans un volume nommé et que la plateforme enregistre les volumes.
docker exec app sh /tmp/app/lab-checkAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Pour les enseignants
Astuce
Cette leçon est un petit exemple de leçon travaillée dans un lab : les étapes et les boutons Exécuter forment la leçon, et le lab est la copie de chaque élève. Rien ici ne se corrige tout seul : l’élève rend l’attaque avant et après, le dernier lab-check et la ligne qu’il a changée, avec sa propre phrase pour expliquer pourquoi elle est sûre, et tu corriges les preuves. Copie la leçon dans ton propre module et modifie-la, ou crée-en une depuis zéro avec le menu Lab de l’éditeur de leçons.