PHP代码审计----2、文件包含


使用include()、include_once()、require()、require_once()时,当文件内容为php代码时,那么任何扩展名都可以被PHP解析,文件内容包含非PHP语法规范源文件时,将会暴露其源代码。
fopen()、readfile()、show_source()、highlight_file()、file_get_contents会造成敏感文件被读取。

1、include()、require()

通过 include 或 require 语句,可以将 PHP 文件的内容插入另一个 PHP 文件(在服务器执行它之前)。

include 和 require 语句是相同的,除了错误处理方面:
require 会生成致命错误(E_COMPILE_ERROR)并停止脚本;
include 只生成警告(E_WARNING),并且脚本会继续。

如果对包含的文件没有进行过滤和限制,就会导致文件包含漏洞。

2、include_once()、reuqire_once()

include_once()和 include() 语句类似,唯一区别是如果该文件中的代码已经被包含了,则不会再次包含。
require_once 语句和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。
如果对包含的文件没有进行过滤和限制,就会导致文件包含漏洞。

3、fopen()

fopen() 函数打开文件或者 URL。如果打开失败,本函数返回 FALSE。

语法
fopen(filename,mode,include_path,context)

filename:必需。规定要打开的文件或 URL。
mode:必需。规定要求到该文件/流的访问类型。可能的值见下表。
include_path:可选。如果也需要在 include_path 中检索文件的话,可以将该参数设为 1 或 TRUE。
context:可选。规定文件句柄的环境。Context 是可以修改流的行为的一套选项。

例子:

<?php
$file = fopen("test.txt","r");
$file = fopen("/etc/passwd","r");
$file = fopen("/etc/passwd","wb");
$file = fopen("http://www.example.com/","r");
$file = fopen("ftp://user:password@example.com/test.txt","w");
?>

如果对fopen传入的文件或者url没有进行过滤或者限制,那么此时我们可以理论上是可以打开任何存在的文件的。
fopen() 将 filename 指定的名字资源绑定到一个流上。如果 filename 是 “scheme://…” 的格式,则被当成一个 URL,PHP 将搜索协议处理器(也被称为封装协议)来处理此模式。如果该协议尚未注册封装协议,PHP 将发出一条消息来帮助检查脚本中潜在的问题并将 filename 当成一个普通的文件名继续执行下去。
如果 PHP 认为 filename 指定的是一个本地文件,将尝试在该文件上打开一个流。该文件必须是 PHP 可以访问的,因此需要确认文件访问权限允许该访问。如果激活了安全模式或者 open_basedir 则会应用进一步的限制。
如果 PHP 认为 filename 指定的是一个已注册的协议,而该协议被注册为一个网络 URL,PHP 将检查并确认 allow_url_fopen 已被激活。如果关闭了,PHP 将发出一个警告,而 fopen 的调用则失败。

4、readfile()

readfile() 函数输出一个文件。该函数读入一个文件并写入到输出缓冲。若成功,则返回从文件中读入的字节数。若失败,则返回 false。

语法:
readfile(filename,include_path,context)

filename:必需。规定要读取的文件。
include_path:可选。如果也想在 include_path 中搜索文件,可以使用该参数并将其设为 true。
context:可选。规定文件句柄的环境。Context 是可以修改流的行为的一套选项。

例子:

<?php
echo readfile("test.txt");
?>

成功,返回字节数:我们可以通过字节数去判断一些文件是否存在。
失败,返回报错信息:我们可以通过报错信息去查看是否存在信息泄露。报错信息可以通过 @readfile() 形式调用该函数进行隐藏。
如果在 php.ini 文件中 “fopen wrappers” 已经被激活,则在本函数中可以把 URL 作为文件名来使用。

5、show_source()函数和highlight_file()函数

show_source():函数对文件进行语法高亮显示。
highlight_file():函数对文件进行语法高亮显示。
show_source()是highlight_file() 的别名。
语法:
highlight_file(filename,return)
filename:必需。要进行高亮处理的php文件的路径
return:可选。如果设置 true,则本函数返回高亮处理的代码。

在使用 show_source() 函数和highlight_file() 函数时,不要因为疏忽而泄露诸如密码或其他类型的敏感信息,否则会出现潜在的安全风险。

6、file_get_contents()

file_get_contents() 函数把整个文件读入一个字符串中。和 file() 一样,不同的是 file_get_contents() 把文件读入一个字符串。
file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。

语法
file_get_contents(path,include_path,context,start,max_length)
 
path:必需。规定要读取的文件。
include_path:可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
context:可选。规定文件句柄的环境。context是一套可以修改流的行为的选项。若使用 null,则忽略。
start:可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
max_length:可选。规定读取的字节数。该参数是 PHP 5.1 新加的。

例子:

<?php
echo file_get_contents("test.txt");
?>

7、防御方法

1.严格判断包含的参数是否外部可控,因为文件包含漏洞利用成功与否的关键点就在于被包含的文件是否可被外部控制;
2.路径限制:限制被包含的文件只能在某一文件夹内,一定要禁止目录跳转字符,如:“…/”;
3.包含文件验证:验证被包含的文件是否是白名单中的一员;
4.尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include(“head.php”);。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七天啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值