opensns前台无限制Getshell

  • A+
所属分类:漏洞时代
摘要

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

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);             }

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

那么本地复现
opensns前台无限制Getshell
opensns前台无限制Getshell
这里定义后缀为php 直接上传
opensns前台无限制Getshell
成功getshell
opensns前台无限制Getshellopen

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: