在 Web 安全领域中,任意文件包含漏洞是一种较为常见且具有潜在危险性的漏洞类型。本文将详细介绍任意文件包含漏洞的概念、原理、分类、利用方法以及防护措施,帮助新手小白更好地理解和防范这一漏洞。😃
一、概念
- 包含的定义
开发人员为了提高代码的复用性,常常将重复使用的函数写在单个文件中,在需要使用这些函数时,直接调用此文件。这个过程就称为包含。 - 文件包含漏洞产生原因
在通过 PHP 函数引入文件时,如果传入的文件名未经过合理校验,就可能导致操作了预想之外的文件。这种情况下,可能会出现意外的文件泄露,甚至恶意的代码注入。 - 漏洞分类
- 本地文件包含(LFI):包含本地主机上的文件,文件名称可以是相对路径或者绝对路径。
- 远程文件包含(RFI):包含互联网上的文件,文件名称为 URL 格式。可以通过查看 php.ini 中是否开启
allow_url_include
来区分,如果开启,则可能包含远程文件。
二、相关函数
include()
:当代码执行到这个函数时,才将文件包含进来。如果发生错误,只给出一个警告,然后继续向下执行。include_once()
:功能和include()
相同,但是如果重复调用同一文件,程序只调用一次。require()
:程序一执行就立即调用脚本。如果执行发生错误,会输出错误信息并终止脚本运行。require_once()
:功能与require()
相同,重复调用同一文件时,程序也只调用一次。
三、特征与检测方法
- 特征
常见的包含形式如?page=a.php
、?home=b.html
、?file=content
等。 - 检测方法
可以尝试访问如?file=../../../../etc/passwd
、?page=file:///etc/passwd
等路径来检测是否存在漏洞。如果能够成功读取到系统文件的内容,那么很可能存在文件包含漏洞。
四、利用方法
- 本地文件包含利用
- 读取系统敏感信息:
- Windows 系统:
如: C:\boot.ini(可查看系统版本) C:\windows\system32\inetsrv\MetaBase.xml(IS 配置文件) C:\windows\repair\sam(windows 初次安装的密码) C:\program Files\mysq|\my.ini(Mysql 配置信息) C:\program Files\mysq|\data\mysq|\user.MYD(Mysql root) C:\windows\php.ini(php 配置信息)
- Linux 系统:
如: /etc/passwd(linux 用户信息) /usr/local/app/apache2/conf/httpd.conf(apache2 配置文件) /usr/local/app/php5/lib/php.ini(php 配置文件) /etc/httpd/conf/httpd.conf(apache 配置文件) /etc/my.cnf(Mysql 配置文件)
- Windows 系统:
- 配合图片马获取 shell:通过文件包含漏洞配合图片马可以获取服务器的 shell,从而进一步控制服务器。
- 常用文件路径:介绍了 apache + Linux、apache + win2003 等不同环境下的日志默认路径和配置文件路径。
- 通过绝对路径和相对路径读取配置文件:示例演示了如何使用绝对路径和相对路径读取
httpd.conf
等配置文件。
- 读取系统敏感信息:
- 远程文件包含利用
如果 php.ini 的配置选项allow_url_include
和allow_url_fopen
都为ON
,就可以加载远程文件。攻击者可以利用此漏洞直接执行任意命令。 - 伪协议利用
file://
:用于访问本地文件系统,不受allow_url_fopen
与allow_ulr_include
影响,使用方法为file://绝对路径
。php://
:可以访问各个输入 / 输出流,不受allow_url_fopen
和allow_url_include
影响。通过php://filter
参数可读取文件,还介绍了相关的筛选过滤应用和实例。php://input
:可以访问请求的原始数据的只读流,将 post 请求中的数据作为 PHP 代码执行,需要开启allow_url_include
。data://
:读取数据流且执行,自 PHP5.2.0 起有效,all_url_fopen
、allow_url_include
需要都开启才能使用。zip://
、bzip2://
、zlib://
:均属于压缩流,可以访问压缩文件中的子文件,不受all_url_fopen
、allow_url_inclued
影响。
五、防护措施
- 包含文件的参数过滤
- 文件名过滤:可以采用白名单或者黑名单过滤。白名单只允许特定的文件被包含,黑名单则禁止特定的文件被包含。
- 不使用动态变量进行包含操作,设置字典等静态处理:避免使用用户输入的动态变量进行文件包含操作,而是采用静态的字典或者预定义的文件列表进行处理。
- 文件名后缀固定:限制被包含文件的后缀,只允许特定类型的文件被包含。
- 路径限制
- 目录限制:在用户提交的变量前增加固定的路径,限制用户可调用的目录范围。
- 目录回退符过滤:避免回退符生效导致路径变化,防止用户通过回退符访问到不应该被访问的目录。
- 中间件的安全配置
- PHP 版本小于 5.4 在 php.ini 中设置 magic_quotes_gpc=on:开启这个选项可以对用户输入的数据进行一定的过滤和转义,增加安全性。
- 限制访问区域:通过 php.ini 中设置
open_basedir
限制用户访问文件的活动范围,apache 也有相关配置。 - 设置访问权限:限制当前中间件所在用户的访问权限,避免不必要的文件被访问。
总之,任意文件包含漏洞是一种需要引起高度重视的 Web 安全漏洞。开发人员和管理员应该采取有效的防护措施,以确保 Web 应用的安全性。同时,用户也应该提高安全意识,避免在不可信的网站上输入敏感信息。