
CakePHP 5.4.2 — высокий уровень — удалённый — SQLi — COLLATE collation является необработанным фрагментом SQL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-collate-sqli
Класс: SQLi Доступ: Удалённый
CakePHP 5.4.2 (887b641) — Cake Software Foundation
StringExpression::sql привязывает строковое значение и конкатенирует collation. IdentifierExpression делает то же самое. Здесь нет ensureSimpleString. В Postgres quoteIdentifier — это '"' . trim($collation, '"') . '"', поэтому встроенная кавычка закрывает CAST раньше времени.
Приложение, которое передаёт collation из запроса/локали в new StringExpression($term, $collation), помещает эту строку в COLLATE. Значение остаётся привязанным. Collation — нет.
| ID | CVE пока нет |
| Класс | SQLi |
| Доступ | Удалённый (приложение, передающее collation/локаль в StringExpression / IdentifierExpression) |
| CWE | CWE-89 |
| CVSS | Высокий: 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) |
| Аутентификация | приложение, передающее collation/локаль в эти конструкторы |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Требуется приложение, которое передаёт collation из пользовательских данных/локали в эти конструкторы. Стандартный cakephp/app сам по себе не предоставляет collation в публичной форме.
| Привилегия | Метод / sink | Тип | Доказано в лаборатории или выведено |
|---|---|---|---|
Внедрить SQL после COLLATE | 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 ...) | Разведка БД | Доказано в лаборатории. Результат xCAKEPHP-COLLATE-SQLI-WITNESS, ошибки выполнения нет |
| Изменять строки / больше SQL с ролью соединения | Та же инъекция | Целостность БД | Выведено. Лаборатория — это SELECT-оракул |
| Негативный контроль | collation C | Закрыто | Доказано в лаборатории. Результат x, свидетеля нет, скомпилировано COLLATE "C" |
Закрыто на этом остатке: привязанное строковое значение (:c0 остаётся литералом x); collation, которое прошло бы ensureSimpleString (^[a-zA-Z0-9]+$), — это не данная полезная нагрузка. Это не неаутентифицированный RCE на скелетном приложении. Это не шелл.
Другие остатки того же пина: window SQLi, attachment CRLF, cache unserialize.
Я зафиксировал 5.4.2 после заметок о FunctionsBuilder / filename=. Десять поисков. Проход по оставшимся 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 как единственный драйвер (конкатенация реальна, выход из обёртки — это 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
ensureSimpleString() (или белый список collation) для аргумента collation. Postgres должен правильно экранировать идентификаторы, а не trim плюс обёртка.
887b641de9f7aba06071f98f17edcbc573cbcf63)StringExpression.php · IdentifierExpression.php · Postgres.phpensureSimpleString()GNU Affero GPL v3.0. См. LICENSE. Только лаборатория на loopback. Без гарантий.