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

本文阅读 7 分钟

使用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”);。

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/118493791
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复