CTF-WEB:PHP伪协议用法总结

php:// 伪协议:

php:// 是 PHP 中的一个虚拟协议(或称为流包装器),用于访问 PHP 内部流资源。它是 PHP 提供的内置流协议之一,允许你通过流(stream)方式访问 PHP 内部的数据流、文件或其他资源。与 file:// 等协议不同,php:// 并不直接映射到文件系统,而是用于处理 PHP 特有的资源,如输入输出流、临时文件、PHP 自身的内存流等。

php:// 协议是 PHP 流包装器的一部分,允许在 PHP 脚本中灵活地处理不同类型的资源。php:// 有多个子协议,它们提供不同的功能,常见的子协议有 php://inputphp://outputphp://memory 等。

1. php://input:读取原始 POST 数据

php://input 是一个只读流,用于读取原始的 POST 数据。与 $_POST 不同,php://input 允许你直接访问 HTTP 请求中提交的原始数据,特别是对于非表单数据(如 JSON、XML 或其他自定义格式的内容)非常有用。

语法:
php 复制代码
php://input
使用场景:
  • 处理 application/jsonapplication/xml 类型的请求体,直接读取原始数据而不通过 PHP 的 $_POST 全局数组。
  • 读取大数据量的流数据,避免将其加载到内存中。
示例:读取 JSON 格式的请求体
php 复制代码
// 假设接收到的 POST 数据是一个 JSON 字符串
$json_data = file_get_contents("php://input");
$data = json_decode($json_data, true);
print_r($data);

在这个例子中,file_get_contents("php://input") 会读取 HTTP 请求体中的原始数据(例如,一个 JSON 字符串)。然后,使用 json_decode() 解析数据。

注意

  • php://input 只能读取一次,因为它是流的形式,读取后就无法再次访问相同的数据。因此,如果需要多次处理请求体,应该将其数据存储到一个变量中。
  • 它只能用于读取原始数据,不能像 $_POST 数组一样处理表单数据。

2. php://output:输出流

php://output 是一个写入流,允许你将数据直接写入到 PHP 的输出缓冲区。这意味着你可以将内容写入 HTTP 响应,而不需要直接使用 echoprint

语法:
php 复制代码
php://output
使用场景:
  • 动态构建响应内容并将其输出到浏览器,而不是立即发送数据。
  • ob_start()ob_get_contents() 配合使用,缓存输出内容并在需要时发送到浏览器。
示例:将数据写入 php://output
php 复制代码
// 打开 php://output 流
$output = fopen('php://output', 'w');
fwrite($output, "Hello, this is written to output.\n");
fclose($output);

在这个例子中,php://output 被用作一个写入流,将字符串写入 PHP 输出缓冲区。数据随后会发送到浏览器。

3. php://memory:内存中的临时文件

php://memory 是一个内存流,允许你在内存中创建一个临时文件。这类似于操作文件,但数据存储在内存中,不会写入磁盘。

语法:
php 复制代码
php://memory
使用场景:
  • 当你需要快速读写临时数据,且不希望占用磁盘空间时,可以使用 php://memory
  • 适用于需要快速操作的小型数据集,如缓存、临时存储等。
示例:使用 php://memory 创建一个内存中的文件
php 复制代码
// 打开 php://memory 流进行写操作
$handle = fopen('php://memory', 'w+');
fwrite($handle, "This is some data in memory.");
rewind($handle); // 将文件指针移回文件开头
$content = fread($handle, 1024);
fclose($handle);

echo $content; // 输出:This is some data in memory.

在这个例子中,php://memory 用作内存流,可以在内存中快速读写数据。

4. php://temp:临时文件(使用内存或磁盘)

php://temp 是一个临时文件流,类似于 php://memory,但它可以根据文件大小自动切换存储方式:对于小文件,数据存储在内存中;对于较大的文件,数据会自动写入临时磁盘文件。

语法:
php 复制代码
php://temp
使用场景:
  • 处理临时数据,自动管理内存和磁盘存储。
  • 适用于需要临时存储的数据,但又不希望事先知道数据量的情况。
示例:使用 php://temp 创建一个临时文件
php 复制代码
// 打开 php://temp 流
$handle = fopen('php://temp', 'w+');
fwrite($handle, "This is a temporary file.\n");
rewind($handle);
$content = fread($handle, 1024);
fclose($handle);

echo $content; // 输出:This is a temporary file.

5.php://stdinphp://stdout

  • php://stdin:用于读取标准输入流(stdin)。这是命令行 PHP 脚本中常用的流协议。
  • php://stdout:用于向标准输出流(stdout)写入数据。在命令行环境中,通常使用它来输出信息。
示例:使用 php://stdinphp://stdout
php 复制代码
// 读取标准输入数据并写入标准输出
$input = fopen("php://stdin", "r");
$output = fopen("php://stdout", "w");

