一、原理解析。
开发人员通常会把可重复使用的函数写到单个文件中,在使用到某些函数时,可直接调用此文件,而无须再次编写,这种调用文件的过程被称为包含。
注意:对于开发人员来讲,文件包含很有用,可以简化代码。
文件包含漏洞的产生原因是在通过引入文件时,由于传入的文件名没有经过合理的校验,或者校验被绕过,从而操作了预想之外的文件,最终造成攻击者进行任意文件包含。
注:包含的文件会被当成脚本文件进行解析。
文件包含本身并不属于漏洞,由于对包含进来的文件不可控,导致了文件包含漏洞的产生。
二、文件包含类别。
文件包含分为本地文件包含LFI和远程文件包含RFL:
当被包含的文件在服务器本地时,就形成的本地文件包含
当被包含的文件在远程服务器时,就形成的远程文件包含
远程文件包含需要在php配置文件中开启
allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件
三、文件包含漏洞函数解析。
①include:使用include引用外部文件时,只有代码执行到include代码段时,调用的外部文件才会被引用并读取,当引用的文件发生错误时,系统只会给出个警告错误,而整个php文件会继续执行。
②require:在php文件被执行之前,php解析器会用被引用的文件的全部内容替换require语句,然后与require语句之外的其他语句组成个新的php文件,最好后按新的php文件执行程序代码。
③include_once:使用include_once会在导入文件前先检测该文件是否在该页面的其他部分被引用过,如果有,则不会重复引用该文件,程序只能引用一次。(要导入的文件中存在一些自定义函数,那么如果在同一个程序中重复导入这个文件,在第二次导入时便会发生错误,因为php不允许相同名称的函数被重复声明)
④require_once:require语句的延伸,他的功能与require语句基本一致,不同的是,在应用require_once时,先会检查要引用的文件是不是已将在该程序中的其他地方被引用过,如果有,则不会在重复调用该文件。(同时使用require_once语句在同一页面中引用了两个相同的文件,那么在输出时,只有第一个文件被执行,第二个引用的文件则不会被执行)
四、文件包含漏洞防护。
1、无需情况下设置allow_url_include和allow_url_fopen为关闭。
2、对可以包含的文件进行限制,可以使用白名单的方式,或者设置可以包含的目录, 如open_basedir。
3、建议假定所有输入都是可疑的,尝试对所有输入提交可能可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现../之类的目录跳转符。
4、严格检查include类的文件包含函数中的参数是否外界可控。