PHP pearcmd.php RCE Exploit Attempt
A PHP pearcmd RCE exploit attempt is a remote code execution attack chain that abuses the system pearcmd.php utility via a local file inclusion vulnerability. Attackers use directory traversal to include pearcmd, then pass PEAR’s config-create command via URL parameters to write arbitrary PHP code to disk and execute it.
pearcmd.php utility via local file inclusion. An attacker leverages a vulnerable parameter on your web app to include the system PEAR file, then uses its config-create command to write arbitrary PHP code to disk and execute it. The pattern is old (2018) but still actively scanned and exploited because many production PHP installations still ship pearcmd.php unnecessarily.
What does a PHP pearcmd RCE attack look like?
The attack arrives as a single GET request with a distinctive URL pattern. Real example, captured from a Dstl8 customer’s production logs:
GET /index.php?lang=../../../../../../../usr/local/lib/php/pearcmd
&+config-create+/&/<?echo(md5(%22hi%22));?>+/tmp/index1.php HTTP/1.1
Three components to spot:
- Local file inclusion via the
langparameter —lang=../../../../../usr/local/lib/php/pearcmdwalks up the directory tree to reach the PEAR installation. - PEAR
config-createcommand — the legitimate purpose of this command is to write a PEAR config file. The destination path and contents are now attacker-controlled. - Embedded PHP payload —
<?echo(md5("hi"));?>is a benign canary used by automated scanners to test for exploitation. Real attacks substitute shell-execution payloads.
pearcmd.php RCE pattern is distinct from PHP-FPM local privilege escalation via PEAR (Lyon Yang, 2018) — that attack requires existing local access. The exploit described here is fully remote, requires only an LFI vulnerability, and does not depend on PHP-FPM specifically.
Why does this attack work?
PHP’s PEAR (PHP Extension and Application Repository) ships with a command-line utility called pearcmd.php. On many shared hosts and legacy installations, it lives at /usr/local/lib/php/pearcmd or /usr/share/php/PEAR/pearcmd.php. The file is harmless on its own — it’s only meant to be invoked from the CLI as a package manager.
The exploit chain:
- The target application has a local file inclusion (LFI) vulnerability — typically in a parameter like
?lang=,?page=, or?file=where user input is concatenated into aninclude()orrequire()call. - Attackers use directory traversal (
../../) to escape the application’s directory and include the systempearcmd.php. - pearcmd.php reads command-line arguments via
$_SERVER['argv']— and PHP, whenregister_argc_argv = On, populates that array from the URL query string. The attacker can pass arbitrary “command-line arguments” via the URL. - The
config-createPEAR command writes a file to disk — file path and contents both attacker-controlled. - Attacker requests the newly-written file to execute their PHP code in the web server’s context.
What’s the severity if it succeeds?
Successful exploitation = full remote code execution in your web server’s context.
Typical blast radius:
- Web server compromise
- Lateral movement into shared infrastructure
- Data exfiltration (database credentials, environment variables, customer PII)
- Persistent backdoors via uploaded webshells
If the attack is blocked, you’ll see a 404, 403, or 400 response. These probing attempts are extremely common — most production sites see dozens to hundreds per day from automated scanners. Blocked attempts are not an emergency, but they are signal — they indicate active reconnaissance against your perimeter.
How do I debug or remediate?
1. Check the HTTP response code
| Response | Meaning | Action |
|---|---|---|
| 404 / 403 / 400 | Attack failed | Log for awareness, no immediate action |
| 200 with normal body | Likely failed, but verify | Check /tmp/ for unexpected files |
| 200 with attacker output | Active compromise | Incident response — isolate the host |
| 500 | Crash from malformed request | Audit application for the LFI bug |
2. Verify pearcmd.php isn’t reachable
find / -name "pearcmd*" 2>/dev/null
If present in production containers, remove it:
rm /usr/local/lib/php/pearcmd*
3. Harden php.ini
allow_url_include = Off
allow_url_fopen = Off
register_argc_argv = Off
The last setting prevents PHP from populating $_SERVER['argv'] from query strings, which breaks this specific attack chain even if pearcmd is still present.
4. Add WAF rules
Block any request matching:
- URL path containing
pearcmd - Query string containing
config-createcombined with/tmp/or<? - Any
?lang=parameter containing../
5. Check for staged payloads
find /tmp /var/www -name "*.php" -mtime -30 -not -path "*/vendor/*"
Anything you don’t recognize is a candidate for forensic analysis.
How does Dstl8 detect this?
Dstl8’s parser flags URL patterns matching known exploit families and groups them into a single security incident — not 50 separate “weird URL” alerts. Here’s an actual detection from a customer’s production logs (anonymized):
The incident summary names each attack family by exploit class, includes the exact payload (so you can verify the attack vector without grepping logs), confirms blocking status, and auto-resolves when probing stops. No manual triage required — the entire incident is one notification, not three dozen.
Related patterns
References
- PHP PEAR security advisory, 2018: bugs.php.net/76918
- OWASP: Path Traversal attacks
- Snyk vulnerability database: PHP pearcmd.php local file inclusion
- Original disclosure: Lyon Yang, PHP-FPM Local Root via pearcmd (2018)
See real attack detections in your own logs.
Dstl8 catches PHP pearcmd, ThinkPHP, directory traversal, and other RCE attempts the moment they hit your perimeter — grouped into a single incident, not 50 separate alerts.














