代码审计:phpcms v9 2013-02-01 会员中心注入漏洞分

  • A+
所属分类:Seay信息安全博客

显示不全请点击全屏阅读

报告名称:phpcms v9 2013-02-01 会员中心注入漏洞分析报告

漏洞作者:skysheep

分析作者:Seay

博客:http://www.cnseay.com/

漏洞分析:

  漏洞存在于 phpcms\modules\member\index.php 文件account_manage_info函数,其功能是更新会员信息。

 

public function account_manage_info() {

       if(isset($_POST['dosubmit'])) {

           //更新用户昵称

           $nickname = isset($_POST['nickname']) && trim($_POST['nickname']) ? trim($_POST['nickname']) : '';

           if($nickname) {

              $this->db->update(array('nickname'=>$nickname), array('userid'=>$this->memberinfo['userid']));

              if(!isset($cookietime)) {

                  $get_cookietime = param::get_cookie('cookietime');

              }

              $_cookietime = $cookietime ? intval($cookietime) : ($get_cookietime ? $get_cookietime : 0);

              $cookietime = $_cookietime ? TIME + $_cookietime : 0;

              param::set_cookie('_nickname', $nickname, $cookietime);

           }

           require_once CACHE_MODEL_PATH.'member_input.class.php';

           require_once CACHE_MODEL_PATH.'member_update.class.php';

           $member_input = new member_input($this->memberinfo['modelid']);

           $modelinfo = $member_input->get($_POST['info']);

           $this->db->set_model($this->memberinfo['modelid']);

           $membermodelinfo = $this->db->get_one(array('userid'=>$this->memberinfo['userid']));

           if(!empty($membermodelinfo)) {

              $this->db->update($modelinfo, array('userid'=>$this->memberinfo['userid']));

           } else {

              $modelinfo['userid'] = $this->memberinfo['userid'];

              $this->db->insert($modelinfo);

           }

代码中:$modelinfo = $member_input->get($_POST[‘info’]);取得提交上来的会员模型中的字段,我们跟进member_input类中的get()函数看看,

在\caches\caches_model\caches_data\ member_input.class.php 文件中:

 

function get($data) {

       $this->data = $data = trim_script($data);

       $model_cache = getcache('member_model', 'commons');

       $this->db->table_name = $this->db_pre.$model_cache[$this->modelid]['tablename'];

       $info = array();

       $debar_filed = array('catid','title','style','thumb','status','islink','description');

       if(is_array($data)) {

           foreach($data as $field=>$value) {

              if($data['islink']==1 && !in_array($field,$debar_filed)) continue;

              $name = $this->fields[$field]['name'];

              $minlength = $this->fields[$field]['minlength'];

              $maxlength = $this->fields[$field]['maxlength'];

              $pattern = $this->fields[$field]['pattern'];

              $errortips = $this->fields[$field]['errortips'];

              if(empty($errortips)) $errortips = "$name 不符合要求!";

              $length = empty($value) ? 0 : strlen($value);

              if($minlength && $length < $minlength && !$isimport) showmessage("$name 不得少于 $minlength 个字符!");

              if($maxlength && $length > $maxlength && !$isimport) {

                  showmessage("$name 不得超过 $maxlength 个字符!");

              } else {

                  str_cut($value, $maxlength);

              }

              if($pattern && $length && !preg_match($pattern, $value) && !$isimport) showmessage($errortips);

                if($this->fields[$field]['isunique'] && $this->db->get_one(array($field=>$value),$field) && ROUTE_A != 'edit') showmessage("$name 的值不得重复!");

              $func = $this->fields[$field]['formtype'];

              if(method_exists($this, $func)) $value = $this->$func($field, $value);

              $info[$field] = $value;

           }

       }

       return $info;

    }

trim_script函数是过滤XSS的,上面get函数一段代码干的事就是取提交上来的字段和值重新赋值到数组,

 

再到phpcms\modules\member\index.php 文件account_manage_info函数

过了get()函数之后。

$modelinfo = $member_input->get($_POST['info']);

           $this->db->set_model($this->memberinfo['modelid']);

           $membermodelinfo = $this->db->get_one(array('userid'=>$this->memberinfo['userid']));

           if(!empty($membermodelinfo)) {

              $this->db->update($modelinfo, array('userid'=>$this->memberinfo['userid']));

           } else {

直接带入数据库,update函数我们跟进看看

public function update($data, $table, $where = '') {

       if($table == '' or $where == '') {

           return false;

       }

       $where = ' WHERE '.$where;

       $field = '';

       if(is_string($data) && $data != '') {

           $field = $data;

       } elseif (is_array($data) && count($data) > 0) {

           $fields = array();

           foreach($data as $k=>$v) {

              switch (substr($v, 0, 2)) {

                  case '+=':

                     $v = substr($v,2);

                     if (is_numeric($v)) {

                         $fields[] = $this->add_special_char($k).'='.$this->add_special_char($k).'+'.$this->escape_string($v, '', false);

                     } else {

                         continue;

                     }

                     break;

                  case '-=':

                     $v = substr($v,2);

                     if (is_numeric($v)) {

                         $fields[] = $this->add_special_char($k).'='.$this->add_special_char($k).'-'.$this->escape_string($v, '', false);

                     } else {

                         continue;

                     }

                     break;

                  default:

                     $fields[] = $this->add_special_char($k).'='.$this->escape_string($v);

              }

           }

           $field = implode(',', $fields);

       } else {

           return false;

       }

       $sql = 'UPDATE `'.$this->config['database'].'`.`'.$table.'` SET '.$field.$where;

       print_r($sql);

       return $this->execute($sql);

    }

从头到尾也是没有验证数据库是否存在数组中的字段,然后直接执行SQL语句。也就是说SQL语句中的字段我们可控,导致注入。

 

攻击测试:

测试地址http://localhost

  注册会员seay并登陆。打开firebug工具HTML选项。修改birthday的name值为注入语句
1

Tags:

phpcmsv9漏洞,

如果您喜欢我的博客,欢迎点击图片定订阅到邮箱填写您的邮件地址,订阅我们的精彩内容: 也可以点击链接【订阅到鲜果】

如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡
代码审计:phpcms v9 2013-02-01 会员中心注入漏洞分