
CakePHP 5.4.2 - 높음 - 원격 - SQLi - COLLATE 콜레이션은 원시 SQL 조각입니다
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-collate-sqli
분류: SQLi 도달 범위: 원격
CakePHP 5.4.2 (887b641) - Cake Software Foundation
StringExpression::sql은 문자열 값을 바인딩하고 콜레이션을 연결합니다. IdentifierExpression도 동일하게 동작합니다. ensureSimpleString은 없습니다. Postgres의 quoteIdentifier는 '"' . trim($collation, '"') . '"'이므로, 내장된 따옴표가 CAST를 조기에 닫습니다.
요청/로케일 콜레이션을 new StringExpression($term, $collation)으로 전달하는 앱은 그 문자열을 COLLATE에 넣습니다. 값은 바인딩된 상태로 유지됩니다. 콜레이션은 그렇지 않습니다.
| ID | 아직 CVE 없음 |
| 분류 | SQLi |
| 도달 범위 | 원격 (콜레이션/로케일을 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) |
| 인증 | 콜레이션/로케일을 해당 생성자로 전달하는 애플리케이션 |
| 라이선스 | 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, witness 없음, 컴파일된 COLLATE "C" |
이 잔여 항목에서 닫힌 것: 바인딩된 문자열 값(:c0은 리터럴 x로 유지됨); ensureSimpleString(^[a-zA-Z0-9]+$)을 통과할 콜레이션은 이 페이로드가 아님. 스켈레톤 앱에서의 비인증 RCE가 아님. 셸도 아님.
동일 핀의 잔여 항목: window SQLi, attachment CRLF, cache unserialize.
FunctionsBuilder / filename= 관련 기록 이후 5.4.2를 핀했습니다. 열 번의 추적. 남은 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)를 실행합니다. 비밀 테이블에 witness가 들어 있습니다.
SUCCESS cakephp-collate-sqli pin=5.4.2 raw=concat pg-wrap=breakout exec=yes CAKEPHP-COLLATE-SQLI-WITNESS
콜레이션 인수에 ensureSimpleString()(또는 콜레이션 허용 목록)을 적용합니다. Postgres는 trim 후 래핑이 아니라 식별자를 제대로 인용해야 합니다.
887b641de9f7aba06071f98f17edcbc573cbcf63)StringExpression.php · IdentifierExpression.php · Postgres.phpensureSimpleString()GNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.