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);
}
相关推荐
Java源头2 小时前
PHP 身份证二要素检测
开发语言·php
祁白_2 小时前
无字母数字 Webshell 绕过
笔记·web安全·测试·ctf
yoyo_zzm2 小时前
PHP vs Java:后端语言终极选择指南
java·spring boot·后端·架构·php
yoyo_zzm4 小时前
五大编程语言对比:PHP、C、C++、C#、易语言
c语言·c++·php
不会摸鱼的小鱼1 天前
WSL 安装 Ubuntu 22.04 到指定磁盘
数据库·postgresql·php
淼淼爱喝水1 天前
DVWA和Pikachu命令注入漏洞检测实验
安全·web安全·php·pikachu·dvwa
专注VB编程开发20年1 天前
json和python元组,列表,字典对比
开发语言·python·json·php
怀旧,1 天前
【Linux网络编程】15. Reactor 反应堆模式
linux·网络·php
Dylan的码园1 天前
2026年免费远程控制软件哪个好?ToDesk向日葵UU远程免费版横评,不限次数不限时长
服务器·开发语言·php
dog2501 天前
解析几何的力量(1)
服务器·开发语言·网络·php