Rapport méthodologique — AWSGoat Module 2¶
Analyste : Jean
Cible : AWSGoat Module 2 (application HR Payroll — conteneur awsgoat-m2-web)
Date : 24 juillet 2026
Contexte¶
Analyse du fichier payslips.php de l'application admin AWSGoat M2, révélant une chaîne d'exploitation complète : bypass d'authentification par injection SQL, suivi d'une élévation de privilèges par IDOR menant à une prise de contrôle de compte (account takeover) sur le compte super-admin.
1. Reconnaissance initiale — Lecture du code source¶
Constat : Le paramètre uid, utilisé dans les requêtes UPDATE de mise à jour de profil, provient de $_REQUEST['uid'] et n'est jamais comparé à $_SESSION['id']. Absence de contrôle d'autorisation applicative (broken access control).
2. Identification des conteneurs de l'environnement¶
Constat : Base de données séparée dans le conteneur awsgoat-m2-db (MySQL 8.0).
3. Récupération des identifiants de connexion base de données¶
4. Énumération des comptes utilisateurs¶
Constat : Hiérarchie de privilèges identifiée — isadmin=2 (super-admin), isadmin=1 (admin RH), isadmin=0 (utilisateur standard).
5. Extraction des hashs de mots de passe (tentative)¶
docker exec -it awsgoat-m2-db mysql -u root -p appdb -e "SELECT id, username, password FROM users WHERE id IN (2,3);"
Constat : Hashs MD5 non salés (cohérent avec md5($password) observé dans le code applicatif).
6. Tentative de cassage par dictionnaire (piste abandonnée)¶
Tentative de cassage MD5 via CrackStation puis via script Python avec dictionnaire rockyou.txt.
Résultat : Aucune correspondance. Piste abandonnée au profit d'une vulnérabilité plus directe identifiée dans login.php.
7. Analyse du mécanisme d'authentification¶
Constat : Requête SQL de login construite par concaténation directe du paramètre email, sans échappement ni requête préparée — injection SQL confirmée sur le formulaire de connexion.
8. Récupération de l'email cible pour le bypass¶
docker exec -it awsgoat-m2-db mysql -u root -p appdb -e "SELECT id, username, email FROM users WHERE id IN (2,3);"
9. Bypass d'authentification par injection SQL¶
Payload injecté dans le champ email du formulaire de login :
Résultat : Authentification réussie en tant que Terry (id=2, isadmin=1) sans connaissance du mot de passe. La clause -- - commente la vérification du mot de passe dans la requête SQL.
10. Interception de la requête de mise à jour de profil légitime¶
Capture via DevTools navigateur (onglet Network) de la requête POST vers admin-index.php déclenchée par le formulaire Settings, afin d'identifier la structure du paramètre uid et les champs du formulaire.
11. Exploitation de l'IDOR — modification d'un compte tiers¶
Invoke-WebRequest -Uri "http://localhost/admin/admin-index.php" -Method POST -UseBasicParsing -Headers @{Cookie="PHPSESSID=<session_terry>"} -Body @{uid="1";inputfirstname="Terry";inputlastname="IDORTEST";inputphone="";inputEmail="terry@inefinextech.com";inputAddress="<adresse_terry>";inputssn="<ssn_terry>";inputbank="";inputnewPassword="";inputcnfPassword="";submit=""}
Résultat : Requête envoyée avec la session de Terry (isadmin=1) mais un uid=1 ciblant le compte de chris (isadmin=2, super-admin).
12. Vérification en base de l'IDOR¶
docker exec -it awsgoat-m2-db mysql -u root -p appdb -e "SELECT id, first_name, last_name FROM users_info WHERE id=1;"
Résultat : Confirmation — le compte id=1 (chris) a été modifié par un utilisateur non autorisé (Terry). IDOR validé : un admin de niveau isadmin=1 peut altérer les données d'un compte isadmin=2.
13. Escalade vers account takeover — prise de contrôle du mot de passe¶
Invoke-WebRequest -Uri "http://localhost/admin/admin-index.php" -Method POST -UseBasicParsing -Headers @{Cookie="PHPSESSID=<session_terry>"} -Body @{uid="1";inputfirstname="Terry";inputlastname="IDORTEST";inputphone="";inputEmail="terry@inefinextech.com";inputAddress="<adresse_terry>";inputssn="<ssn_terry>";inputbank="";inputnewPassword="<nouveau_mdp>";inputcnfPassword="<nouveau_mdp>";submit=""}
14. Vérification finale — confirmation du takeover¶
docker exec -it awsgoat-m2-db mysql -u root -p appdb -e "SELECT id, username, password FROM users WHERE id=1;"
Résultat : Hash MD5 du compte chris modifié, correspondant au nouveau mot de passe injecté. Prise de contrôle complète du compte super-admin confirmée.
Synthèse de la chaîne d'exploitation¶
| Étape | Vulnérabilité | Impact |
|---|---|---|
| 1 | Injection SQL — login.php (champ email, requête non préparée) |
Bypass d'authentification |
| 2 | IDOR — admin-index.php/payslips.php (paramètre uid non vérifié vs. session) |
Élévation de privilèges horizontale/verticale |
| 3 | Absence de contrôle sur le changement de mot de passe via le même IDOR | Account takeover total |
Chemin d'attaque résumé : authentification bypassée par SQLi → accès admin de niveau intermédiaire → exploitation de l'IDOR pour cibler un compte de privilège supérieur → écrasement du mot de passe → prise de contrôle totale du compte super-admin, sans authentification légitime à aucune étape.
Recommandations¶
- Requêtes préparées (paramétrées) sur tous les points d'entrée SQL, notamment
login.php. - Vérification systématique de l'appartenance de la ressource à l'utilisateur courant (
$_SESSION['id']vs.uidreçu) avant toute opération UPDATE. - Contrôle d'accès basé sur les rôles (RBAC) empêchant un
isadmin=1d'agir sur unisadmin=2. - Hachage des mots de passe avec un algorithme adapté (bcrypt/argon2) et sel, en remplacement de MD5 non salé.
Fin du rapport — session AWSGoat Module 2.