ThinkSNS2.5前台getshell+后台任意文件删除

12年爆出的一个洞 前几天比赛的一个cms  于是跟出题人表哥要过来审计了看看

 

漏洞文件再根目录thumb.php中

 1 <?php
 2 /*
 3  * 自动缩略图 参数 url|w|h|type="cut/full"|mark="text/image|r"
 4  * thumb.php?url=/thinksns/data/userface/000/00/00/41_middle_face.jpg?1247718988&w=20&h=20
 5 */
 6 error_reporting(0);
 7 set_time_limit(30);
 8 $biggest_memory_limit    =    256; //单位M,后缀不要加M
 9 //全局定义文件
10 //require 'define.inc.php';
11 
12 //临时目录
13 $tempDir    =    "./data/thumb_temp/";
14 checkDir($tempDir);
15 
16 //分析URL
17 $url    =    urldecode($_GET['url']);
18 
19 //XSS脚本攻击探测
20 //include THINK_PATH.'/Vendor/xss.php';
21 //DetectXSS($url);
22 
23 //2009-10-7 修改 将本地图片修改成相对地址,避免file_get_contents不能读取远程文件时出错(可修改php.ini  设置 allow_fopen_url 为 true)
24 //$url =  str_ireplace(SITE_URL,'.',$url);
25 if(file_exists($url)){
26     $url    =    $url;
27     
28 }elseif($result    =    GrabImage($url,$tempDir)){
29     $url    =    $result;
30     $grab_temp_file    =    $result;
31 }else{
32     $url    =    "./public/images/nopic.jpg";
33 }
34 
35 //解析参数
36 $w = $_GET['w']?$_GET['w']:'100';    //宽度
37 $h = $_GET['h']?$_GET['h']:'100';    //高度
38 $t = $_GET['t']?$_GET['t']:'c';        //是否切割
39 $r = $_GET['r']?'1':'0';            //是否覆盖
40 
41 
42 
43 //目录名hash
44 $fileHash    =    md5($url.$w.$h);
45 $hashPath    =    substr($fileHash,0,2).'/'.substr($fileHash,2,2).'/';
46 
47 //缩图目录
48 $thumbDir    =    "./data/thumb/".$hashPath;
49 checkDir($thumbDir);
50 
51 $tempFile    =    $tempDir.$fileHash.'.'.$sourceInfo['type'];
52 
53 $thumbFile    =    $thumbDir.$fileHash."_".$w."_".$h."_".$t.'.'.$sourceInfo['type'];
54 
55 $img        =    new Image();
56 //判断是否替换,存在则跳转,不存在继续进行
57 if(!$r && file_exists($thumbFile)){
58     //这里有2种方法,第一种多一次跳转,多一个http连接数,第二种,要进行一次php处理,多占用一部分内存。
59     //header('location:'.$thumbFile);
60     $img->showImg($thumbFile);
61 }
62 
63 //不存在输出
64 if(copy($url,$tempFile)){
65     //判断图片大小 如果图片宽和高都小于要缩放的比例 直接输出
66     $info    =    getimagesize($tempFile);
67 
68     //判断处理图片大约需要的内存
69     $need_memory    =    (($info[0]*$info[1])/100000);
70     $memory_limit    =    ini_get('memory_limit');
71     if( ($need_memory > $memory_limit) && ($need_memory <= $biggest_memory_limit) ){
72         ini_set('memory_limit',$need_memory.'M');
73     }
74 
75     if($info[0]<=$w && $info[1]<=$h){
76         
77         copy($tempFile,$thumbFile);
78         $img->showImg($thumbFile,'',$info[0],$info[1]);
79         unlink($tempFile);
80         unlink($grab_temp_file);
81         exit;
82     }
83     else{
84 
85         //生成缩图
86         if($t=='c'){
87             $thumb    =    $img->cutThumb($tempFile,$thumbFile,$w,$h);
88         }elseif($t=='f'){
89             $thumb    =    $img->thumb($tempFile,'',$thumbFile,$w,$h);
90         }
91         //输出缩图
92         $img->showImg($thumb,'',$w,$h);
93         unlink($tempFile);
94         unlink($grab_temp_file);
95         exit;
96     }
97 }

第17行获取了url参数

第28行进入了GrabImage函数

