
CakePHP 5.4.2 - 高 - リモート - SQLi - COLLATE照合順序は生のSQLフラグメントです
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-collate-sqli
解説記事: https://abraxaslabs.tech/research/cakephp-collate-sqli
クラス: SQLi 到達性: リモート
CakePHP 5.4.2 (887b641) - Cake Software Foundation
StringExpression::sql は文字列値をバインドし、照合順序 (collation) を連結します。IdentifierExpression も同様です。ensureSimpleString は存在しません。Postgres の quoteIdentifier は '"' . trim($collation, '"') . '"' であるため、埋め込まれた引用符が CAST を早期に閉じてしまいます。
リクエストやロケールの照合順序を new StringExpression($term, $collation) に転送するアプリは、その文字列を COLLATE に挿入してしまいます。値はバインドされたままですが、照合順序はバインドされません。
| ID | CVE 未割当 |
| クラス | SQLi |
| 到達性 | リモート (照合順序/ロケールを StringExpression / IdentifierExpression に転送するアプリ) |
| CWE | CWE-89 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 製品 | CakePHP (cakephp/database) |
| 影響を受けるバージョン | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| 認証 | 照合順序/ロケールをこれらのコンストラクタに転送するアプリケーション |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
ユーザー/ロケールの照合順序をこれらのコンストラクタに渡すアプリケーションが必要です。素の cakephp/app は、それ自体では公開フォームで照合順序を公開していません。
| 権限 | メソッド / シンク | 種類 | ラボ実証または推測 |
|---|---|---|---|
COLLATE の後に SQL を挿入 | StringExpression::sql が $this->collation を連結 | コンパイル済み SQL の整合性 | ラボ実証済み。生 SQL にペイロードがバインドされずに含まれる |
| 識別子でも同様の挿入 | IdentifierExpression の note COLLATE <payload> | コンパイル済み SQL の整合性 | ラボ実証済み。id_raw_sql にペイロードが含まれる |
Postgres の "..." ラップから脱出 | quoteIdentifier = '"' . trim($collation, '"') . '"' | コンパイル済み SQL の整合性 | ラボ実証済み。コンパイル済み SQL は COLLATE "C" AS text)) || (SELECT ... |
| 脱出を実行して別テーブルを読み取る | CAST(... ) || (SELECT note FROM lab_secret ...) | DB の偵察 | ラボ実証済み。結果は xCAKEPHP-COLLATE-SQLI-WITNESS、実行エラーなし |
| 接続ロールで行を変更 / 追加の SQL を実行 | 同じインジェクション | DB の整合性 | 推測。ラボは SELECT オラクル |
| ネガティブコントロール | 照合順序 C | クローズ | ラボ実証済み。結果は x、ウィットネスなし、コンパイル結果は COLLATE "C" |
この残存項目についてクローズ済み: バインドされた文字列値 (:c0 はリテラル x のまま); ensureSimpleString (^[a-zA-Z0-9]+$) を通過する照合順序はこのペイロードではありません。スケルトンアプリに対する未認証 RCE ではありません。シェルではありません。
同じピン留めからの残存項目: window SQLi、attachment CRLF、cache unserialize。
FunctionsBuilder / filename= のメモの後、5.4.2 にピン留めしました。10 回の調査。残存 SQLi のパスがこれです。StringExpression::sql:
$placeholder = $binder->placeholder('c');
$binder->bind($placeholder, $this->string, 'string');
return $placeholder . ' COLLATE ' . $this->collation;
Postgres の quoteIdentifier は ASCII 引用符で囲み、trim($collation, '"') を適用します。埋め込まれた " は識別子を閉じてしまいます。-- は残った閉じ引用符を飲み込み、Cake は依然としてそれを付加します。
すでに記録済みの誤った方向性: SQLite を唯一のドライバとする見方(concat は実際に存在し、wrap-breakout は Postgres のもの); バインドされた値をインジェクションとみなすこと; ensureSimpleString がここで既に実行されたと主張すること(実行されていない); リバースシェル。茶番です。
python3 cakephp-collate-sqli-Abraxas-Labs.py
または
cd lab
./run.sh
必ず http://127.0.0.1:19450 のみを対象とすること。cakephp/database 5.4.2 と Postgres 16 を使用。小さなアプリが ?collation= を StringExpression / IdentifierExpression に転送し、CAST(... AS text) を実行する。シークレットテーブルに証人が格納されている。
SUCCESS cakephp-collate-sqli pin=5.4.2 raw=concat pg-wrap=breakout exec=yes CAKEPHP-COLLATE-SQLI-WITNESS
collation 引数に対する ensureSimpleString()(または collation の許可リスト)。Postgres は識別子を適切にクォートする必要があり、trim とラップの組み合わせでは不十分です。
887b641de9f7aba06071f98f17edcbc573cbcf63)StringExpression.php · IdentifierExpression.php · Postgres.phpensureSimpleString()GNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。