sajjit.soti
← Retour aux projets

Étude de cas — Test d’intrusion en équipe, EPITA

Test d’intrusion web : quatorze failles, une seule chaîne de compromission

Une équipe de quatre personnes a mené un test d’intrusion en boîte grise sur une application web municipale (portail citoyen), avec un accès authentifié de départ (rôle « chef »). L’objectif n’était pas de trouver des failles isolées, mais de voir jusqu’où une seule chaîne de petites erreurs pouvait mener — la réponse fut : jusqu’à l’exécution de code à distance et à un accès complet à la base de données.

14

Vulnérabilités identifiées et prouvées

2 + 9

Failles critiques + failles élevées

<1 s

Temps de cassage du hash admin extrait

Critique

Niveau de risque global évalué

Réalisé avec Aimen Daddi, Oladapo Banjo-Obaleye et Yahya Borghol.

01

La chaîne complète, étape par étape

Chaque étape de cette évaluation part d’un défaut mineur en apparence et l’enchaîne avec le suivant. Aucune des techniques utilisées n’est exotique — c’est précisément ce qui la rend instructive : ce sont les erreurs les plus banales, empilées, qui ont fait tomber l’application.

1. Un mot de passe « caché » à la ROT13

La page de configuration CCTV valide le mot de passe entièrement côté client, en JavaScript. Le mot de passe encodé (ebg13vfxrl) est visible directement dans le code source de la page — un décodage ROT13 donne rot13iskey. Un premier signal : la logique de sécurité vit côté navigateur, pas côté serveur.

2. Élévation de privilèges via des cookies non signés

L’application identifie les utilisateurs via des cookies (login, id_user) sans aucune signature cryptographique. Connecté en tant que « chef », il suffit de modifier ces cookies dans les outils de développement du navigateur — sans exploit, sans injection — pour rafraîchir la page avec un accès administrateur complet.

3. Upload de fichier non restreint → exécution de code à distance

Une fois admin, le module de gestion des articles accepte des pièces jointes en filtrant uniquement sur l’extension du fichier. Un fichier nommé php-jpeg-shell.jpg.php passe le filtre — la double extension trompe la vérification — et le serveur exécute le script PHP téléversé comme du code, exactement comme n’importe quel autre fichier .php du site.

# Le filtre ne vérifie que l'extension "visible", pas le vrai type MIME
# ni si le fichier contient plusieurs extensions.
Fichier envoyé : php-jpeg-shell.jpg.php
Résultat serveur : exécuté comme du PHP → shell web fonctionnel
Commande testée : ?cmd=ipconfig → sortie système renvoyée dans la réponse HTTP

4. Identifiants de base de données trouvés en clair

Avec un accès shell via le fichier téléversé, il a suffi de parcourir l’arborescence du serveur pour trouver include/mysql.php, contenant les identifiants de connexion à la base de données en clair — un accès direct à toutes les données de l’application, sans passer par l’interface web.

5. Un second chemin indépendant : injection SQL

Séparément, le paramètre id de la page de configuration CCTV était vulnérable à une injection SQL de type UNION, permettant d’extraire directement le hash du mot de passe administrateur. Ce hash MD5, non salé, a été cassé en moins d’une seconde avec Hashcat — deux chemins totalement différents menaient au même niveau de compromission, un signe que la faiblesse n’était pas ponctuelle mais systémique.

6. Manipulation de paramètre → fraude financière

Le module de paiement des impôts locaux détermine le montant à payer via un paramètre d’URL, jamais revalidé côté serveur. Modifier montant=200 en montant=0 (ou une valeur négative) suffit à marquer une facture comme payée, voire à créditer un solde.

02

Le reste de la chaîne de failles

Quatre autres défauts complètent le tableau, chacun ouvrant sa propre porte :

  • XSS stockée dans la messagerie. Un message contenant <script>alert(document.cookie)</script> s’exécute dès que l’administrateur le consulte, exposant son cookie de session.
  • CSRF sur la suppression de messages. Les suppressions passent par une simple requête GET sans jeton — une page piégée peut forcer la suppression de messages d’une victime connectée.
  • IDOR sur la boîte de réception. Changer id_user dans l’URL permet de lire les messages privés de n’importe quel autre compte, admin compris.
  • Sauvegarde publique et identifiants en clair dans le code. Une archive de sauvegarde complète de la base de données était accessible publiquement dans /backup/, protégée par un mot de passe trivial (« hack »), et des identifiants admin/agent/chef traînaient en clair dans des commentaires HTML visibles par un simple « Afficher le code source ».

L’ensemble du site transitait en plus par du HTTP non chiffré : même sans exploiter une seule des failles ci-dessus, un simple écoute réseau (Wireshark) suffisait à intercepter identifiants et jetons de session en clair.

03

La cause racine commune

Quatorze failles distinctes, mais une seule cause qui revient sans cesse : faire confiance au client. Un cookie que le navigateur peut modifier, une extension de fichier vérifiée sans regarder le contenu réel, un montant de paiement lu depuis l’URL, un mot de passe validé en JavaScript — dans chaque cas, une décision de sécurité qui n’aurait jamais dû quitter le serveur avait été déléguée au navigateur de l’utilisateur. La recommandation centrale du rapport tient en une phrase : toute décision de sécurité doit être revalidée côté serveur, sans exception.