什么是文件包含
为了更好地使用代码的重用性,简单来说就是,同样功能的代码,不用多次书写,当我们引入了文件包含函数,通过文件包含函数将文件包含进来,直接使用包含文件的代码,总结来说就是一个文件里面包含另外一个或多个文件
一般来说,文件包含就是把一些经常要用到的代码放在一个文件,通过在其他代码中包含这个文件来实现功能的共享
漏洞成因 & 危害
由于上文提到,在编写文件包含时,会引用到文件(文件路径),如果这个文件(文件路径)作为一个可以变化的量(攻击者可自定义)时,就会形成漏洞
因为当攻击者配合文件上传漏洞、引入恶意日志文件等手段,使其对引入文件具有控制权时,可能会传入像是 Web Shell 等对服务器产生危害的脚本或木马,使其最终拿到服务器的控制权限
高危函数
一般在 PHP 中,引发文件包含漏洞的是以下四种函数,当使用这四个函数来包含文件时,不管文件是什么类型(图片、txt 等等),都会直接作为 PHP 文件进行解析:
include() & include_once()
include()
函数会将指定的文件读入,并且执行里面的程序;include_once()
函数多了一个 once 后缀,其含义是在运行期间若文件已经被包含过,则不会重复包含和运行,其他功能与include()
函数一致
require() & require_once()
require()
函数会将目标文件的内容读入,并且把自己本身代换成这些读入的内容;require_once()
函数和require()
函数基本一致,其 once 后缀的含义也是检测是否已经被包含过,若已经被包含过则不会重复运行
include() 和 require() 的核心区别
个人建议从使用场景上去理解这两种函数,require()
函数类似 C 语言中的预处理函数,目的是提前引入某些功能;include()
函数一般会用在某些功能需要多次使用的情况下,例如代码中需要多次引入某一功能,将include()
函数放在流程控制的处理部分,当执行到它时再读取文件,可将程序流程简单化
此外,require()
如果在包含过程中出错,就会直接退出,不执行后续语句;include()
如果在包含过程中出错,只会提出警告,但不影响后续语句的执行
本地文件包含漏洞(LFI)
当被包含的文件在服务器本地时,就形成本地文件包含。此时仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击者更多的会包含一些固定的系统配置文件,从而读取系统敏感信息,很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力
远程文件包含漏洞(RFI)
当被包含的文件在第三方服务器时,叫做远程文件包含,当php.ini(PHP配置文件)
中配置选项allow_url_fopen
和allow_url_include
均为开启状态(On)的话,则包含的文件可以是第三方服务器中的文件,这样就形成了远程文件包含漏洞,使得能够通过 URL 地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,对服务器产生较大的危害
本地与远程文件包含漏洞的核心差别
从攻击者的视角来看,它们核心差别在于敏感信息的来源在哪里,在研究本地文件包含漏洞时,所有我们可利用的敏感文件或木马,一定都来自于本地;而研究远程文件包含漏洞时,文件来源既可以来源于本地,也可以来源于远程,一般情况下远程文件漏洞包含也比较少见,但两者间漏洞原理基本相同,只是引用的文件来源不同
利用方法
-
结合敏感的配置文件,获取目标敏感信息 -
配合 Web Shell 提权(将在文件上传部分演示) -
利用 PHP 伪协议(封装协议)进行攻击
总结
本文主要是介绍了 PHP 中文件包含漏洞的漏洞危害和漏洞成因,因为 Pikachu 靶场由 PHP 编写,所以仅介绍 PHP 相关内容,但并不代表只有 PHP 才存在此类漏洞,像是 JSP 也会存在此类漏洞,只不过漏洞种类和产生机理不同,最后推荐一下个人认为值得一看的学习文章和 PHP 伪协议扩展学习的文章
-
PHP伪协议总结 -
WEB安全梳理-文件包含 -
浅谈文件包含漏洞 -
结合 Pikachu 和 DVWA 靶场学习文件包含漏洞
原文始发于微信公众号(天禧信安):【Pikachu 靶场精讲】File Inclusion—前置知识
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论