伪协议php:input命令执行的原理
字数 1675 2025-08-11 08:36:22

PHP伪协议php://input命令执行原理详解

1. php://input概述

php://input是一个可以访问请求原始数据的只读流,在PHP安全领域常被用于命令执行和Webshell管理。它主要用于以下场景:

  • 当请求方式是POST
  • Content-Type不等于"multipart/form-data"时
  • 可以获取原始请求的数据

在PHP 5.6.0之前,$HTTP_RAW_POST_DATA有类似功能,但已被废弃,由php://input替代。

2. $_POST与php://input的区别

2.1 $_POST数组的特性

$_POST数组仅在以下两种Content-Type时有效:

  1. application/x-www-form-urlencoded
  2. multipart/form-data

它会将变量以关联数组形式传入当前脚本。

2.2 php://input的特性

php://input可以读取原始POST数据,不受Content-Type限制(除了multipart/form-data)。它与$_POST的主要区别:

  1. 数据格式:php://input获取原始数据,$_POST获取解析后的数组
  2. 编码处理:$_POST会自动urldecode(),而php://input保持原始编码
  3. 适用范围:php://input适用于更多Content-Type

3. 不同Content-Type下的行为分析

3.1 multipart/form-data(文件上传)

示例代码

<form enctype="multipart/form-data" method="post">
  <input type="text" name="name" />
  <input type="file" name="upload_file" />
  <button type="submit">Submit</button>
</form>

<?php
var_dump($_POST); 
var_dump(file_get_contents("php://input"));
?>

结果

  • $_POST:可以接收表单内容
  • php://input:为空,不起作用

3.2 application/x-www-form-urlencoded

示例代码

<form enctype="application/x-www-form-urlencoded" method="post">
  <input type="text" name="name" />
  <button type="submit">Submit</button>
</form>

<?php
var_dump($_POST);
var_dump(file_get_contents("php://input"));
?>

结果

  • $_POST:接收解码后的表单内容
  • php://input:接收原始编码数据

URL编码差异

  • 如果数据经过多次URL编码,$_POST会解码一次,而php://input保持原始编码

3.3 application/json

特点

  • $_POST无法处理JSON格式数据
  • 必须使用php://input读取原始数据

4. 命令执行原理

php://input本身不能直接导致命令执行,关键在于它与哪些函数结合使用:

4.1 文件包含漏洞

<?php
include($_GET['file']);
?>

利用方式:

  1. 参数:?file=php://input
  2. POST body中写入PHP代码

4.2 直接代码执行

<?php
eval(file_get_contents("php://input"));
?>

利用方式:

  • 直接在POST body中写入PHP代码(无需<?php ?>标签)

4.3 其他危险函数组合

任何将php://input内容作为PHP代码解析的函数组合都可能导致RCE,例如:

  • assert()
  • create_function()
  • preg_replace()的/e修饰符

5. 实际利用案例

5.1 Webshell管理工具

许多Webshell管理工具利用php://input特性:

  • 冰蝎4默认shell就使用了类似技术
  • 其他常见Webshell管理工具也普遍支持

5.2 绕过限制

php://input可以:

  1. 绕过某些WAF对$_POST的过滤
  2. 传输非标准格式的数据
  3. 在无法使用常规POST方式时执行代码

6. 防御措施

  1. 禁用危险函数:eval, assert, create_function
  2. 严格过滤输入:特别是文件包含的参数
  3. 使用白名单:限制允许的协议和内容类型
  4. 更新PHP版本:新版PHP对某些危险特性有改进
  5. 配置php.ini:限制allow_url_include等设置

7. 总结

php://input伪协议在PHP安全中扮演重要角色,理解其工作原理对于:

  • 安全人员:识别和防御相关攻击
  • 开发人员:避免引入相关漏洞
  • 渗透测试人员:利用相关特性进行测试

关键点在于认识到php://input与危险函数组合时可能导致代码执行,而不仅仅是数据读取功能。

PHP伪协议php://input命令执行原理详解 1. php://input概述 php://input 是一个可以访问请求原始数据的只读流,在PHP安全领域常被用于命令执行和Webshell管理。它主要用于以下场景: 当请求方式是POST Content-Type不等于"multipart/form-data"时 可以获取原始请求的数据 在PHP 5.6.0之前, $HTTP_RAW_POST_DATA 有类似功能,但已被废弃,由 php://input 替代。 2. $_ POST与php://input的区别 2.1 $_ POST数组的特性 $_POST 数组仅在以下两种Content-Type时有效: application/x-www-form-urlencoded multipart/form-data 它会将变量以关联数组形式传入当前脚本。 2.2 php://input的特性 php://input 可以读取原始POST数据,不受Content-Type限制(除了multipart/form-data)。它与 $_POST 的主要区别: 数据格式: php://input 获取原始数据, $_POST 获取解析后的数组 编码处理: $_POST 会自动urldecode(),而 php://input 保持原始编码 适用范围: php://input 适用于更多Content-Type 3. 不同Content-Type下的行为分析 3.1 multipart/form-data(文件上传) 示例代码 : 结果 : $_POST :可以接收表单内容 php://input :为空,不起作用 3.2 application/x-www-form-urlencoded 示例代码 : 结果 : $_POST :接收解码后的表单内容 php://input :接收原始编码数据 URL编码差异 : 如果数据经过多次URL编码, $_POST 会解码一次,而 php://input 保持原始编码 3.3 application/json 特点 : $_POST 无法处理JSON格式数据 必须使用 php://input 读取原始数据 4. 命令执行原理 php://input 本身不能直接导致命令执行,关键在于它与哪些函数结合使用: 4.1 文件包含漏洞 利用方式: 参数: ?file=php://input POST body中写入PHP代码 4.2 直接代码执行 利用方式: 直接在POST body中写入PHP代码(无需 <?php ?> 标签) 4.3 其他危险函数组合 任何将 php://input 内容作为PHP代码解析的函数组合都可能导致RCE,例如: assert() create_function() preg_replace() 的/e修饰符 5. 实际利用案例 5.1 Webshell管理工具 许多Webshell管理工具利用 php://input 特性: 冰蝎4默认shell就使用了类似技术 其他常见Webshell管理工具也普遍支持 5.2 绕过限制 php://input 可以: 绕过某些WAF对 $_POST 的过滤 传输非标准格式的数据 在无法使用常规POST方式时执行代码 6. 防御措施 禁用危险函数: eval , assert , create_function 等 严格过滤输入:特别是文件包含的参数 使用白名单:限制允许的协议和内容类型 更新PHP版本:新版PHP对某些危险特性有改进 配置php.ini:限制 allow_url_include 等设置 7. 总结 php://input 伪协议在PHP安全中扮演重要角色,理解其工作原理对于: 安全人员:识别和防御相关攻击 开发人员:避免引入相关漏洞 渗透测试人员:利用相关特性进行测试 关键点在于认识到 php://input 与危险函数组合时可能导致代码执行,而不仅仅是数据读取功能。