1、定义
文件包含就是一个文件里面包含另外一个文件。一开始接触的时候是因为php里面,但是查找了一些资料这个存在在很多语言里面。
程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。
程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,
但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,
而在JSP、ASP、程序中却非常少,甚至没有,这是有些语言设计的弊端。
在PHP中经常出现包含漏洞,但这并不意味这其他语言不存在。
2、原理
通过引入文件时,用户可控,没有严格的检验,或是被绕过,操作一些敏感文件,导致文件泄露和恶意代码注入。
当包含文件在服务器本地上,就形成本地文件包含,当包含的文件在第三方服务器是,就形成可远程文件包含。
3、常见函数
php:include(),include_once(), require(), require_once(), fopen(),readfile()
Jsp/servlet: java.io.File(), java.io.FileReader()
asp: include file, include virtual
4、文件包含分类:
①本地文件包含:当被包含的文件在服务器本地时,就形成本地文件包含;
②远程文件包含:当被包含的文件在第三方服务器时,叫做远程文件包含。
5、该漏洞涉及到php常见包含文件函数包括:
include():当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行
include_once():功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次
require():require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行 。使用require()函数包含文件时,只要程序一执行,立即调用文件,而include()只有程序执行到函数时才调用 .require()在php程序执行前执行,会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。
require_once():它的功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
6、文件包含可以利用的方式
① 直接进行文件的遍历读取;(读取敏感信息)
在获悉中间件 IIS、apache与第三方集成包等程序默认安装路径的情况,可以直接利用文件包含结合目录遍历进行“配置文件的读取”
include.php?file=../../../etc/pass
include.php?file=../../../xampp/htdocs/config.php
②解析符合php规范的任何文件;(本地包含配合文件上传)
可以利用文件包含函数可以解析任何符合PHP规范的文件的特性,结合文件上传绕过WAF,获取webshell。
利用过程:
1)上传shell.txt /shell.jpg /shell.rar /shell.xxx (需要确认上传后,上传文件的绝对路径)
2) 使用文件包含漏洞,直接解析上传的非php后缀的文件,获取webshell。
③使用PHP封装协议(读取php文件源码)
PHP内置有很多类似于URL风格的封装协议:
file:// — 访问本地文件系统;
http:// — 访问HTTP(s)网址;
ftp:// — 访问FTP(s)URLs ;
php:// — 访问输入/输出流(I/0 stream)