本次教程来自YanXia,转载请注明作者信息,博客地址http://www.535yx.cn,感谢


在做这道题的时候,我曾把文件包含和文件读取这两个漏洞给弄混淆了。那么什么是文件包含,什么是文件读取呢?
简单的说:文件被解析,则是文件包含漏洞

    显示源代码,则是文件读取漏洞

好了,步入正文
打开网站发现跳出来一个滑稽表情

65927-f6c2wfp7ewm.png

当我们使用F12时候发现source.php
65892-666g93ngo72.png

访问后获得一大串代码。需要我们审计

 <?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\" />";
    }  
?> 

接下来让我们来剖析这一大串代码
首先我们可以看到highlight_file这个函数,其就是对文件进行语法高亮显示。所以我们可以判断这题需要利用文件包含漏洞。
然后我们发现$whitelist数组中有两个值为source.php和hint.php。所以我们访问一下hint.php
44840-gv8b1l9yqpr.png

这里我们就知道了,待会需要构造语句来解析ffffllllaaaagggg,从而得到FLAG
好的,我们继续分析代码

if (! isset($page) || !is_string($page)) {
                echo "you can't see it";         //这里要求$page必须是字符串,否则false
                return false;
            }

if (in_array($page, $whitelist)) {    //这里判断如果page存于whitelist,就返回true
                return true;

这里我们认识一下mb_strpos()函数以及mb_substr
74221-de0dw74gr4g.png

15443-6nsl8vubikt.png

89439-hg87l7qoq5w.png

                

$_page = mb_substr(              $page,                                       
                0,
                mb_strpos($page . '?', '?') //若$page中有俩个问号,截取其中间段
            );
            if (in_array($_page, $whitelist)) {//这里是取'?'前的部分并判断如果$page存于whitelist,返true
                return true;
            }

$_page = urldecode($page); //将$page解码
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) { //判断经url解码且截取片段的$page是否存于whitelist
                return true;

只有经过这些验证才能,进行下一步的执行,否则返回false

if (! empty($_REQUEST['file']) //变量不为空
        && is_string($_REQUEST['file']) //要求请求为字符串
        && emmm::checkFile($_REQUEST['file']) //将值赋予checkfile函数

总结一下这里的要求
$page为字符串且存于whitelist数组中
$page中 '?' 前部分需存于whitelist数组中
进行一次url解密,并继续判断$page是否存在于$whitelist中
最后check函数再url解密一次
所以说,我们这里可以直接构造出payload(这里由于我们不知道ffffllllaaaagggg在哪个路径下,所以只能依次加上../直至得出flag)

source.php?file=source.php?../../../../../ffffllllaaaagggg

即可得出FLAG(或者将source.php后面的'?'url加密俩次也可)
97725-hifq8wq3nq4.png

发表评论