
CakePHP 5.4.2 – Hoch – Remote – SQLi – COLLATE-Kollation ist ein rohes SQL-Fragment
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-collate-sqli
Write-up: https://abraxaslabs.tech/research/cakephp-collate-sqli
Klasse: SQLi Reichweite: Remote
CakePHP 5.4.2 (887b641) - Cake Software Foundation
StringExpression::sql bindet den String-Wert und hängt die Collation an. IdentifierExpression macht dasselbe. Es gibt kein ensureSimpleString. Postgres' quoteIdentifier ist '"' . trim($collation, '"') . '"', sodass ein eingebettetes Anführungszeichen CAST vorzeitig schließt.
Eine App, die Request-/Locale-Collation in new StringExpression($term, $collation) weiterreicht, setzt diesen String in COLLATE. Der Wert bleibt gebunden. Die Collation nicht.
| ID | noch keine CVE |
| Klasse | SQLi |
| Reichweite | Remote (App, die Collation/Locale in StringExpression / IdentifierExpression weiterreicht) |
| CWE | CWE-89 |
| CVSS | Hoch: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produkt | CakePHP (cakephp/database) |
| Betroffen | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | Anwendung, die Collation/Locale in diese Konstruktoren weiterreicht |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Erfordert eine Anwendung, die Benutzer-/Locale-Collation in diese Konstruktoren übergibt. Das Standard-cakephp/app legt die Collation nicht von sich aus über ein öffentliches Formular offen.
| Berechtigung | Methode / Sink | Art | Im Lab nachgewiesen oder abgeleitet |
|---|---|---|---|
SQL nach COLLATE einschleusen | StringExpression::sql verkettet $this->collation | Integrität des kompilierten SQL | Im Lab nachgewiesen. Rohes SQL enthält die Payload ungebunden |
| Derselbe Einschub bei Identifikatoren | IdentifierExpression note COLLATE <payload> | Integrität des kompilierten SQL | Im Lab nachgewiesen. id_raw_sql enthält die Payload |
Ausbruch aus der Postgres-"..."-Umhüllung | quoteIdentifier = '"' . trim($collation, '"') . '"' | Integrität des kompilierten SQL | Im Lab nachgewiesen. Kompiliertes SQL ist COLLATE "C" AS text)) || (SELECT ... |
| Den Ausbruch ausführen und eine andere Tabelle lesen | CAST(... ) || (SELECT note FROM lab_secret ...) | Recon der DB | Im Lab nachgewiesen. Ergebnis xCAKEPHP-COLLATE-SQLI-WITNESS, kein Exec-Fehler |
| Zeilen ändern / mehr SQL mit der Verbindungsrolle | Dieselbe Injection | Integrität der DB | Abgeleitet. Das Lab ist ein SELECT-Oracle |
| Negativkontrolle | Collation C | Geschlossen | Im Lab nachgewiesen. Ergebnis x, kein Witness, kompiliert COLLATE "C" |
Geschlossen bei diesem Rest: gebundener String-Wert (:c0 bleibt das Literal x); eine Collation, die ensureSimpleString (^[a-zA-Z0-9]+$) passieren würde, ist nicht diese Payload. Kein unauthentifiziertes RCE auf einer Skeleton-App. Keine Shell.
Weitere Reste desselben Pins: window SQLi, attachment CRLF, cache unserialize.
Ich habe 5.4.2 nach den Notizen zu FunctionsBuilder / filename= gepinnt. Zehn Jagden. Der Durchgang zu verbleibendem SQLi ist dieser. StringExpression::sql:
$placeholder = $binder->placeholder('c');
$binder->bind($placeholder, $this->string, 'string');
return $placeholder . ' COLLATE ' . $this->collation;
Postgres quoteIdentifier schließt mit ASCII-Anführungszeichen ein und verwendet trim($collation, '"'). Ein eingebettetes " schließt den Bezeichner. -- verschluckt den übrig gebliebenen Abschluss, den Cake dennoch anhängt.
Bereits festgehaltene Fehlannahmen: SQLite als einziger Treiber (die Verkettung ist real, der Wrap-Breakout ist Postgres); der gebundene Wert als die Injection; die Behauptung, ensureSimpleString sei hier bereits gelaufen (das ist nicht der Fall); eine Reverse Shell. Theater.
python3 cakephp-collate-sqli-Abraxas-Labs.py
oder
cd lab
./run.sh
Ziele nur http://127.0.0.1:19450. cakephp/database 5.4.2 plus Postgres 16. Eine kleine App leitet ?collation= in StringExpression / IdentifierExpression weiter und führt CAST(... AS text) aus. Eine geheime Tabelle enthält den Zeugen.
SUCCESS cakephp-collate-sqli pin=5.4.2 raw=concat pg-wrap=breakout exec=yes CAKEPHP-COLLATE-SQLI-WITNESS
ensureSimpleString() (oder eine Collation-Allowlist) für das Collation-Argument. Postgres muss Bezeichner ordnungsgemäß quoten, nicht trim plus Umhüllung.
887b641de9f7aba06071f98f17edcbc573cbcf63)StringExpression.php · IdentifierExpression.php · Postgres.phpensureSimpleString()GNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.