攻防世界-web:warmup

题目描述

暂无

题目截图

image

解题思路

访问标题链接,发现图片是个大大笑脸。直接看源码。
image
发现提示source.php,访问source.php,得到php源代码。
image
源码如下:

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

分析源码:
1)接收一个请求参数file。
2)判断请求参数是否为空,是否为字符串,然后利用checkFile函数进行检测。
3)检测通过后,对file参数进行文件包含。

该题主要是分析checkFile函数。经过分析checkFile函数,发现逻辑如下:
1)设置了一个白名单数组,数组内容为source.php,hint.php
2)判断file参数值是否存在,是否为字符串。否则返回false
3)判断file参数值是否在白名单里,如果在直接返回true
4)利用mb_substr、mb_strpos函数是对目标字符串进行截取操作,将截取结果赋值给$_page参数。
5)判断$_page参数是否在白名单里。如果存在直接返回true,否则继续执行。
6)对file参数进行url解码赋值给$_page
7)利用mb_substr、mb_strpos函数是对$_page参数进行截取操作,将截取结果赋值给$_page参数。
8)判断$_page参数是否在白名单里。如果在就返回true,否则返回false。

基本过程就是上面所述,此题目标就是利用目录穿越进行文件包含,获取flag。核心关键是构造的目录穿越字符串要能经过checkFile函数的检测。
通过file参数赋值hint.php,可以知道flag在ffffllllaaaagggg文件里,所以只要能够包含到此文件即可获取flag。
image
构造包含思路如下:
1)file=/ffffllllaaaagggg
2)file=../../../../ffffllllaaaagggg
但是以上两个构造都无法通过checkFile函数检测,直接会返回false。
我们再次分析checkFile函数流程,发现只要$_page能够匹配到白名单即可返回true。所以file参数经过字符串截取操作后,为source.php或hint.php即可。
我们发现checkFile函数里进行了url解码,我们知道浏览器到服务器会进行一次url解码,checkFile会再次进行一次url解码,可以考虑二次url编码。
我们还发现,字符串截取逻辑是在传入的file参数字符串后面拼接一个"?",然后去查找"?"在file参数字符串中第一次出现的位置,然后从0位置向"?"字符位置进行字符串截取。
例如:
file=hint.php?/../../../../123.php,则经过第一次截取后的结果为hint.php,直接返回true。则会包含hint.php?/../../../../123.php,但是这个是无法构成目录穿越的。
如果
file=hint.php%253f/../../../123.php,(其中%253f为"?"经过两次url编码的结果),则经过第一次截取后返回结果为hint.php%3f/../../../123.php,不在白名单里,则会进行url解码后进行第二次截取,url解码结果为hint.php?/../../../123.php,对这个字符串进行截取后,截取结果为hint.php,在白名单里,返回true。则会包含hint.php%3f/../../../123.php,这个字符串可以构成目录穿越,服务器会将hint.php%3f当作当前目录下的一个文件夹。经过上级目录穿越,最终将123.php进行包含。
所以最终payload为:
1)hint.php%253f/../../../../../ffffllllaaaagggg
2)source.php%253f/../../../../../ffffllllaaaagggg
image
得到flag

总结

1)理解目录穿越原理
2)理解URL二次编码后服务器解析原理
3)能够分析代码逻辑

posted @ 2021-10-14 13:07  顺时针--+  阅读(100)  评论(0编辑  收藏  举报