php云人才系统 小漏洞一步步getshell(后台)

2014-09-15T00:00:00
ID SSV:93975
Type seebug
Reporter Root
Modified 2014-09-15T00:00:00

Description

简要描述:

php云人才系统 小漏洞一步步getshell,这里包含了php与mysql交互时候的特性(也算一个漏洞),还有phpyun自身图片的验证机制问题,等等,步骤比较艰辛,本来想在这里搞一个csrf呢,找了半天没有找到,到时找到一大堆xss,这里就不利用xss了,且看分析

详细说明:

首先我们做一个小测试: 对于mysql存储来说,建站者都会给每一个字段设置长度,然后当我们插入进去的数据长度超过了设置的长度,那么mysql是不会报错,然而会自然截断存储,这个就给我们编写程序的人留下了隐患。 利用场景分析 1.如果你上传的目录会保存到数据库里面,并且这里上传的文件采用白名单,那么我们就可以根据数据库这个特性绕过程序判断,然后进入数据库,存储一个不在白名单内的文件路径 2.当我们二次利用这个东西的时候,比如说include 或者required 就会执行php代码 发散思考,其实这个思路不仅仅利用在文件这里,我只是举个例子,比如说如果么有对email的长度做验证,那么我们就可以注册一个和管理员一样的email,当后续用这个email查询验证时候,我们所有的回话就是管理员的,这里不做赘述 开始进行测试:

<img src="https://images.seebug.org/upload/201409/102341421e6a3d435eea659037e129ac8ce1a1fc.png" alt="3.png" width="600" onerror="javascript:errimg(this);">

这里我们创建一个有两列,长度为5的字段,然后我们插入一个大于5的姓名,看看效果会怎样 insert into vff values('xxxxxxxxxx','xx') 我们发现结果里面就只有五个长度:

<img src="https://images.seebug.org/upload/201409/10234455490607aa355c8ea50a77516a29e5e313.png" alt="4.png" width="600" onerror="javascript:errimg(this);">

这里我们在延伸一下,我们插入 insert into vff values('123 sdsd','xx')

<img src="https://images.seebug.org/upload/201409/1023464264423f6bb27bae92ab0961c84ff3b3cc.png" alt="5.png" width="600" onerror="javascript:errimg(this);">

我们在用 select * from vff where name = '123' 这个是可以取出来的

<img src="https://images.seebug.org/upload/201409/1023483824d0984e1ee48e44de086cfc737c5f23.png" alt="6.png" width="600" onerror="javascript:errimg(this);">

这里的东西不多赘述,下来我们直接看phpyun里面的代码: corn.class.php:(line:94-100):

function run_action(){ if($_GET['id']) { $this-&gt;cron($_GET['id']); } $this-&gt;layer_msg('计划任务(ID:'.$_GET["id"].')执行成功!',9,0,"index.php?m=cron"); }

我们跟到$this->cron里面去看看: common.php:(lines:1987-1999):

``` if($timestamp) { krsort($timestamp); $croncache = current($timestamp); ignore_user_abort(); set_time_limit(600);

            if(file_exists(LIB_PATH.'cron/'.$croncache['dir']))
            {
                include(LIB_PATH.'cron/'.$croncache['dir']);
            }
            $nexttime = $this-&gt;nextexe($croncache);

```

看到了LIB_PATH.'cron/'.$croncache['dir'],然后如果存在则进入到了引用函数,执行了, 那么我们来分析一下$croncache['dir'],从哪里来的....... cron.class.php:(lines:63-67):

if(!$id){ $_POST["ctime"]=mktime(); $nbid=$this-&gt;obj-&gt;insert_into("cron",$_POST); $alert="计划任务(id:".$nbid.")添加成功!"; $this-&gt;croncache();

这里明显就是保存之后,然后生成缓存文件,跟到缓存文件继续查看: cache.class.php:(lines:38-55)

public function cron_cache($dir){ $rows=$this-&gt;obj-&gt;DB_select_all("cron","`display`='1' order by id asc"); if(is_array($rows)){ foreach($rows as $key=&gt;$value){ $cron_cache[$key]['id']=$value["id"]; $cron_cache[$key]['dir']=$value["dir"]; $cron_cache[$key]['type']=$value["type"]; $cron_cache[$key]['week']=$value["week"]; $cron_cache[$key]['month']=$value["month"]; $cron_cache[$key]['hour']=$value["hour"]; $cron_cache[$key]['minute']=$value["minute"]; $cron_cache[$key]['nexttime']=$value["nexttime"]; } } $data['cron']=ArrayToString2($cron_cache); return $this-&gt;obj-&gt;made_web_array($this-&gt;cachedir.$dir,$data); }

看到这里大家都明白了$cron_cache[$key]['dir']=$value["dir"];是从我们刚才存储到数据库里面的dir取出来的,我们在回头看看,刚才的那个有什么限制, cron.class.php:(line:56-59):

$dirArr = explode('.',$_POST['dir']); if(end($dirArr)!='php'){ $this-&gt;obj-&gt;ACT_layer_msg("无效的执行文件!",8,"index.php?m=cron"); }

发现这里只能是php文件,当然了根据刚才我们的思路,我们可以绕过去的,我们进入后台:

<img src="https://images.seebug.org/upload/201409/11000013e37e8fe746b4f4bf57a2556bea71d8ae.png" alt="7.png" width="600" onerror="javascript:errimg(this);">

<img src="https://images.seebug.org/upload/201409/1100005356630fe8703ecf47bd1f9305f284e0c9.png" alt="1.png" width="600" onerror="javascript:errimg(this);">

这样一来这两张图,就可以把一个vvvv.png,存储到数据库中了,我们重新上传一个:

<img src="https://images.seebug.org/upload/201409/110001516412b38298425db3a9cedf47315e708b.png" alt="2.png" width="600" onerror="javascript:errimg(this);">

然后我们查看数据库,

<img src="https://images.seebug.org/upload/201409/11000312a5f441236d65e2b2bd48440be4a5e616.png" alt="8.png" width="600" onerror="javascript:errimg(this);">

我们在去界面的另外一个地方点击执行

<img src="https://images.seebug.org/upload/201409/11000454ca735374a069d32fc1252201f5faab39.png" alt="9.png" width="600" onerror="javascript:errimg(this);">

<img src="https://images.seebug.org/upload/201409/11000811a1002d47ced25050f3b7f9c35ffc1bdc.png" alt="10.png" width="600" onerror="javascript:errimg(this);">

前面的着所有的一切,已经正式一个东西,此处可以绕过,并且通过文件包含可以执行代码 那么这个图片码怎么搞定,我们经过尝试,phpyun测试了上传头像和上传身份证一边,只有上传身份证没有对图片的内容做深度校验:

<img src="https://images.seebug.org/upload/201409/110010551d899c5cae9726bd46e09e317777fece.png" alt="11.png" width="600" onerror="javascript:errimg(this);">

我们上传后,看看上传上去的文件路径,

<img src="https://images.seebug.org/upload/201409/11001230738bc92c2b1a5b6402f292a87494405c.png" alt="12.png" width="600" onerror="javascript:errimg(this);">

我们看看图片内容改变了没有:

<img src="https://images.seebug.org/upload/201409/110013410abfe8347fe09e582a84364b7c9f896c.png" alt="13.png" width="600" onerror="javascript:errimg(this);">

果真这里没有变化,后续的我就不多说了,直接把那个shell.png换掉就可以了

漏洞证明: