opensns前台无限制Getshell

public function uploadPictureBase64()
    {

        $aData = $_POST['data'];

        if ($aData == '' || $aData == 'undefined') {
            $this->ajaxReturn(array('status'=>0,'info'=>'²ÎÊý´íÎó'));
        }

        if (preg_match('/^(data:*image/(+);base64,)/', $aData, $result)) {
            $base64_body = substr(strstr($aData, ','), 1);

            empty($aExt) && $aExt = $result[2];
        } else {
            $base64_body = $aData;
        }

        empty($aExt) && $aExt = 'jpg';

        $pictureModel = D('Picture');

        $md5 = md5($base64_body);
        $sha1 = sha1($base64_body);


        $check = $pictureModel->where(array('md5' => $md5, 'sha1' => $sha1))->find();

        if ($check) {
            //ÒÑ´æÔÚÔòÖ±½Ó·µ»ØÐÅÏ¢
            $return['id'] = $check['id'];
            $return['path'] = render_picture_path($check['path']);
            $this->ajaxReturn(array('status'=>1,'id'=>$return['id'],'path'=> $return['path']));
        } else {
            //²»´æÔÚÔòÉÏ´«²¢·µ»ØÐÅÏ¢
            $driver = modC('PICTURE_UPLOAD_DRIVER','local','config');
            $driver = check_driver_is_exist($driver);
            $date = date('Y-m-d');
            $saveName = uniqid();
            $savePath = '/Uploads/Picture/' . $date . '/';

            $path = $savePath . $saveName . '.' . $aExt;
            if($driver == 'local'){
                //±¾µØÉÏ´«
                mkdir('.' . $savePath, 0777, true);
                $data = base64_decode($base64_body);
                $rs = file_put_contents('.' . $path, $data);
            }
            else{
                $rs = false;
                //ʹÓÃÔÆ´æ´¢
                $name = get_addon_class($driver);
                if (class_exists($name)) {
                    $class = new $name();
                    if (method_exists($class, 'uploadBase64')) {
                        $path = $class->uploadBase64($base64_body,$path);
                        $rs = true;
                    }
                }
            }
            if ($rs) {
                $pic['type'] = $driver;
                $pic['path'] = $path;
                $pic['md5'] = $md5;
                $pic['sha1'] = $sha1;
                $pic['status'] = 1;
                $pic['create_time'] = time();
                $id = $pictureModel->add($pic);
               $this->ajaxReturn (array('status'=>1,'id' => $id, 'path' => render_picture_path($path)));
            } else {
                $this->ajaxReturn(array('status'=>0,'ͼƬÉÏ´«Ê§°Ü¡£'));
            }

        }
}

这段代码POST获取我们传递base64加密过来的图片内容 然后经过了一个正则判断是否是base64图片方式传递的(这里很关键)

if (preg_match('/^(data:*image/(+);base64,)/', $aData, $result)) {
            $base64_body = substr(strstr($aData, ','), 1);

            empty($aExt) && $aExt = $result[2];
        } else {
            $base64_body = $aData;
        }

        empty($aExt) && $aExt = 'jpg';

可以看见下面有一个 $aExt = 'jpg',这里是重新定义后缀,但很狗血的是前面有一个判断aExt这个变量是否为空,而刚好咋们正则为true时是一次对这个变量赋值的机会,既然是自定义的post 肯定一切内容我们都是可以控制的。

看看后面还有没东西

$pictureModel = D('Picture');

        $md5 = md5($base64_body);
        $sha1 = sha1($base64_body);


        $check = $pictureModel->where(array('md5' => $md5, 'sha1' => $sha1))->find();

        if ($check) {
            //ÒÑ´æÔÚÔòÖ±½Ó·µ»ØÐÅÏ¢
            $return['id'] = $check['id'];
            $return['path'] = render_picture_path($check['path']);
            $this->ajaxReturn(array('status'=>1,'id'=>$return['id'],'path'=> $return['path']));
        } else {
            //²»´æÔÚÔòÉÏ´«²¢·µ»ØÐÅÏ¢
            $driver = modC('PICTURE_UPLOAD_DRIVER','local','config');
            $driver = check_driver_is_exist($driver);
            $date = date('Y-m-d');
            $saveName = uniqid();
            $savePath = '/Uploads/Picture/' . $date . '/';

            $path = $savePath . $saveName . '.' . $aExt;
            if($driver == 'local'){
                //±¾µØÉÏ´«
                mkdir('.' . $savePath, 0777, true);
                $data = base64_decode($base64_body);
                $rs = file_put_contents('.' . $path, $data);
            }

认真的看下,后面并没有针对文件后缀做验证的。只有一个判断文件内容是否重复的数据库查询

那么本地复现
1
1
这里定义后缀为php 直接上传
1
成功getshell
1open

发表评论