
「DEF CON 32 - SQLインジェクションは死んでいない - プロトコルレベルでのクエリのスマグリング - Paul Gerste」のPoC
ログイン機能を備えたシンプルなWebアプリケーションです。管理者のみがログインできます。
このアプリケーションはPostgreSQLとpgx v5.5.3(脆弱性のあるバージョン)を使用しています。
攻撃者はユーザーテーブルに悪意のあるレコードを挿入してログインを試みます。ただし、プレースホルダが使用されているため、従来のSQLインジェクションは成立しません。
PostgreSQL メッセージ形式: https://www.postgresql.org/docs/17/protocol-message-formats.html
このエクスプロイトは、SQL実行時にpgxがデータベースサーバーへ送信するメッセージ形式に依存します。
デフォルトでは、pgxは P(Parse) で準備文を送信し、その後 B(Bind) でパラメータを送信します。
以下の設定を行うと、pgxは Q(Query) で補間されたクエリを送信します:
cfg.ConnConfig.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
実際のメッセージは、tcpdump の -X オプションを使用して確認できます。
Q_simple.py: Q(Query) でオーバーフローを引き起こします。攻撃者が実行中のクエリを完全に把握していることを前提とします(ブラックボックスの場合は総当たりが必要です)。Q_nop_sled.py: Q(Query) でオーバーフローを引き起こします。5回以内の試行でエクスプロイトに成功します。B_simple.py: B(Bind) でオーバーフローを引き起こします。攻撃者が実行中のクエリを完全に把握していることを前提とします(私の見解では、ブラックボックスシナリオでの B(Bind) のエクスプロイトは困難です)。