//获取远程图片
function GrabImage($url,$thumbDir) {
    if($url=="")    return false;
    $filename    =    md5($url).strrchr($url,".");
    $img        =    file_get_contents($url);
    if(!$img)        return false;

    $filepath    =    $thumbDir.$filename;
    $result        =    file_put_contents($filepath,$img);
    if($result){
        return $filepath;
    }else{
        return false;
    }
}

获取url参数的内容  并写入了filepath中截取了一下

./data/thumb_temp/7588534a6998ec36787cf997e688a8d6
第53行 重新构造文件名
$thumbFile
= $thumbDir.$fileHash."_".$w."_".$h."_".$t.'.'.$sourceInfo['type'];

这里$t传入.php

第77行 完成了复制的操作

copy($tempFile,$thumbFile);

导致了getshell 

 

 

在后台数据库导入的地方

 1     function import(){
 2         $filename = $_GET['filename'];
 3         $sqldump = '';
 4         $file = './data/database/'.$filename;
 5         //die($file);
 6         if(file_exists($file)){
 7             
 8             $fp = @fopen($file,'rb');
 9             $sqldump = fread($fp,filesize($file));
10             
11             fclose($fp);
12         }
13         
14         $ret = D('Database')->import($sqldump);
15         if($ret) {
16             $this->success('导入成功');
17         }else{
18             $this->error('导入失败');
19         }
20     }

首先文件名没有进行过滤  可以遍历读取到东西之后进入了另外一个import函数

跟进一下

    public function import($sqldump){
        $sqlquery = $this->splitsql($sqldump);
        var_dump($sqlquery);
        $ret = false;
        $linkid = $this->db->connect();
            foreach($sqlquery as $sql) {
                $sql = trim($sql);
                if(!empty($sql)) {
                        $ret = mysql_query($sql);
                    }
             }
        return $ret;
    }

没有过滤 逐行执行

但是没有上传功能呀 怎么办呢

在前台头像上传的地方

    function upload(){
        
        @header("Expires: 0");
        @header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
        @header("Pragma: no-cache");
        $pic_id = time();//使用时间来模拟图片的ID.           
        $pic_path = $this->getSavePath().'/original.jpg';
        $pic_abs_path = __UPLOAD__.'/avatar'.convertUidToPath($this->uid).'/original.jpg';
        //保存上传图片.
        if(empty($_FILES['Filedata'])) {
            $return['message'] = L('photo_upload_failed');
            $return['code']    = '0';
        }else{
        
            $file = @$_FILES['Filedata']['tmp_name'];
            //die($pic_path);
            file_exists($pic_path) && @unlink($pic_path);
            if(@copy($_FILES['Filedata']['tmp_name'], $pic_path) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $pic_path)) 
            {
                @unlink($_FILES['Filedata']['tmp_name']);
                /*list($width, $height, $type, $attr) = getimagesize($pic_path);
                if($width < 10 || $height < 10 || $width > 3000 || $height > 3000 || $type == 4) {
                    @unlink($pic_path);
                    return -2;
                }*/
                include( SITE_PATH.'/addons/libs/Image.class.php' );
                Image::thumb( $pic_path, $pic_path , '' , 300 , 300 );
                list($sr_w, $sr_h, $sr_type, $sr_attr) = @getimagesize($pic_path);
                
                $return['data']['picurl'] = 'data/uploads/avatar'.convertUidToPath($this->uid).'/original.jpg';
                $return['data']['picwidth'] = $sr_w;
                $return['data']['picheight'] = $sr_h;
                $return['code']    = '1';
            } else {
                @unlink($_FILES['Filedata']['tmp_name']);
                $return['message'] = L('photo_upload_failed');
                $return['code']    = '0';
            }
            
        }
        return json_encode( $return );
    }

大体意思就是没检测文件内容 也不管后缀是什么 读取出文件内容  统一写入一个固定的文件

我们在这里写入要执行的sql语句这里我想到的利用方法

1.留xss后门

执行一个update或者insert语句  在用户管理的表中  后台查看用户就会触发xss 这里绕过了前台的过滤持续控制后台

2.因为并没有回显

 可以执行update 或者insert语句 在插入文章的

INSERT INTO `ts_ad` (`title`,`place`,`is_active`,`content`,`is_closable`,`mtime`,`ctime`) VALUES ('31',0,'0',user(),0,1502120589,1502120589)

进一步获取服务器敏感信息

3 如果有root权限可以写shell

4有时间可以尝试下时间盲注

 

同时删除的地方可以进行任意文件删除

转载于:https://www.cnblogs.com/test404/p/7302516.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值