fwrite($output, "Enter some text: ");
$line = fgets($input);
fwrite($output, "You entered: " . $line);

php://filter 伪协:

php://filter 是 PHP 提供的一个特殊协议,它允许在文件流操作中应用各种过滤器。通过使用 php://filter,你可以在读取文件或写入文件时对内容进行过滤或转换。这种功能非常适用于处理压缩、加密、解密、字符编码转换等需求,而不必手动处理文件内容。

基本概念

php://filter 是通过组合流协议和过滤器来实现的。它允许你在访问文件流时应用一个或多个过滤器,过滤器可以改变数据的表现形式或内容。

语法

php://filter 的基本格式如下:

php://filter/[filter_name]/resource=[resource]
  • filter_name:过滤器的名称,指定要应用的过滤器。
  • resource:资源名称,指示操作的实际文件或流。

常见过滤器

php://filter 支持多种过滤器,它们可以用于对文件内容进行多种处理。过滤器可以分为以下几类:

1. 压缩和解压缩过滤器

这些过滤器可以将数据流进行压缩或解压缩。

  • zlib.deflate:将数据流压缩为 DEFLATE 格式(无文件扩展名)。适用于压缩文本数据。
  • zlib.gzip:将数据流压缩为 GZIP 格式。
  • zlib.gunzip:解压缩 GZIP 格式的文件。
  • bzip2.compress:将数据流压缩为 BZIP2 格式。
  • bzip2.decompress:解压缩 BZIP2 格式的文件。
示例:使用 zlib.deflate 压缩数据
php 复制代码
$compressed = file_get_contents("php://filter/zlib.deflate/resource=/path/to/file.txt");
echo $compressed;

此代码会读取 /path/to/file.txt 文件的内容,并将其压缩为 DEFLATE 格式。

2. 字符编码过滤器

这些过滤器允许你转换字符编码格式。

  • convert.iconv.* :转换字符编码格式。例如,convert.iconv.ISO-8859-1/UTF-8 将文件从 ISO-8859-1 编码转换为 UTF-8 编码。
