Buuctf-Web-[HCTF 2018]WarmUp

前言

刷题地址:https://buuoj.cn/challenges

创新互联公司是工信部颁发资质IDC服务器商,为用户提供优质的大邑服务器托管服务


首先打开是一个笑脸,查看源代码,如下图发现了,一个文件

一.代码分析

发现是一堆代码,需要PHP代码审计,全部代码如下。

1 "source.php","hint"=>"hint.php"];
8            if (! isset($page) || !is_string($page)) {
9                echo "you can't see it";
10                return false;
11           }
12
13            if (in_array($page, $whitelist)) {
14                return true;
15            }
16
17            $_page = mb_substr(
18                $page,
19                0,
20                mb_strpos($page . '?', '?')
21            );
22            if (in_array($_page, $whitelist)) {
23                return true;
24            }
25
26            $_page = urldecode($page);
27            $_page = mb_substr(
28                $_page,
29                0,
30                mb_strpos($_page . '?', '?')
31            );
32            if (in_array($_page, $whitelist)) {
33                return true;
34            }
35            echo "you can't see it";
36            return false;
37        }
38    }
39
40    if (! empty($_REQUEST['file'])
41        && is_string($_REQUEST['file'])
42        && emmm::checkFile($_REQUEST['file'])
43    ) {
44        include $_REQUEST['file'];
45        exit;
46    } else {
47        echo "
"; 48 } 49 ?>

查看到了关键字眼hint.php

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

我们访问这个文件查看,如下图,发现flag在ffffllllaaaagggg里面

首先先看40-48行的内容! empty($_REQUEST['file']的意思是传参file不能为空

is_string($_REQUEST['file']的意思是传参必须要字符串

emmm::checkFile($_REQUEST['file']这句话的意思是要经过checkFile函数的检查

如果都为真那么就执行include $_REQUEST['file'];包含文件

如果为否那么就输出滑稽图片

由此可以总结

1.file传参不能为空

2.file传参必须要字符串

3.需要经过checkFile函数的检测

40    if (! empty($_REQUEST['file'])
41        && is_string($_REQUEST['file'])
42        && emmm::checkFile($_REQUEST['file'])
43    ) {
44        include $_REQUEST['file'];
45        exit;
46    } else {
47        echo "
"; 48 }

接下来来看看,函数代码为5-38行,首先来看第一个if语句issset()函数判断是否设置了$page,或者如果$page不是字符串就输出you can't see it然后返回为假。

第二个if语句判断的是$page是否在$whitelist里面,如果在那么就返回true。

然后17行-21行是截取$page?前面的东西mb_substr()函数是截取,mb_strpos()涵数是判断字符串首次出现的位置就是,截取$page0-?首次出现的位置的地方也就是截取?前面的东西

22-24行又判断$page是否在$whitelist里面如果有那么就返回true

26行对传参进行了一次url编码解码

27-31又进行了一次截取

32-34又进行了一次判断是否在$whitelist里面,如果有那么就返回true

总结来说

1.第一个if判断是$是否设置了值或者是$page是否为字符串,如果不是返回false

2.第二个if判断的是$page是否在$whitelist列表里面如果在就返回true

3.第三个语句是截取$page问号前面的东西

4.第四个语句会对$page进行一次url编码的解码,加上浏览器就是两次解码

5.第五个语句还是截取$page问好前面的东西

6.最后一个语句判断$page是否在$whitelist里面

如果上面四个if语句都没返回那么就返回false

class emmm
4    {
5        public static function checkFile(&$page)
6        {
7            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
8            if (! isset($page) || !is_string($page)) {
9                echo "you can't see it";
10                return false;
11           }
12
13            if (in_array($page, $whitelist)) {
14                return true;
15            }
16
17            $_page = mb_substr(
18                $page,
19                0,
20                mb_strpos($page . '?', '?')
21            );
22            if (in_array($_page, $whitelist)) {
23                return true;
24            }
25
26            $_page = urldecode($page);
27            $_page = mb_substr(
28                $_page,
29                0,
30                mb_strpos($_page . '?', '?')
31            );
32            if (in_array($_page, $whitelist)) {
33                return true;
34            }
35            echo "you can't see it";
36            return false;
37        }
38    }

所以经过上面的判断,payload应该是如下,测试其实不需要两次编码都可以,因为?的解码还是?所以也可以直接/source.php?file=source.php?../../../../../../../../../../ffffllllaaaagggg

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

当前题目:Buuctf-Web-[HCTF 2018]WarmUp
文章位置:http://myzitong.com/article/dsogoei.html