
phpMyAdmin 5.2.3 - 高 - リモート - SQLi - ImportLdi TERMINATED BY 残存
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-importldi
解説記事: https://abraxaslabs.tech/research/phpmyadmin-importldi
クラス: SQLi 到達範囲: リモート
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
ImportLdi.php は、POST パラメータ ldi_terminated と ldi_new_line から FIELDS/LINES TERMINATED BY を含む LOAD DATA を組み立てます。これら 2 つの文字列は、シングルクォートで囲まれた SQL に連結されます。ldi_enclosed と ldi_escaped は escapeString を経由します。phpMyAdmin は /import で PMA_ENABLE_LDI を設定するため、MYSQLI_OPT_LOCAL_INFILE が有効になります。
サインイン済みのユーザーが format=ldi を POST し、ldi_terminated にクォートを含めます。発行される LOAD DATA には、TERMINATED BY の中に生の POST 値が含まれます。制御用ユーザーではなく、ユーザー接続への SQL インジェクションです。
| ID | CVE 未割当 |
| クラス | SQLi |
| 到達範囲 | リモート (認証済み Cookie ログイン、テーブルインポート、フォーマット ldi) |
| CWE | CWE-89 |
| CVSS | Medium: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| 製品 | phpMyAdmin |
| 影響を受けるバージョン | 5.2.3 タグ RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| 認証 | 認証済み Cookie ログイン。テーブルインポート、フォーマット ldi |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
テーブルインポートを開けるサインイン済みの phpMyAdmin ユーザーは、自身の MySQL 接続上で LOAD DATA ... TERMINATED BY に SQL を注入できます。
| 権限 | メソッド / シンク | 偵察 / 整合性 / 可用性 | ラボ実証または推測 |
|---|---|---|---|
FIELDS TERMINATED BY リテラルを破壊 | POST index.php?route=/import format=ldi ldi_terminated にクォート | PMA が組み立てるステートメントの整合性 | ラボ実証済み。HTML の SQL ボックス: TERMINATED BY '',PMA-IMPORTLDI-WITNESS' |
ENCLOSED BY をイン・バンドに保つ | 同じ POST、ldi_enclosed にクォート | ネガティブコントロール | ラボ実証済み。ENCLOSED BY はエスケープされる |
| ユーザー接続上での追加 SQL (INTO OUTFILE / 許可されていればスタック) | 文字列を閉じた後の同じシンク | ユーザー接続の整合性 | 推測。ラボは壊れたデリミタで停止。デフォルトの mysqli::query は単一ステートメント |
| MySQL 側のファイル読み書き | アカウントが FILE または Web サーバーへの LOCAL INFILE を持つ場合の同じ LOAD DATA | mysqld が触れられるファイルの整合性 | 推測。ここでは付与されていない。主張しない |
このラボで除外済み: 未認証アクセス、制御用ユーザー / pmadb、OS の include LFI、FILE で制限される読み書き。サインイン済みユーザーはすでに SQL ボックスを持っており、この残存問題は PMA がそのユーザーのために組み立てるステートメント内のエスケープされないデリミタです。
同じピン: WebAuthn CustomServer の残存問題。
phpMyAdmin RELEASE_5_2_3 をピン留めしました。LOAD DATA を手作業で組み立てるインポートプラグインはクォート処理の監査対象です。4 つのデリミタフィールドのうち 2 つはエスケープされていました。2 つはされていませんでした:
$sql .= ' FIELDS TERMINATED BY \'' . $ldi_terminated . '\'';
...
$sql .= ' LINES TERMINATED BY \'' . $ldi_new_line . '\'';
ldi_enclosed / ldi_escaped は $dbi->escapeString を呼び出します。Common.php は /import + format=ldi で PMA_ENABLE_LDI を設定します。ルートは GET|POST /import と GET|POST /table/import です。
すでに記録済みの誤った方向性: FILE 権限なしで LFI を主張すること。SQL ボックスを発見事項として扱うこと(残存物は PMA が連結するエスケープされていない区切り文字です)。制御ユーザー / pmadb を主張すること。リバースシェル。すべて見せかけです。
python3 phpmyadmin-importldi-Abraxas-Labs.py
# or: cd lab && ./run.sh
対象は http://127.0.0.1:19290 のみです。イメージは phpmyadmin:5.2.3 と mysql:8.0 です。Compose プロジェクトは phpmyadmin-importldi です。実行後、スタックは破棄されます。
Cookie ログイン。format=ldi と ldi_terminated 内のクォートを指定して /import に POST します。LOAD DATA LOCAL INFILE ... INTO TABLE \ldi_target` FIELDS TERMINATED BY '',PMA-IMPORTLDI-WITNESS'が発行されました。同じクォートをldi_enclosedに指定すると、エスケープされたENCLOSED BYとして保存されます。5.2.3 イメージ上のピン留めされたソースには、依然として'.$ldi_terminated.'と$dbi->escapeString($ldi_enclosed)` が含まれています。
SUCCESS phpmyadmin-importldi pin=RELEASE_5_2_3 how=live TERMINATED-BY-raw ENCLOSED-escaped PMA-IMPORTLDI-WITNESS
ldi_terminated と ldi_new_line に対して escapeString を適用し、enclosed および escaped の場合と同じにする。skip_queries を int キャストする。
962857e4f63d42e38f11ff4d63f5e722018add76)libraries/classes/Plugins/Import/ImportLdi.phpGNU Affero GPL v3.0。LICENSE を参照。ループバックラボ専用。保証なし。