CakePHP 5.1.14 反序列化POP链挖掘与分析
概述
本文详细分析了CakePHP 5.1.14最新版本中的两条反序列化POP(Property-Oriented Programming)链,这些链可用于实现远程代码执行(RCE)。文章包含完整的调用链分析、调试过程以及两个不同的利用链构造方法。
背景
CakePHP框架在3.x和4.x版本中已知的反序列化漏洞入口点vendor\symfony\process\Process.php在5.1.14版本中已被修复,新增了__wakeup方法限制,直接抛出异常阻止了旧链的利用。
第一条POP链分析
1. 寻找destruct入口
在Internal/RejectedPromise.php类中发现了可利用的__destruct入口:
public function __destruct() {
if ($this->handled) {
return;
}
$handler = set_rejection_handler(null);
if ($handler === null) {
$message = 'Unhandled promise rejection with ' . $this->reason;
\error_log($message);
return;
}
try {
$handler($this->reason);
} catch (\Throwable $e) {
\preg_match('/^([^:\s]++)(.*+)$/sm', (string) $e, $match);
\assert(isset($match[1], $match[2]));
$message = 'Fatal error: Uncaught ' . $match[1] . ' from unhandled promise rejection handler' . $match[2];
\error_log($message);
exit(255);
}
}
关键点:
$this->handled默认为false,无需设置$this->reason完全可控- 当
set_rejection_handler(null)返回null时,会触发$this->reason的__toString方法
2. 寻找toString方法
全局搜索__toString魔术方法,发现\Ast\Type\ConstTypeNode类:
public function __toString(): string {
return $this->constExpr->__toString();
}
这里$constExpr可控,可以触发任意对象的__toString方法。
3. 寻找__call方法
通过__toString可以触发__call魔术方法。在vendor\cakephp\cakephp\src\ORM\Table.php中:
// 只要让_behaviors属性拥有method方法就可以调用call方法
4. 寻找call方法调用
在vendor\cakephp\cakephp\src\ORM\BehaviorRegistry.php中找到关键调用:
public function call(string $method, array $args = []): mixed {
$method = strtolower($method);
if ($this->hasMethod($method) && $this->has($this->_methodMap[$method][0])) {
[$behavior, $callMethod] = $this->_methodMap[$method];
return $this->_loaded[$behavior]->{$callMethod}(...$args);
}
throw new BadMethodCallException(
sprintf('Cannot call `%s`, it does not belong to any attached behavior.', $method),
);
}
关键点:
$this->hasMethod($method)检查方法是否存在$this->has($this->_methodMap[$method][0])检查行为是否存在$this->_methodMap和$this->_loaded属性可控- 可以动态调用任意方法
5. 寻找RCE终点
通过分析找到src\Framework\MockObject\Generator\MockClass类中的generate方法:
// mockName需要放一个存在的类名即可进入if
// 属性classCode可控,里面可以用php代码实现RCE
注意事项:
- 需要寻找无参函数或有默认参数的函数
- PHP版本限制:
- ≥7.1.0:有参函数不能无参调用,会报Fatal error
- ≤7.0.33:有参函数可以无参调用,但有警告
第二条POP链分析
替代toString点
在src/cakephp-5-1-4/vendor/cakephp/cakephp/src/Http/Response.php中也发现了可以触发__call方法的点。
利用链构造
第一条链的EXP构造要点
- 需要实现
MockType接口 mockName属性需要设置为存在的类名classCode属性包含PHP代码实现RCE
第二条链的POC构造
(原文中未提供完整POC,需要进一步分析Response.php中的利用点)
防御建议
- 避免反序列化不可信数据
- 更新到最新版本并关注安全公告
- 实现
__wakeup方法进行完整性检查 - 使用类型严格比较
总结
本文详细分析了CakePHP 5.1.14中两条新的反序列化POP链,从__destruct入口到RCE终点的完整调用过程。这些链利用了框架内部的行为注册机制和动态方法调用特性,展示了现代PHP框架中反序列化漏洞的复杂利用方式。