php伪协议

  • PHP 伪协议(PHP Streams)是 PHP 提供的一种机制,允许你以不同的方式访问和操作文件和其他数据流。伪协议使得 PHP 可以处理各种数据源,例如文件系统、网络连接、内存等,使用统一的接口进行读取和写入操作。伪协议是通过 php:// 开头的特殊 URI 实现的。

    常见的 PHP 伪协议

    1. php://input

      • 用途: 读取原始的 POST 数据。

      • 特性: 只可读一次,用于获取来自 HTTP 请求的原始数据流。例如,处理 application/x-www-form-urlencodedmultipart/form-data 编码的数据。

      • 示例:

        1
        $rawData = file_get_contents('php://input');
    2. php://output

      • 用途: 写入到 HTTP 响应流中。

      • 特性: 可以将数据直接发送到客户端,通常用于输出内容。

      • 示例:

        1
        2
        3
        $handle = fopen('php://output', 'w');
        fwrite($handle, "Hello, World!");
        fclose($handle);
    3. php://temp

      • 用途: 临时文件流,存储在内存中,当数据超过一定大小时自动写入到磁盘。

      • 特性: 适用于处理不确定大小的数据。

      • 示例:

        1
        2
        3
        4
        5
        $handle = fopen('php://temp', 'r+');
        fwrite($handle, "Temporary data");
        rewind($handle);
        $content = fread($handle, 1024);
        fclose($handle);
    4. php://memory

      • 用途: 完全存储在内存中的文件流。

      • 特性: 数据不会写入磁盘,适用于需要高效读写的小数据量。

      • 示例:

        1
        2
        3
        4
        5
        $handle = fopen('php://memory', 'r+');
        fwrite($handle, "In-memory data");
        rewind($handle);
        $content = fread($handle, 1024);
        fclose($handle);
    5. php://filter

      • 用途: 应用过滤器对流进行转换,例如编码、解码、加密等。

      • 特性: 可以在读取或写入数据时应用多种过滤器。

      • 示例:

        • Base64 编码:

          1
          $encodedContent = file_get_contents('php://filter/convert.base64-encode/resource=example.txt');
        • Base64 解码:

          1
          $decodedContent = file_get_contents('php://filter/read=string.base64//path/to/base64file.txt');
    6. php://stdin

      • 用途: 读取标准输入(通常用于命令行环境)。

      • 特性: 从标准输入流读取数据。

      • 示例:

        1
        $input = file_get_contents('php://stdin');
    7. php://stdout

      • 用途: 写入标准输出(通常用于命令行环境)。

      • 特性: 将数据写入标准输出流。

      • 示例:

        1
        file_put_contents('php://stdout', "Hello, CLI World!");
    8. php://stderr

      • 用途: 写入标准错误输出(通常用于命令行环境)。

      • 特性: 将数据写入标准错误流。

      • 示例

        :

        1
        file_put_contents('php://stderr', "An error occurred!");

    使用示例

    • 读取文件内容:

      1
      $content = file_get_contents('php://input');
    • 写入数据:

      1
      2
      3
      $handle = fopen('php://output', 'w');
      fwrite($handle, "Data to output");
      fclose($handle);
    • 临时数据处理:

      1
      2
      3
      4
      5
      $tempFile = fopen('php://temp', 'r+');
      fwrite($tempFile, "Temporary data");
      rewind($tempFile);
      $data = fread($tempFile, 1024);
      fclose($tempFile);
    • 数据编码:

      1
      $encoded = file_get_contents('php://filter/convert.base64-encode/resource=somefile.txt');

    例:

    [SWPUCTF 2021 新生赛]include

img

尝试用get方法/?file=1

得到源码:

img

分析:

由于 ‘allow_url_include’ 被设置为 ‘on’,所以可以从远程 URL 包含文件。如果 URL 中包含了 file=flag.php 参数,脚本会尝试包含 flag.php 文件。所以这里我们构造php伪协议

php://filter/convert.base64-encode/resource=flag.php 得到base64编码的flag.php里的内容

NSSCTF{ca866ccd-2a9d-4ef7-b74b-44026fcf8887}