
CakePHP 5.4.2 - 높음 - 원격 - 역직렬화 - 캐시 엔진이 클래스 허용 목록 없이 객체를 역직렬화함
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-cache-unserialize
Class: Object injection Reach: Remote (Redis/Memcached write) / Local (FileEngine)
CakePHP 5.4.2 (887b641) - Cake Software Foundation
5.3.7에서 이러한 이유로 Redis allowedClasses가 추가되었지만, 하위 호환성을 위해 기본값은 true(모두 허용)로 남겨졌습니다. RedisEngine은 해당 기본값이 유지되는 한 여전히 순수한 unserialize()를 호출합니다. FileEngine에는 허용 목록이 전혀 없습니다. MemcachedEngine은 여전히 serialize의 기본값을 php로 둡니다.
Redis에서 cake_ 키를 SET할 수 있거나 캐시 파일을 작성할 수 있는 사람은 직렬화된 객체를 심습니다. 다음 Cache::read(또는 CacheSession 로드)가 PHP 워커에서 이를 실행합니다.
| ID | 아직 CVE 없음 |
| Class | Object injection |
| Reach | Redis 또는 Memcached가 공격자로부터 쓰기 가능할 때 Remote. tmp/cache의 FileEngine의 경우 Local. |
| CWE | CWE-502 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (캐시 저장소에 대한 쓰기 필요). FileEngine은 AV:L. |
| Product | CakePHP |
| Affected | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | 캐시 저장소에 대한 쓰기(Redis SET, Memcached set 또는 캐시 파일). 잠긴 localhost Redis에 대한 비인증 HTTP가 아님. |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 전용 |
앱 캐시에 직렬화된 객체를 심습니다. 다음 읽기가 워커에서 PHP를 실행합니다. 이 랩은 witness 파일에서 멈춥니다. 가젯 체인이나 셸을 시연하지 않습니다.
랩에서 입증됨 (무결성)
cake_<key> 후 Cache::read. 기본 접두사는 cake_입니다. RedisEngine unserialize()는 allowedClasses가 기본값 true일 때 순수한 unserialize($value)를 사용합니다. LabMarker로 인스턴스화된 심어진 LabMarker 객체와 __wakeup이 PHP UID로 witness 파일을 작성했습니다.{expiry}\n{serialize($obj)}를 심음. FileEngine::get()은 여전히 순수한 unserialize($data)를 호출합니다. 동일한 마커, 동일한 witness. 파일명은 prefix에 키를 더한 것(cake_labfile)입니다.allowedClasses => false는 객체를 거부함. 동일한 Redis 페이로드가 __PHP_Incomplete_Class로 반환되었습니다. __wakeup이 실행되지 않았습니다. witness 파일이 없었습니다.추론됨 (여기서 실행되지 않음)
defaults => cache일 때 CacheSession::read는 동일한 싱크입니다. 모든 세션 로드가 공격자 제어 캐시 바이트의 unserialize가 됩니다.serialize => php**는 동일한 부류의 버그입니다. 이 랩은 Memcached를 시작하지 않았습니다.종료됨 / 이 잔여물이 아님
cakephp/app에 대한 비인증 HTTP.allowedClasses => false(또는 엄격한 목록)는 운영자가 설정하면 이미 객체를 차단합니다. 기본값이 아닙니다.동일 핀 잔여물: window SQLi, collate SQLi, attachment CRLF.
2026 FunctionsBuilder / jsonValue / Smtp CRLF / View element 물결 이후 cakephp/cakephp 5.4.2를 핀했습니다. RedisEngine은 옵션을 문서화하면서도 여전히 기본값을 열어 둡니다:
* - `allowedClasses` ... Defaults to `true` (allow all) for backwards compatibility.
...
'allowedClasses' => true,
읽기 경로:
protected function unserialize(string $value): mixed
{
if (preg_match('/^[-]?\d+$/', $value)) {
return (int)$value;
}
$allowedClasses = $this->getConfig('allowedClasses');
if ($allowedClasses !== true) {
return unserialize($value, ['allowed_classes' => $allowedClasses]);
}
return unserialize($value);
}
FileEngine에는 동등한 옵션이 없습니다:
if ($data !== '' && !empty($this->_config['serialize'])) {
$data = unserialize($data);
이미 기록된 잘못된 방향: 잠긴 localhost Redis를 비인증 HTTP RCE로 취급; 가젯 체인 제공; FileEngine이 원격이라고 주장; 리버스 셸. 연극. 오라클은 플래그 파일을 작성하는 마커 __wakeup입니다.
python3 cakephp-cache-unserialize-Abraxas-Labs.py
또는
cd lab
./run.sh
오직 127.0.0.1:19470만 대상으로 합니다. Docker 내부의 태그 5.4.2에서 가져온 라이브 CakePHP 5.4.2. 호스트가 SET할 수 있도록 protected-mode가 꺼진 Redis 7. ext-redis가 있는 PHP 8.3. /tmp/CAKEPHP-CACHE-UNSERIALIZE-WITNESS를 작성하는 __wakeup이 있는 마커 클래스 LabMarker. 셸 없음.
SUCCESS cakephp-cache-unserialize redis-default-wakeup=yes redis-denied-wakeup=no file-wakeup=yes pin=5.4.2 sha=887b641de9f7aba06071f98f17edcbc573cbcf63 how=live CAKEPHP-CACHE-UNSERIALIZE-WITNESS
Redis allowedClasses의 기본값을 false로, 또는 앱이 실제로 저장하는 클래스의 엄격한 목록으로 설정합니다. FileEngine에 동일한 옵션을 추가하고 get()에서 이를 준수합니다. Memcached serialize의 기본값을 json으로 설정합니다. CacheSession이 캐시 엔진의 unserialize 정책을 상속한다는 것을 문서화합니다.
887b641de9f7aba06071f98f17edcbc573cbcf63)RedisEngine.php · FileEngine.phpGNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.