文件包含

本文最后更新于:10 个月前

BUUCTF_ WarmUp

嗯。。一打开是一个滑稽脸直接一眼ctrl+u查看源代码,查找到注释提示source.php,进入source.php看到是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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?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\" />";
}
?>

先看代码主体部分

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

明确了传入一个参数file,并且如果满足:

file不为空(被赋值);是字符串;传入emmm类中的checkFile()方法后返回值为真。则能够将file包含。

审计emmm类,

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

白名单中包含”source.php”和”hint.php”,source.php就是本页面,传入file=hint.php对hint.php进行包含(一开始做的时候真的以为是什么提示硬是想不看提示自己琢磨结果发现无论如何还是得看的呜呜呜呜呜)

告诉了我们得到flag不是在这,而是在ffffllllaaaagggg,继续审计,

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

$page必须是有被赋值而且是字符串。

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

$page如果在白名单内(source.php和hint.php)则返回true。

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

mb_substr(a,b,c),对a字符串进行截取,从第b位开始,截取c个字符串长度,返回截取的字符串;

mb_strpos(a,b),返回字符串b在字符串a中第一次出现的位置,如果没出现过则返回false;

mb_substr()截取$page,从第一个字符开始,截取长度为mb_strpos($page.’?’,’?’),即问号在字符串page$.’?’(就是$page字符串最后面跟一个问号)中第一次出现的位置,记住是第一次,$page.’?’末尾的问号未必是第一次出现的位置。截取到的字符串赋值给$_page。(注意分清变量名)

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

如果$_page在白名单里,则返回true,$_page的值我们是可以决定的,所以传入的file的值应以字符串”hint.php?”或者”source.php?”开头,这样一来经过mb_sudstr()的截取最终将”hint.php”或”source.php”与白名单进行对比返回为true。

到此为止已经满足了主体部分的三个条件了,结合hint.php的提示flag在ffffllllaaaagggg,传参?file=hint.php?ffffllllaaaagggg,没有结果判断flag不在本目录,盲猜在根目录,于是

payload:

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


BUUCTF_新生赛include1

一开始只有一个tips超链接,点击,提示“Can you find out the flag?”。查看源代码没有任何收获,发现url的位置是通过file传参,file=flag.php。想到应该是主页源码含有文件包含,通过包含参数file。尝试php伪协议。

1
?file=php://input

页面发出警告“hacker!”尝试大写绕过失败,尝试filter伪协议读取网页源码。

1
php://filter/read=convert.base64-encode/resource=flag.php

base64解码后拿到flag

题后反思:用同样的方法查看了一下index.php源码

过滤函数使用的是stristr()是不区分大小写的,strstr()则区分,同样还过滤掉了zip://和phar://还有data://。顺路学了下文件上传的zip://和phar://协议注入。