文件包含漏洞
文件包含漏洞
文件包含漏洞是一个非常简单,容易上手的一个漏洞
文件包含概述
开发人员常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。
比如 C语言 中的 include 将 stdio.h 文件中的代码包含到当前文件中,从而实现标准输入输出。
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
文件包含漏洞 通常出现在动态网页中,有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,比如:对传入的文件名没有经过合理的校验,或者校检被绕过,就导致攻击者可以通过修改文件的位置来让后台包含任意文件,从而导致文件包含漏洞。
大多数 Web 语言都支持文件包含操作,其中 PHP 语言所提供的文件包含功能太强大、太灵活,也就导致文件包含漏洞经常出现在 PHP 语言中。
在 PHP 中常用的文件包含函数有以下四种:
require():找不到被包含的文件会产生致命错误,并停止脚本运行
include():找不到被包含的文件只会产生警告,脚本继续执行
require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
当以上 四种函数 参数可控的情况下,我们需要知道以下两点特性:
若文件内容符合 PHP 语法规范,包含时不管扩展名是什么都会被 PHP 解析。
若文件内容不符合 PHP 语法规范则会暴漏其源码
本地文件包含
在文件包含中,主要分为 本地 和 远程 两种类别,分类取决于所包含文件位置的不同。这两种分类依赖于 php.ini 中的两个配置项,注意对配置进行更改时,注意 On / Off 开头需大写,其次,修改完配置文件后务必要重启 Web 服务,使其配置文件生效。
allow_url_fopen (默认开启)
allow_url_include #(默认关闭,远程文件包含必须开启)
能够打开并包含本地文件的漏洞,我们称为本地文件包含漏洞(LFI)
如下代码
<?php
highlight_file(__FILE__);
$file=$_GET['file'];
include $file;
?>
利用该代码,我们可以读取一些系统本地的敏感信息。
例如:C:\Windows\system.ini文件。

常见的敏感信息路径如下:
Windows下常见敏感文件
目录 内容
\boot.ini 系统版本信息
\xxx\php.ini PHP配置信息
\xxx\my.ini MYSQL配置信息
\xxx\httpd.conf Apache配置信息
Linux下常见敏感文件
目录 内容
/etc/passwd Linux系统账号信息
/etc/httpd/conf/httpd.conf Apache配置信息
/etc/my.conf MySQL配置信息
/usr/etc/php.ini PHP配置信息
远程文件包含(RFI)
如果PHP的配置选项allow_url_include、allow_url_fopen状态为ON的话,则include/require函数是可以加载远程文件的,这种漏洞被称为远程文件包含(RFI)
伪协议
PHP 伪协议允许开发者通过指定不同的输入源来读取、处理和引入数据,这一特性在文件包含漏洞(如 include 或 require)中被滥用,导致攻击者能够通过伪协议来读取敏感数据或执行恶意代码。
以下是在文件包含漏洞中常用的伪协议。
php://input
攻击者可以通过伪协议 php://input 读取 POST 数据并将其作为包含文件的内容。这允许攻击者上传或注入恶意代码,导致代码执行。
用法:?file=php://input+post包


file://
用于访问本地文件系统。
file:// 是 PHP 使用的默认封装协议,展现了本地文件系统。 当指定了一个相对路径(不以/、\、\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录。 在很多情况下是脚本所在的目录,除非被修改了。 使用 CLI 的时候,目录默认是脚本被调用时所在的目录。

php://filter
通过 php://filter 伪协议,攻击者可以将目标文件的内容以编码的形式返回,这使得攻击者可以读取敏感文件的内容
该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:
名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
攻防世界fileclude

/?file1=php://filter/read=convert.base64-encode/resource=flag.php&file2=data://text/plain,hello ctf

data://
攻击者可以使用 data:// 伪协议注入任意代码并执行。

?file=data://text/plain,<?php system("ls"); ?>

日志包含
我们之前提到过:若文件内容符合 PHP 语法规范,包含时不管扩展名是什么都会被 PHP 解析。
若文件内容不符合 PHP 语法规范则会暴漏其源码
应用程序将用户提交的数据(如HTTP请求头、参数、URL等)直接记录到日志文件中,且未对特殊字符(如../、<?php ?>等)进行过滤或转义。
如果应用程序存在文件包含漏洞(如PHP的include()、require()函数),攻击者可能通过包含日志文件(如/var/log/apache2/access.log)来执行注入的恶意代码。
访问日志的位置和文件名在不同的系统上会有所差异
apache一般是/var/log/apache/access.log。
nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log
来举个例子
ctfshow 萌新web19
用插件可以看出服务器类型为Nginx

查看日志文件
?c=/var/log/nginx/access.log

发现其日志文件中写入了user-agent了信息,那么我们在提交请求的时候可以在user--agent中写入木马

蚁剑连接

总结
文件包含漏洞是一个非常简单,容易上手的一个漏洞,学会了就可以解决很多文件包含漏洞的题了。
总之不要相信用户的输入
是的孩子们我回来了


浙公网安备 33010602011771号