打开靶机,进入界面:
在这里插入图片描述

信息搜集

当前界面没有任何有用信息。
想到查看页面源代码。右键–查看页面源代码
在这里插入图片描述
看到hint:<!--source.php-->

进入/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,先不管,先看看后面真正被执行的代码:

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

是一个条件判断语句。分析一下:

empty() 检查变量是否为空
is_string() 检查变量是否为字符串
emmm::checkFile() 调用emmm类中的checkFile方法
$_REQUEST[‘file’] 获取GET或POST传参的数据,参数为file

所以这里的判断就是:
当传入的变量file不为空 是字符串 checkFile()结果为true时,返回值为true.在当前界面包含file指向的文件。
那么关键就在于让 checkFile()结果为true。所以我们审计一下该方法:

 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;
        }

第一处:
! isset($page) || !is_string($page) isset()判断传入的参数page(方法中的page就是我们传入的参数file)是否已设置并且非空;is_string()判断参数是否为字符串。当两者同时为true时,进入下一处条件判断。
第二处:
in_array($page, $whitelist) in_array()判断参数page是否位于whitelist数组中.
由于$whitelist = ["source"=>"source.php","hint"=>"hint.php"];所以合法的值只有source.php和hint.php。
现在我们所在的界面是source.php,所以我们令file=hint.php,返回值为true,就能包含hint.php,查看该文件的内容。
在这里插入图片描述提示flag在ffffllllaaaagggg文件。但是该文件不在whitelist数组中,所以这一处的条件判断我们不能让它返回true,而是要进入下一步。

第三处:

mb_substr() 用于截取字符串,第一个参数为字符串,第二个和第三个参数分别为起始索引和终止索引。
mb_strpos() 用于查找指定字符串在目标字符串中首次出现的位置。第一个参数是目标字符串,第二个参数是只当字符串。

$_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
           
在参数page中截取字符串。
起始索引为0,也就是从头开始截取。
终止索引为参数page拼接一个?后,?首次出现的位置。
if (in_array($_page, $whitelist)) {
                return true;
            }

如果_page在whitelist中,也return true。
所以我们可以在file=hint.php后面拼接问号,在问号后面输入我们真正要包含的文件。
构造payload:

?file=hint.php?/../../../../ffffllllaaaagggg

mb_substr()会截取问号之前的数据,也就是截取了hint.php带入白名单查询,查询结果为true,返回值为true.
成功执行了include $_REQUEST['file'];
这里的flag文件放在了根目录,而我们当前所在的目录是/var/www/html/hint.php
因此使用了四个…/回到根目录,获取flag.

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部