一、什么是文件包含?
在PHP中,也有类似的函数,为了更好地使用代码的重用性,引入了文件包含函数,可以通过文件包含函数将文件包含进来,直接使用包含文件的代码
文件包含分文本地文件包含(Loacl File Inclusion,LFI)和远程文件包含(Remote File Inclusion,RFI)
远程文件包含需要在php.ini中设置allow_url_include = on和allow_url_fopen= on(我这里还没有开,等一会开)
二、文件包含漏洞
在包含文件时候,为了灵活包含文件,将被包含文件设置为变量,通过动态变量来引入需要包含的文件时,攻击者利用包含的特性,加上应用本身对文件(包含)控制不严格,最终造成攻击者进行任意文件包含(任意文件包含才是漏洞),这样就导致了文件包含漏洞 通常文件包含漏洞出现在PHP
语言中
三、文件包含关键函数
include()函数:使用include引用外部文件时,只有代码执行到include代码段时,调用的外部文件才会被引用并读取,当引用的文件发生错误时,系统只会给出个警告错误,而整个php文件会继续执行
require()函数:在php文件被执行之前,php解析器会用被引用的文件的全部内容替换require语句,然后与require语句之外的其他语句组成个新的php文件,最好后按新的php文件执行程序代码
include_once()函数:使用include_once会在导入文件前先检测该文件是否在该页面的其他部分被引用过,如果有,则不会重复引用该文件,程序只能引用一次
require_once()函数:功能与 require()相同,区别同样在于当重复调用同一文件时,程序只调用一次
四、漏洞复现
1、本地包含
访问网页,可以看到,test.txt文本中间代码执行了,这里注意:txt,png,jpg,gif......(配合文件上传)等后缀包含都是以php进行执行。
注意,如果这个包含处可以用户修改,那就,哈哈哈哈哈,你懂的:
<?php
$test = $_GET['file']; //用户可控
include($test);
?>
利用:
(1)日志记录错误,这错误apache会自动记录。
这里再访问时候,浏览器会对访问的网址及进行url编码,我们的代码并没有执行,
这里面的<>被编码成%3C和%3E,在文件包含中无法对该文件解码,所以只能输出源文件
怎么解决,抓包修改即可。
所以这里进行bp拦截更改内容。
访问网址,发现已经执行:
(2)文件上传
自己脑补,自由发挥。自己上传不同的类型文件,然后本地包含
2、远程包含
当包含的文件在远程服务器上时,就形成了远程文件包含
构成条件
需要php.ini中allow_url_include = on以及allow_url_fopen=on
所包含远程服务器的文件后缀不能与目标服务器语言相同。(比如目标服务器是php脚本语言解析的,那么包含的远程服务器文件后缀不能是php)
首先看下远程服务器的phpinfo信息
(1)、另一台服务器有txt文件如下:
(2)然后试着去包含远程服务器的txt;
可以看到远程服务器的txt文件代码以php形式执行。
五、文件包含和伪协议:
文件中可以包含不同的伪协议,我将在下面演示其中的一些
- data:text/plain or data: text/plain; base64
- php://input
- php://filter
- file://
- zip://
(1)data:text/plain
输出直接显示在相应的URL中,显示参数:data:text/plain 然后你需要执行如下所示的php代码
http://192.168.189.129/x.php?file=data:text/plain,<?php echo "test"; phpinfo(); ?>
<?php
$str = '<?php phpinfo();';
echo base64_encode($str);
?>
https://tool.oschina.net/encrypt?type=3
php://input(php:// 这是一系列)
php://input访问请求的原始数据的只读流(read-only stream),会将post请求中的数据作为php代码执行
php://filter
php://filter可以读取php文件的代码base64编码的输出并将其返回给你
file://
file://用于访问本地文件系统,不受allow_url_fopen or allow_url_include的影响,
你可以使用file:// absolute / path / to / file来获取
zip://(用的不多)
zip://可以访问zip文件中的文件,但它需要一个绝对路径。你可以使用zip://[archive absolute path] # [compressed file name]在本地创建一个文件并将其压缩到一个zip压缩文件中