示例:使用 convert.iconv 转换字符编码
php 复制代码
$content = file_get_contents("php://filter/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;

这会将 /path/to/file.txt 文件从 ISO-8859-1 编码转换为 UTF-8 编码。

3. 加密与解密过滤器

一些过滤器可用于对文件内容进行加密或解密操作。

  • mcrypt.encryptmcrypt.decrypt:使用 Mcrypt 库对数据进行加密或解密。
示例:使用 mcrypt 加密
php 复制代码
$encrypted = file_get_contents("php://filter/mcrypt.encrypt/resource=/path/to/file.txt");
echo $encrypted;
4. 其他常见过滤器
  • string.toupper:将文件内容转换为大写。
  • string.tolower:将文件内容转换为小写。
  • string.strip_tags:去除 HTML 标签。
  • string.rot13:将文本进行 ROT13 加密。
示例:将文件内容转换为大写
php 复制代码
$content = file_get_contents("php://filter/string.toupper/resource=/path/to/file.txt");
echo $content;

使用 php://filter 的一些示例

1. 读取并压缩文件内容

如果你想在读取文件的同时进行压缩,可以使用 php://filter 配合 zlib.deflate 过滤器:

php 复制代码
// 压缩文件内容并输出
$compressed_content = file_get_contents("php://filter/zlib.deflate/resource=/path/to/large_file.txt");
echo $compressed_content;

这段代码会读取 /path/to/large_file.txt 文件的内容,并将其压缩成 DEFLATE 格式输出。

2. 转换文件编码

假设你有一个文件使用 ISO-8859-1 编码,但你需要将其内容转换为 UTF-8 编码后读取,可以使用 convert.iconv 过滤器:

php 复制代码
$content = file_get_contents("php://filter/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;
3. 加密文件内容

如果你需要对文件内容进行加密,可以使用 mcrypt.encrypt 过滤器(注意,Mcrypt 扩展在 PHP 7.1 之后已被标记为弃用,但仍然可以在一些 PHP 版本中使用):

php 复制代码
$encrypted_content = file_get_contents("php://filter/mcrypt.encrypt/resource=/path/to/file.txt");
echo $encrypted_content;

组合过滤器

php://filter 允许你将多个过滤器组合起来使用。多个过滤器会依次应用于文件流,顺序非常重要。例如,你可以先压缩文件内容,再转换编码:

php 复制代码
// 先进行压缩,再转换字符编码
$content = file_get_contents("php://filter/zlib.deflate/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;

在这个例子中,文件内容会先被压缩,然后再从 ISO-8859-1 转换为 UTF-8 编码。

data:// 伪协议:

data:// 伪协议是 PHP 中的一种特殊协议,允许在不依赖外部文件的情况下,直接将数据嵌入到 PHP 代码中进行处理。data:// 协议常用于嵌入小型的数据内容(如文本或图像),它通过在 URL 中直接包含数据的方式,简化了文件操作的需求,尤其适用于在 Web 应用中处理嵌入式资源时的场景。

data:// 伪协议的语法

data:// 协议的基本语法如下:

data://[MIME-type];base64,[data]
  • data:// :协议标识符,表示这是一个 data 协议。
  • MIME-type :可选的 MIME 类型,指定数据的格式。例如:text/plainimage/png 等。
  • base64:如果数据是二进制数据(如图片或其他文件),则通常采用 Base64 编码。这个标识符表示数据部分是经过 Base64 编码的。
  • [data]:要嵌入的数据部分。如果数据是文本,可以直接使用;如果是二进制数据,通常需要进行 Base64 编码。

语法解释

  1. data:// 协议头:指定了这是一个数据协议。
  2. MIME-type :定义数据的类型。例如,如果是文本数据,通常是 text/plain;如果是图像,可能是 image/pngimage/jpeg 等。
  3. base64(可选):这是一个标记,表示数据是经过 Base64 编码的。Base64 编码常用于将二进制数据(如图片或文件内容)转为 ASCII 字符串,这样它就可以嵌入到 URL 中。
  4. [data]:实际的数据。文本数据直接嵌入;二进制数据需要经过 Base64 编码。

示例

1. 简单的文本数据

如果你想通过 data:// 协议嵌入一段简单的文本数据,你可以按如下方式写:

php 复制代码
$data = file_get_contents("data://text/plain,Hello%20World%21");
echo $data;  // 输出: Hello World!

在这个示例中:

  • data://text/plain,Hello%20World%21 是一个包含文本 "Hello World!" 的数据 URL。
  • text/plain 是 MIME 类型,表示这是普通的文本数据。
  • Hello%20World%21 是 URL 编码的文本,表示 Hello World!,空格被编码为 %20,感叹号被编码为 %21
2. Base64 编码的二进制数据

对于图像或其他二进制数据,你通常需要使用 Base64 编码。这是因为 data:// 协议能够传输二进制数据,但必须以文本的形式进行表示。

例如,如果你有一个小的图像文件并希望将其嵌入到 PHP 中,你首先需要将图像进行 Base64 编码:

php 复制代码
$img_data = file_get_contents('image.png');
$base64_img = base64_encode($img_data);
$data_url = "data:image/png;base64," . $base64_img;

echo $data_url;

在这个示例中:

  • file_get_contents('image.png') 读取了一个 PNG 图像文件。
  • base64_encode($img_data) 将图像数据编码为 Base64 格式。
  • data:image/png;base64,... 就是包含图像数据的 data:// URL。

如果你需要显示这个图像,可以在 HTML 中使用这个 data:// URL:

html 复制代码
<img src="data:image/png;base64,..." />

... 代表你的 Base64 编码数据,浏览器会解析并显示这个图像。

3. 小型嵌入的文本文件

如果你有一个小的文本文件,并且希望将其嵌入到 PHP 中以进行读取或操作,可以使用 data:// 协议。比如:

php 复制代码
$text = file_get_contents("data://text/plain,This%20is%20a%20test%20file");
echo $text;  // 输出: This is a test file

在这个示例中,data://text/plain,This%20is%20a%20test%20file 是一个包含文本 This is a test file 的数据 URL。

file:// 伪协议:

file:// 协议是 PHP 中用于访问文件系统的标准协议,允许你通过 URL 形式访问本地文件系统中的文件。这使得 PHP 脚本能够直接与文件交互,比如读取文件内容或写入数据。file:// 协议的核心作用是提供一个统一的接口,使得 PHP 可以在不同的文件系统中通过一致的方式进行文件操作。

file:// 语法详解

file:// 协议的基本语法如下:

file://[host]/path/to/file
  • file://:协议标识符,表示文件协议。
  • [host] (可选):在某些系统中,file:// 可以包含一个主机部分。通常这个部分对于本地文件系统来说可以忽略,特别是在 UNIX 或 Linux 系统中。
  • /path/to/file :文件路径,指定你要访问的文件的完整路径。在 Windows 系统中,路径通常以盘符开始(如 C:/path/to/file);在类 UNIX 系统(如 Linux、macOS)中,路径通常从根目录 / 开始。

1. 访问本地文件

在最常见的用法中,file:// 协议用于访问本地文件系统中的文件。你可以将文件路径通过 file:// 协议指定为 URL,从而使用诸如 file_get_contents()fopen() 等函数读取或写入文件。

1.1 UNIX 和 Linux 系统

在 UNIX 和 Linux 系统中,文件路径从根目录 / 开始。假设你有一个位于 /var/www/html/test.txt 的文件,你可以使用 file:// 协议来访问它:

php 复制代码
// 读取文件内容
$contents = file_get_contents("file:///var/www/html/test.txt");
echo $contents;
  • file:// 是协议标识符,表示这是一个本地文件访问。
  • /var/www/html/test.txt 是文件的绝对路径。
1.2 Windows 系统

在 Windows 系统中,路径通常以盘符(如 C:)开始,路径分隔符为反斜杠 \,但在 file:// 协议中,反斜杠需要转换为正斜杠 /。例如,如果文件位于 C:\xampp\htdocs\test.txt,可以用 file:// 协议访问:

php 复制代码
// 读取文件内容
$contents = file_get_contents("file:///C:/xampp/htdocs/test.txt");
echo $contents;

在这个例子中:

  • file:// 协议标识符表示本地文件。
  • C:/xampp/htdocs/test.txt 是文件的路径,注意这里的路径分隔符是 / 而不是反斜杠 \

2. 访问远程文件系统(网络共享)

在某些情况下,file:// 协议可以用于访问远程的文件系统或网络共享资源,尤其是在网络文件系统(NFS)、SMB(Samba)等协议支持的环境中。在这种情况下,file:// 协议的路径可以包含主机名和共享路径。

2.1 网络共享路径

例如,如果你需要访问一个 Windows 网络共享文件夹,路径可能如下所示:

php 复制代码
// 访问远程共享的文件夹
$contents = file_get_contents("file://192.168.1.100/shared-folder/test.txt");
echo $contents;
  • 192.168.1.100 是共享文件夹所在计算机的 IP 地址。
  • /shared-folder/test.txt 是共享文件夹中的文件路径。
2.2 Windows 文件共享(SMB)

在 Windows 网络共享中,路径格式通常为 \\server\share\path。在 file:// 协议中,反斜杠 \ 需要转换为正斜杠 /,并且前面需要加上 file:// 前缀。例如,访问一个共享文件夹时的路径可能如下:

php 复制代码
// 访问 Windows 文件共享
$contents = file_get_contents("file:server/shared-folder/test.txt");
echo $contents;

这里,//server/shared-folder/test.txt 是网络共享文件的路径,server 是共享计算机的名称。

3. 使用 file:// 协议进行文件读取

PHP 提供了多个函数来使用 file:// 协议进行文件操作,最常用的是 file_get_contents()fopen()

3.1 file_get_contents()

file_get_contents() 是 PHP 中读取文件内容的一个常用函数。你可以通过 file:// 协议指定文件路径,读取本地或远程的文件。

php 复制代码
$contents = file_get_contents("file:///path/to/file.txt");
echo $contents;

该函数读取整个文件并返回文件内容。对于大文件,可能需要使用流式读取(例如 fopen())来避免内存消耗过大。

3.2 fopen() 和其他文件操作函数

你也可以使用 fopen()fread()fwrite() 等函数进行文件操作。它们支持 file:// 协议来访问本地文件:

php 复制代码
$handle = fopen("file:///path/to/file.txt", "r");
if ($handle) {
    $contents = fread($handle, filesize("file:///path/to/file.txt"));
    fclose($handle);
    echo $contents;
}

这个例子中,fopen() 打开文件并返回文件句柄,fread() 读取文件内容,fclose() 关闭文件。

3.3 写入文件

你可以使用 file_put_contents()fopen() + fwrite() 来向文件写入数据:

php 复制代码
// 使用 file_put_contents 写入文件
file_put_contents("file:///path/to/file.txt", "Hello, World!");

或者使用 fopen()fwrite()

php 复制代码
$handle = fopen("file:///path/to/file.txt", "w");
if ($handle) {
    fwrite($handle, "Hello, World!");
    fclose($handle);
}
相关推荐
2401_857439693 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
Smile灬凉城6669 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
奥顺11 小时前
PHPUnit使用指南:编写高效的单元测试
大数据·mysql·开源·php
王ASC11 小时前
SpringMVC的URL组成,以及URI中对/斜杠的处理,解决IllegalStateException: Ambiguous mapping
java·mvc·springboot·web
黑客Jack12 小时前
网络安全加密
安全·web安全·php
龙哥·三年风水15 小时前
workman服务端开发模式-应用开发-后端api推送修改二
分布式·gateway·php
计算机徐师兄16 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
希雅不是希望17 小时前
Ubuntu命令行网络配置
网络·ubuntu·php
龙哥·三年风水20 小时前
workman服务端开发模式-应用开发-后端api推送修改一
分布式·gateway·php
开心工作室_kaic1 天前
springboot461学生成绩分析和弱项辅助系统设计(论文+源码)_kaic
开发语言·数据库·vue.js·php·apache