[web] - url路径不一致

Flag:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VV42XLMT-1586576814117)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image002.gif)]

首先根据老师上课的提示尝试路径不一致漏洞:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-or69sfmJ-1586576814120)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image004.gif)]

  • 查看源码,并在本地将源码对于检测关键字符串的回馈信息进行调整:
<?php
require_once('core.php');

function check($path) {
  // $path = clean($path);
    if (strpos($path, 'core') !== false) {
        return "core";
    }
    if (strpos($path, '/var/www/html/') !== 0) {
        return "www";
    }
    if (strpos($path, '..') !== false) {
        return "..";
    }
    return false;
}

if (isset($_GET['path'])) {
    $path = $_GET['path'];
    if (check($path)) {
        echo check($path);
    } else {
        if ( file_exists($path) &&(strpos($path, 'flag') !== false)) {
            echo "No flag read";
        } else {
            echo file_get_contents($path);
        }
    }
} else {
    highlight_file(__file__);
}

?>


  • 根据check函数的约束规则,要求必须以/var/www/html开头且path参数里面不能出现core..
  • 御剑扫描后台只发现了一个core.php,源代码中发现导入了core.php函数并且使用了其中的clean函数。
  • 试着在url中输入/var/www/html///../index.php/var/www/html/index.php的结果一样,而没有提示检测到..因此猜测clean函数里面对路径进行了类似spring的解读,也就是将$path中的//看成是一个空目录,与相邻的/../目录合并抵销。顺着这个猜想尝试进入/var/www/html/的逐层上找查询flag在哪级目录中:
    在这里插入图片描述发现是在根目录中,然后致力于绕过下面的if ( file_exists($path) &&(strpos($path, 'flag') !== false))分支进入else从而读取flag
    在这里插入图片描述这个if分支由两个条件相与共同限制,只要破坏其中一个就可以,基于从小对于file_exists的刻板印象选择先从后面的strpos突破,试了编码、字符串拼接、数据类型转换等方法都无果然后想到和上文的strpos($path,'core')是相同的限制,如果这里能突破strpos上文就能直接看到core.php的源码了,因为上面就放弃了所以转而去研究有没有可能file_exists存在和file_get_content之间的差别,使得能够file_exists返回false而file_get_content成功读到内容。
    这时经同学提示看到了两篇文章:

https://www.techug.com/post/php-file_exists-problem.html
https://www.freebuf.com/articles/web/53656.html
其中有解释:
在这里插入图片描述
意味着在中间目录中插入/anystring/…/会不经检验的直接抵消。

试了一下在原有url后面追加/6666/../flag变成path=/var/www/html///..///..///../6666/../flag
得出报告一开头出现的flag。
Note:
然而仔细想其实这两篇文章跟我们这个题目的逻辑实际是相互矛盾的:
上文两篇博客的目的都是为了在中间加入命令行而又能浑水摸鱼通过file_exists函数的检验,使用eval执行命令,而我们这个题则是希望从file_exists这儿卡住目录转而进入file_ge_contents
网上的博客file_exists说的是会把url中/anystring/和/…/这一对不加检查直接抵销掉,但是这个题里面从结果能绕过if分支来看是他需要就检查出来了每一小段/anystring/目录是否存在,而get_content那个函数只检查最终文件是否存在所以把/ anystring/和/…/抵消了读出文件,这样来看这个题中的file_exist和php原版的file_exists检测规则是不一样的。有理由怀疑core.php中可能重写了一个file_exists,但是core.php的源码又尚未获得所以可以说这个题是误打误撞了。

发布了30 篇原创文章 · 获赞 0 · 访问量 2045

猜你喜欢

转载自blog.csdn.net/s11show_163/article/details/105449753