
Docker-based local lab reproducing CVE-2026-87902, a WordPress page-template path traversal leading to local PHP file inclusion and PEAR-based RCE, with a PoC script.
A local Docker lab for reproducing CVE-2026-87902 (WordPress page template parsing path traversal → local PHP file inclusion → pearcmd file write RCE).
⚠️ For security learning and research in authorized environments only. It can only be run in local Docker, and must not be used against any unauthorized target. The vulnerability was officially fixed on 2026-09-22, and patches have been released for all supported branches.
get_page_template() 对用户可控的 pagename 参数做二次 urldecode() 后拼进模板候选名,locate_template() 用 file_exists() 找文件、加载前只做了 realpath/后缀/可读检查,没有校验路径仍在主题目录内(canonicalization 有了,containment 没有)| # | Condition | How This Lab Satisfies It |
|---|---|---|
| 1 | A published page with no custom template specified | setup.sh automatically creates and cleans up a sample page |
| 2 | A page-* directory at the top level of the active theme | theme/mytheme/page-templates/ (the active theme contains this directory) |
| 3 | A readable /usr/local/lib/php/pearcmd.php | The official php image ships with PEAR |
| 4 | register_argc_argv=On + a writable drop location | The official image has no php.ini, so the compiled default is On; /tmp is writable |
docker compose up -d # Automatically pulls the image on first run (about 1GB)
sh setup.sh # Install + plant /flag + verify the four conditions
python cve-2026-87902.py --url http://127.0.0.1:8091
Expected output:
[*] page id : 4 (about, default template, via /index.php?rest_route=...)
[*] depth 7 : stage 1 HTTP 200, stage 2 HTTP 200
[+] marker : 'CVE-2026-87902-POC-OK' found 12 time(s) in the stage-2 response
[+] EXPLOIT SUCCESSFUL - PHP executed with the web-server account's privileges
(12 times = the PEAR configuration file has 12 configuration items, each of which embeds a copy of the payload)
View the file written by PEAR in stage 1 (serialized text beginning with #PEAR_Config 0.9, with the payload embedded as ordinary characters in the 12 configuration items):
docker compose exec wordpress cat /tmp/wp-pear-rce-flag.php
register_argc_argv=On 使 query string 按 + 切成 $argv,pearcmd 以为自己在终端被调用;config-create <root> <file> 把 root(内嵌 PHP 代码)原样写进目标文件<?=...?> 执行,读取 /flag 回显CVE-2026-87902-POC-OK(位于容器 /flag)setup.shComplete cleanup (containers + data volumes + images):
docker compose down -v --rmi all
docker-compose.yml WordPress 7.0.2-php8.3-apache + MySQL 8.4 + wp-cli
theme/mytheme/ Lab theme (contains the page-templates/ directory, condition ②)
cve-2026-87902.py PoC (from ressl/cve-2026-87902-poc, copyright belongs to the original author)
setup.sh One-click installation + four-condition self-check