(1)文件包含原理
程序在引用文件的时候,引用的文件名,用户可控的情况下,传入的文件名没有经过合理的校验或者校验不严,从而操作了预想之外的文件,就有可能导致文件泄露和恶意的代码注入。程序开发者一般会把重复使用的函数写道单个文件中莫须有使用某个函数时直接调用次文件,而无需再次编写,这重文件调用的过程一般称为文件包含。程序开发者一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但正是这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
(2)代码分析
$_GET['filename']接收客户端传的参数,其中没有任何过滤,带入到include函数中,include包含这个文件,引到当前文件中,因此造成文件包含漏洞。
(3)函数
函数require、include、include_once、require_once。include和require区别主要是include在包含过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。include_once()、require_once()这两个函数,与前两个不同之处在于这两个函数只包含一次,适用于脚本执行期间同一个文件有可能被包括吵过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。
(4)类型
本地文件包含、文件包含图片、包含日志文件、包含环境变量、PHP info文件包含临时文件、包含远程文件、文件包含截断攻击、文件包含%00截断、超长文件包含截断、远程包含截断。
(5)伪协议
file://访问本地文件系统 http://访问HTTP(s)网址 ftp://访问FTP(s)URLs
php://访问各个输入/输出流(I/O streams) zlib://压缩流 data://数据
glob:// 查找匹配的文件路径模式 phar:// PHP归档 ssh2:// Secure Shell 2
rar:// RAR ogg://音频流 expect://处理交互式的流
(6)文件包含常用路径
包含日志文件getshell
读取网站配置文件
包含系统文件
包含Linux文件
(7)防御方案
严格判断包含中的参数是否外部可控
路径限制:限制被包含文件只能在某一文件内,一定要禁止目录跳转字符
包含文件验证:验证被包含的文件是否时白名单中的一员
进来不要使用动态包含,可以在需要包含的页面固定写好
设置allow_url_include为off