文件包含
开发人员常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程就叫做包含。
文件包含漏洞 通常出现在动态网页中,有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,比如:对传入的文件名没有经过合理的校验,或者校检被绕过,就导致攻击者可以通过修改文件的位置来让后台包含任意文件,从而导致文件包含漏洞。
常用的文件包含函数
include()
找不到被包含的文件时只会产生警告,脚本将继续运行。include_once()
与include()唯一区别是如果该文件中的代码已经被包含,则不会再次包含,毕竟 once 呀。require()
找不到被包含的文件会产生致命错误并停止脚本运行。require_once()
与require()唯一区别是如果该文件中的代码已经被包含,则不会再次包含,毕竟 once 呀。
此外还有两种特性:
- 若文件内容符合 PHP 语法规范,包含时不管扩展名是什么都会被 PHP 解析。
- 若文件内容不符合 PHP 语法规范则会暴漏其源码。
文件包含分类
主要分为本地和远程两种类型,分类取决于文件位置。两种分类依赖于 php.ini 中的两个配置项,对配置进行更改时,注意 On / Off 开头需大写,其次,修改完配置文件后务必要重启 Web 服务,使其配置文件生效。
判断服务器类型
读取文件
尝试读取 /ect/passwd, 如果可行,则代表操作系统为 Linux, 否则为 Windows(不是百分百正确)。
大小写混写
在 Linux 中严格区分大小写,而 Windows 中则不区分大小写。
文件包含协议
file://
- 条件:allow_url_fopen: 不受影响,allow_url_include: 不受影响。
- 作用:访问本地文件系统。
file:// 是 PHP 使用的默认封装协议,展现了本地文件系统。PHP 在读写本地文件时,默认就是使用这个协议,所以大部分时候你写代码(如 fopen("test.txt"))并不需要显式地写上 file://,PHP 会自动帮你加上。
例子:
file:///etc/passwd
file://C:/Windows/win.ini
php://
- 条件:allow_url_fopen:不受影响,allow_url_include:仅 php://input、 php://stdin、php://memory、php://temp 需要 on。
- 作用:访问各个输入/输出流(I/O streams)
协议
| 协议 | 作用 |
|---|---|
| php://input | 可以访问请求的原始数据的只读流。 |
| php://output | 只写的数据流,允许你以 print 和 echo 一样的方式写入到输出缓冲区。 |
| php://fd | (>=5.3.6) php://fd 允许直接访问指定的文件描述符。 |
| php://memory php://temp | (>=5.1.0) 类似文件包装器的数据流,允许读写临时数据。两者的一个区别是 php://memory 总是把数据储存在内存中,而 php://temp 会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。 |
| php://filter | (>=5.0.0) 元封装器, 设计用于数据流打开时的筛选过滤应用。 |
input: 想象你收到一个快递:
平时你收到快递,家人可能已经帮你拆开包装,把东西整理好了(这就是 $_POST)。
php://input 是那个还没拆封的原始包裹,里面是什么就是什么。
限制:如果是超大件快递(文件上传),快递站不让直接看原始包裹。
output: 就像你在公开场合讲话:
echo "Hello" 和 print "World" 就像直接开口说话。
php://output 就是你手里的那个话筒,你对着它说,所有人都能听到。
fd: 想象你有一个带编号的文件柜:
每个文件都有一个编号(文件描述符)。
php://fd/3 就是说:"给我 3 号抽屉里的文件"。
memory or temp: 临时笔记本
php://memory - 小抄本
就像你随身带的小笔记本。
所有内容都记在内存里,速度快。
但空间有限(受内存限制)。
php://temp - 智能笔记本
开始也用内存(前2MB)。
内容太多时,自动存成临时文件。
就像小本子写满了,就换成大文件夹。
filter: 数据加工流水线
想象你要处理原材料
没有过滤器的情况:原材料 → 直接使用
有 php://filter 的情况:原材料 → [编码器] → [转换器] → [过滤器] → 加工后的产品
data://
- 条件:allow_url_fopen:on, allow_url_include: on
- 作用:自 PHP>=5.2.0 起,可以使用 data:// 数据流封装器,以传递相应格式的数据。通常可以用来执行 PHP 代码。
data:// 就是把数据本身当成"文件"来用,省去了创建真实文件的步骤。
用法:
data://text/plain,<?php phpinfo();
data://text/plain;base64,[Base64编码后的代码]
先到这了,先消化一下,做做题理解一下……