
phpMyAdmin 5.2.3 - 高 - リモート - SQLi - ImportLdi TERMINATED BY 残存
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-importldi
Class: SQLi Reach: Remote
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 未割当 |
| Class | SQLi |
| Reach | Remote (認証済み 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 |
| Product | phpMyAdmin |
| Affected | 5.2.3 タグ RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| Auth | 認証済み Cookie ログイン。テーブルインポート、フォーマット ldi |
| License | GNU Affero GPL v3.0 |
| Lab | 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 leftover。
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 ログイン。/import に format=ldi と ldi_terminated 内のクォートを付けて 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 を参照。ループバックラボのみ。無保証。