[BSidesCF 2020]Had a bad day

[BSidesCF 2020]Had a bad day

这题还是比较简单的,打开环境里面就两个按钮

image

输入其他参数都会提示:Sorry, we currently only support woofers and meowers.

第一次猜测是SQL注入,但输入引号测试没效果

然后猜测也可能是布尔注入,于是测试and,结果发现报错了

image

居然是include。。。

那很明显这不是一道SQL注入的题,传参可以提交要包含的文件名,但他服务器里有什么文件目前还不知道。先尝试用伪协议读源码,但是报错了。

image

报错信息可以看出,尾缀的php多了一个,应该是被拼接了,删除后缀名再提交就可以了。

拿到源码:

<?php
				$file = $_GET['category'];

				if(isset($file))
				{
					if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
						include ($file . '.php');
					}
					else{
						echo "Sorry, we currently only support woofers and meowers.";
					}
				}
?>

源码很简单,里面用到了strpos函数,这个就是返回一个字第一次出现的位置,需要注意

image

如果第一个字在首位出现,则返回0,PHP中弱类型0就是假,所以会导致if判断过不了

解决这题的关键在于PHP目录定位的特点

正常情况下,我们定位文件只需要输入文件地址就可以,但如果输入的文件地址超过了最小的文件夹,无疑会出错

image

但如果我们用两个点号又返回了上级目录,再访问文件,就又变得可行。

image

继续研究,如果访问的文件不存在的话,还能不能向上返回目录了?

image

测试发现,不可以!

但这仅是在Windows的环境下进行的测试,其他的环境还需要具体测试。

Linux环境下的测试:

image

测试结果可以发现,当最后切换的对象是一个文件而不是一个目录时,Linux的表现和Windows不同,Windows系统可以正常返回当前目录下,而Linux系统会报错。

不同的环境对目录的处理机制不太一样,PHP也不例外。

PHP环境下测试:

测试代码(例题的简化版):

<?php
$file = $_GET['d'];
$b = $file . '.php';
echo $b;
echo "<br>";
	if(isset($file))
	{
		include ($b);
	}
?>

测试结果:

image

image

image

多轮测试发现,PHP对文件是否存在不关心,因为他只关心你最终所在的目录位置,甚至中间多套几层也不影响。

image

但是,如果你最终的目录位置不存在的话,人家该报错还是会报错的,比如下面就少了一层

image

回归题目,这题就是利用PHP的这个特性完成绕过的。

image

这题最后就不多啰嗦了,flag文件可以包含进来,没有报错,说明存在该文件,只需要再利用伪协议读源码就行了

payload:?category=php://filter/convert.base64-encode/resource=woofers/sui/bian/da/../../../../flag

image

base64解码就是flag了!

posted @ 2021-11-01 20:02  Sentry_fei  阅读(149)  评论(0编辑  收藏  举报