"文件包含漏洞"(File Inclusion Vulnerability)是一种常见的Web应用程序漏洞,攻击者可以通过这个漏洞在目标系统上包含或执行任意文件。主要有两种类型的文件包含漏洞:
-
本地文件包含(Local File Inclusion, LFI):攻击者利用LFI漏洞可以包含并执行服务器上的本地文件,攻击者可以读取系统上的敏感文件,甚至可能执行代码。
-
远程文件包含(Remote File Inclusion, RFI):攻击者利用RFI漏洞可以从远程服务器上包含并执行文件,这通常用于注入恶意代码,以便获取目标系统的控制权。
常见场景:
1. 动态页面加载
应用程序通过用户输入的参数来加载不同的页面或模板。这种场景下,如果没有正确验证和过滤用户输入,就会产生文件包含漏洞。
2. 配置文件包含
应用程序通过配置文件来包含不同的设置文件。如果这些配置文件的路径可以由用户控制且未进行适当验证,就可能产生漏洞。
3. 动态语言文件包含
应用程序根据用户的语言偏好加载不同的语言文件。如果语言文件的路径可以被用户控制,且没有进行适当的验证,可能产生漏洞。
4. 图片或媒体文件包含
一些应用程序允许用户上传文件,并在之后的某个地方包含这些文件进行处理。如果文件名或路径可以由用户控制且未验证,可能产生漏洞。
5. 调试或日志文件包含
开发者在调试或记录日志时,可能会动态包含文件以便于查看。如果这些文件的路径可以由用户控制且未验证,可能产生漏洞。
接着我们也是使用pikachu靶场中的文件包含漏洞进行演示,阐述文件包含漏洞的原理与利用;本文我们主要对本地文件包含漏洞的利用与产生原理以及文件上传漏洞与文件包含漏洞结合利用的方式进行阐述,远程文件包含留在下一篇中说明。
示例:
Ⅰ.本地文件包含
1.打开靶场相关页面,可以看到一个下拉选项的框框;选择某个选项,页面中就会显示对应球星的信息;但是通过URL可以看出来页面在进行数据请求的时候,还访问了另外一个php代码(file1.php)。
因为访问的php文件的文件名后面有一个数字1,那么此时我们通过BP的爆破功能针对访问的php文件名进行爆破尝试,将file后的数字设置为变量进行爆破。
此处的payload选择可以选择BP自带的Number模式,进行数字输入:此处我们选择的数字范围为1-10
至此获得到file1-file10.php请求的响应页面:此时发现请求file1-file5.php文件时显示的都是球星的照片,但是在请求file6.php时显示了类似账户密码信息:
file7.php后的文件则都是报错:
但是从报错的内容中我们可以看到当前访问的页面文件在服务器中的绝对路径,那么这个时候我们就可以尝试读取当前服务器中的任意文件;如这个时候我们可以根据报错给出的信息找到服务器中的hosts文件(笔者这边是使用Windows进行靶场搭建);一下则是hosts文件对于当前页面文件的相对路径:
C:/../../../../../Windows/System32/drivers/etc/hosts
这个时候我们进行访问的url为:
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=C:/../../../../../Windows/System32/drivers/etc/hosts&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
查看效果:此时hosts文件中的内容就被读取显示值页面中。
这个时候我们根据代码剖析一下漏洞产生原理:
$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){$filename=$_GET['filename'];include "include/$filename";//变量传进来直接包含,没做任何的安全限制
// //安全的写法,使用白名单,严格指定包含的文件名
// if($filename=='file1.php' || $filename=='file2.php' || $filename=='file3.php' || $filename=='file4.php' || $filename=='file5.php'){
// include "include/$filename";
// }
}
这段代码涉及用户输入的文件名并包含该文件的操作;如果用户通过GET请求传递了一个文件名,代码会尝试包含位于include
目录下的相应文件。
include "include/$filename";
:包含位于include
目录下的文件,文件名由用户通过GET参数提供;如果$filename
的值是test.php
,那么实际执行的代码将是include "include/test.php";
。
在许多编程语言中,特别是PHP中,文件包含功能常用于动态加载代码或模板。然而,如果不加以注意,文件包含功能可能会导致严重的安全漏洞,主要的文件包含漏洞产生的相关函数:
①include:用于包含并运行指定文件;如果文件不存在或包含错误,脚本会继续执行,并发出一个警告。 ②require:与include类似,但如果文件不存在或包含错误,脚本会终止执行并发出一个致命错误。 ③include_once:include_once函数与include相同,但如果文件已包含过,则不会再次包含。 ④require_once:require_once函数与require相同,但如果文件已包含过,则不会再次包含。
include和require函数报错的区别:
如果include执行错误则后续代码还会继续执行;而若是require执行错误后续代码不会继续执行了;include和require的使用效果:
include "C:/../../../../../Windows/System32/drivers/etc/hosts";
require "C:/../../../../../Windows/System32/drivers/etc/hosts";
在require和include包含某个文件后,则会将文件内容进行输出(若是php文件则会直接执行);以下为执行效果:
文件上传+文件包含GetShell
若是文件包含漏洞与文件上传漏洞同时存在,则可以轻松getshell了;因为此时我们可以将php木马转化为图片的形式以绕过相关过滤,并且可以指定图片马的路径进行包含最后GetShell;此时我们将靶场中的这两个漏洞进行结合利用:
1.上传图片马:生成图片马并进行上传;在这里我们先来说一下如何生成片马;首先我们要准备一个木马代码文件和一张图片文件:
接着我们使用copy命令将木马代码嵌入图片中:
copy /B 头像.jpeg + /A 新建文本文档.txt PiTr.jpg
这串命令会将将 头像.jpeg
和 新建文本文档.txt
合并为一个新文件 PiTr.jpg
;头像.jpeg
按二进制模式复制,这意味着每个字节都被准确复制;新建文本文档.txt
按ASCII模式复制,这意味着它将按文本模式处理,但由于目标是图像文件,文本内容将被附加到图片文件的末尾。
接着我们进行上传,顺便抓个包:
可以看到木马代码就在文件末尾,接着我们就需要将此时的图片马所在文件拼接出来:
http://127.0.0.1/pikachu/vul/unsafeupload/uploads/PiTr.jpg
接着根据上面爆破file1-10.php时获得到的报错路径推测相对于文件包含漏洞页面代码的相对路径;以下就是报错得到的路径:
根据相同的目录名我们基本上可以推测出此时图片马在服务器中的路径为:
D:/phpstudy_pro/www/pikachu/vul/unsafeupload/uploads/PiTr.jpg
那么此时的相对路径就是:
../../unsafeupload/uploads/PiTr.jpg
接下去来到文件包含漏洞中修改包含文件路径为图片马的相对路径,此时我们访问的url为:
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/PiTr.jpg&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
这个时候的页面效果:页面中出现了乱码,实际上就是图片中的标识头。
这个时候我们就可以直接通过WebShell连接工具进行连接GetShell了;
至此漏洞利用成功。