导航

攻防世界warmup

Posted on 2026-01-27 10:47  看雪?  阅读(0)  评论(0)    收藏  举报

点开网页就是一个贴吧老哥的经典表情,按照惯例按F12.注释里有个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\" />";
}  

?>`
一长串代码,吓晕了。。开始代码审计。定义一个emmm类,公共静态函数checkFile,其参数是引用page,表示在函数内部对page做的改变外部也会同步改变。定义一个名为whitelist的键值对数组,分别是source.php,hint.php.看到这我们再去访问一下hint.php,说flag在ffffllllaaaagggg,看到这缺乏做题经验的我以为是出题人在恶作剧瞎写呢。接下来三个if,是满足其一就可以返回true,也就是我们要的结果。
第一个if,是如果page在白名单里也就是source.php和hint.php那么就返回true。
诶看到这出现了个mb_substr()和mb_strpos(),搜索得知前者是截断作用,语法为mb_substr(字符串, 起始位置, 截取长度);后者是定位作用,本题中mb_strpos($page . '?', '?')意为找到page中?第一次出现的位置,并且自动在page末尾补上一个?(这是为了防止page中没有?返回false)。
那么第二个if意思就很明确了,例如说source.php?id=1这样的经过截断后也在白名单里,也能返回true。
第三个if呢,是对page经过URL解码后再进行截断操作。
最终,如果请求中的file不为空且是字符串(这都不用看当然满足啦)并且通过了checkfile返回true,那么就能成功文件包含include读取文件。
第二个if最简单,那我们就file=source.php?后面跟东西就行。接下来要考虑的是后面跟啥。之前的hint.php说flag在ffffllllaaaagggg里,那我们就利用include的路径穿越,一层一层往上找它的位置。最终url为http://61.147.171.103:57771/?file=source.php?/../../../../ffffllllaaaagggg