Projet pédagogique — Cybersécurité Avancée — EMINES UM6P Benguerir 2026 Application intentionnellement vulnérable. Ne jamais déployer en production. Voir DISCLAIMER.md pour le cadre légal et éthique.
Application bancaire fictive (Django 4.2 / Python 3.11) conçue pour démontrer et comprendre les attaques XSS stockées avancées (Projet P02 — Red Team).
Trois variantes d'exploitation sont implémentées :
| Variante | Technique | Objectif |
|---|---|---|
| A | Keylogger JavaScript | Capturer toutes les frappes clavier de la victime |
| B | Phishing Overlay | Voler les identifiants via une fausse page de login |
| C | DOM Tampering | Détourner silencieusement un virement bancaire |
Point d'entrée XSS : backend/templates/app/messages.html — filtre |safe (ligne 65)
- Docker Desktop ≥ 24.0
- Docker Compose (inclus dans Docker Desktop)
- Ports
8000et8888libres sur votre machine
# 1. Cloner le dépôt
git clone https://github.com/RayRay-cloud/g2-cybersec.git
cd g2-cybersec
# 2. Lancer les deux services (bank + C2)
docker-compose up --build
# 3. Attendre ~30 secondes, puis ouvrir dans votre navigateur :
# Application bancaire : http://localhost:8000
# Dashboard C2 : http://localhost:8888Les migrations, le seed de la base de données et la collecte des fichiers statiques
s'exécutent automatiquement au démarrage via backend/entrypoint.sh.
| Utilisateur | Mot de passe | Nom complet | Solde initial | Rôle |
|---|---|---|---|---|
rachid |
rachid1234 |
Rachid Amrani | 12 500,00 € | Victime principale |
rayan |
rayan1234 |
Rayan Benali | 8 750,50 € | Victime secondaire |
rim |
rim1234 |
Rim Ouali | 3 200,00 € | Victime |
sara |
sara1234 |
Sara Kettani | 500,00 € | Victime |
admin |
admin1234 |
— | — | Superuser (Django Admin) |
Note : Pour jouer le rôle de l'attaquant, créez un nouveau compte via
/register/(ex. usernameattacker, mot de passeattacker1234). Un solde de 5 000 € est attribué automatiquement à tout nouveau compte.
docker-compose down # Arrêter les conteneurs (données conservées)
docker-compose down -v # Arrêter et supprimer toutes les données# Créer un environnement virtuel Python
python -m venv venv
source venv/bin/activate # Linux/macOS
# .\venv\Scripts\activate # Windows PowerShell
# Installer les dépendances du backend
cd backend
pip install -r requirements.txt
# Initialiser la base de données et le seed
python manage.py migrate
python manage.py seed_demo
python manage.py collectstatic --no-input
# Lancer Django
python manage.py runserver
# Dans un second terminal : lancer le serveur C2
cd ../attacker
pip install -r requirements.txt
python c2_server.pyg2-cybersec/
│
├── docker-compose.yml # Orchestration Docker (bank:8000 + c2:8888)
├── README.md # Ce fichier
├── DISCLAIMER.md # Avertissement légal et pédagogique
│
├── backend/ # Application Django
│ ├── Dockerfile # Image python:3.11-slim
│ ├── entrypoint.sh # Migration + seed + collectstatic au démarrage
│ ├── requirements.txt # Django 4.2, Pillow, whitenoise, crispy-forms
│ ├── manage.py
│ │
│ ├── bank_project/ # Configuration Django
│ │ ├── settings.py # ⚠️ Sécurité intentionnellement dégradée
│ │ └── urls.py
│ │
│ ├── app/ # Application principale
│ │ ├── models.py # BankAccount, Transaction, Message (vulnérable)
│ │ ├── views.py # ⚠️ messages_view sans sanitisation
│ │ ├── forms.py # MessageForm sans nettoyage HTML
│ │ └── management/commands/
│ │ └── seed_demo.py # Peuplement des données de démo
│ │
│ └── templates/
│ ├── base.html # Layout Bootstrap 5 dark theme
│ ├── registration/
│ │ ├── login.html
│ │ └── register.html
│ └── app/
│ ├── dashboard.html
│ ├── transfer.html # Cible Variante C (DOM Tampering)
│ ├── history.html
│ └── messages.html # ⚠️ POINT D'ENTRÉE XSS — filtre |safe ligne 65
│
├── attacker/ # Serveur C2 Flask
│ ├── Dockerfile
│ ├── c2_server.py # Dashboard + endpoints d'exfiltration (:8888)
│ └── requirements.txt # Flask 3.0, flask-cors
│
├── payloads/ # Payloads XSS documentés
│ ├── README.md # Guide d'utilisation des payloads
│ ├── keylogger.js # Variante A — capture des frappes clavier
│ ├── phishing.js # Variante B — overlay de phishing
│ └── dom_tamper.js # Variante C — détournement de virement
│
└── rapport/
└── rapport_p02.tex # Rapport technique LaTeX (20 pages)
Étape 1 : Démarrer le lab
docker-compose up --build -d
docker-compose ps # Vérifier que bank et c2-server sont UPÉtape 2 : Injecter le payload (rôle attaquant)
- Ouvrir
http://localhost:8000et créer un compteattacker / attacker1234 - Naviguer vers
/messages/ - Coller le contenu de
payloads/phishing.jsdans une balise<script>:<script> /* coller le contenu de phishing.js ici */ </script>
- Publier le message
Étape 3 : Déclencher l'attaque (rôle victime)
- Ouvrir un onglet privé ou un second navigateur
- Se connecter avec
rachid / rachid1234 - Naviguer vers
/messages/ - → L'overlay de phishing apparaît immédiatement
- Entrer des identifiants dans le faux formulaire
Étape 4 : Observer l'exfiltration
- Ouvrir
http://localhost:8888 - Le dashboard C2 affiche les identifiants capturés en temps réel
# 1. Trouver le numéro de compte de l'attaquant
# → http://localhost:8000/admin/ (admin / admin1234)
# → App > Comptes bancaires > sélectionner le compte attacker
# 2. Éditer payloads/dom_tamper.js
# → Remplacer REPLACE_WITH_ATTACKER_ACCOUNT_NUMBER
# par le vrai numéro de compte (format FR76...)
# 3. Injecter le payload dans /messages/ (compte attacker)
# 4. Se connecter comme victime (rachid)
# → Visiter /messages/ (active le payload)
# → Visiter /transfer/ et saisir un virement vers rayan
# 5. Observer : le virement arrive sur le compte attacker
# → C2 dashboard confirme le détournementFichier : backend/templates/app/messages.html, ligne 65
{# ⚠️ LIGNE VULNÉRABLE — |safe bypasse l'auto-échappement Django #}
<div class="message-content">{{ msg.content|safe }}</div>Fichier : backend/app/views.py, ligne 159
msg = form.save(commit=False)
msg.author = request.user
msg.save() # aucune sanitisation du contenu{# Retirer simplement le filtre |safe #}
<div class="message-content">{{ msg.content }}</div>Paramètre (settings.py) |
Valeur | Impact |
|---|---|---|
SECURE_BROWSER_XSS_FILTER |
False |
Supprime X-XSS-Protection |
X_FRAME_OPTIONS |
'ALLOWALL' |
Permet le clickjacking |
SECURE_CONTENT_TYPE_NOSNIFF |
False |
Supprime X-Content-Type-Options |
| Pas de CSP | — | Scripts externes autorisés |
DEBUG |
True |
Stack traces visibles |
AUTH_PASSWORD_VALIDATORS |
[] |
Aucune contrainte de mot de passe |
Frontend : HTML5 + Bootstrap 5.3.3 dark theme + Bootstrap Icons + Inter (Google Fonts)
Backend : Django 4.2 + SQLite (via ORM)
C2 : Flask 3.0.3 + Flask-CORS (exfiltration JSON/logs)
Docker : python:3.11-slim × 2 services, réseau bridge xss_lab
Auth : django.contrib.auth (sessions, CSRF activé)
Flux réseau :
Navigateur victime ──HTTP──► bank:8000 (Django)
│
payload JS ◄──┘
│
Image beacon / POST ──────► c2-server:8888 (Flask)
│
logs/ captured.json
- OWASP XSS Prevention Cheat Sheet
- CWE-79 : Improper Neutralization of Input
- MDN — Content Security Policy
- Django Security Documentation
- bleach — Sanitisation HTML Python
- PortSwigger Web Security Academy — XSS
Voir DISCLAIMER.md.
Les techniques présentées sont illégales si utilisées sans autorisation explicite sur des systèmes réels (loi 07-03, articles 607-3 à 607-11 du Code pénal marocain). Utilisation strictement limitée à l'environnement Docker local du lab.