文件包含漏洞

文件包含漏洞

文件包含漏洞是一个非常简单,容易上手的一个漏洞

文件包含概述

开发人员常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。

比如 C语言 中的 includestdio.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文件。

image

常见的敏感信息路径如下:

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_includeallow_url_fopen状态为ON的话,则include/require函数是可以加载远程文件的,这种漏洞被称为远程文件包含(RFI)

伪协议

PHP 伪协议允许开发者通过指定不同的输入源来读取、处理和引入数据,这一特性在文件包含漏洞(如 includerequire)中被滥用,导致攻击者能够通过伪协议来读取敏感数据或执行恶意代码。

以下是在文件包含漏洞中常用的伪协议。

php://input

攻击者可以通过伪协议 php://input 读取 POST 数据并将其作为包含文件的内容。这允许攻击者上传或注入恶意代码,导致代码执行。

用法:?file=php://input+post包

image

image

file://

用于访问本地文件系统。

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

image

php://filter

通过 php://filter 伪协议,攻击者可以将目标文件的内容以编码的形式返回,这使得攻击者可以读取敏感文件的内容

该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:

名称							描述
resource=<要过滤的数据流>		这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表>			该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表>			该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表>				任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

攻防世界fileclude

image

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

image

data://

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

image

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

image

日志包含

我们之前提到过:若文件内容符合 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

image

查看日志文件

?c=/var/log/nginx/access.log

image

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

image

蚁剑连接

image

总结

文件包含漏洞是一个非常简单,容易上手的一个漏洞,学会了就可以解决很多文件包含漏洞的题了。

总之不要相信用户的输入

是的孩子们我回来了

image

posted @ 2025-07-19 12:08  落山机糊人  阅读(92)  评论(0)    收藏  举报