
Сканирует WordPress Core 4.7.0–7.1.1 на наличие CVE-2026-87902 — неаутентифицированного LFI через обход pagename с двойным кодированием, с опциональной эскалацией до RCE через PEAR config-create и массовым сканированием.
Инструмент эксплуатации обхода пути в get_page_template() / locate_template() ядра WordPress
Только для авторизованного тестирования безопасности. Несанкционированный доступ к компьютерным системам незаконен.
| Пункт | Детали |
|---|---|
| CVE ID | CVE-2026-87902 |
| GHSA ID | GHSA-7hp8-65ch-5whp |
| Тип уязвимости | CWE-98 — Некорректный контроль имени файла для include/require |
| CVSS v3.1 | 8.1 (High) / CVSS 4.0: 9.2 (Critical) |
| Уязвимый компонент | Ядро WordPress |
| Уязвимые версии | 4.7.0 – 7.1.1 (все ветки) |
| Исправленные версии | 7.1.2 (и бэкпорты вплоть до 4.7.37) |
| Требуется аутентификация | Нет (неаутентифицированная) |
| Вектор атаки | Один GET-запрос |
| Обнаружено | Robert Ressl (через программу WordPress HackerOne) |
| Дата раскрытия | 22 сентября 2026 г. |
| Эксплуатируется в реальных атаках | Да — внесена в каталог CISA KEV |
CVE-2026-87902 — это неаутентифицированная уязвимость обхода пути и локального включения файлов (LFI) в ядре WordPress, затрагивающая каждую версию WordPress, выпущенную с 2016 года (4.7.0 – 7.1.1). Атакующему не требуется учётная запись или аутентификация. Сформировав вредоносный параметр запроса pagename, атакующий может заставить механизм разрешения шаблонов страниц WordPress включить любой читаемый .php-файл за пределами каталога активной темы. При определённых условиях на сервере (PHP register_argc_argv = On и читаемый pearcmd.php) уязвимость может быть повышена до удалённого выполнения кода (RCE).
| Ветка | Исправленная версия |
|---|---|
| 4.7.x | 4.7.37 |
| 5.0.x | 5.0.29 |
| 5.3.x | 5.3.25 |
| 5.9.x | 5.9.18 |
| 6.0.x | 6.0.16 |
| 6.6.x | 6.6.9 |
| 6.9.x | 6.9.9 |
| 7.0.x | 7.0.6 |
| 7.1.x | 7.1.2 |
Уязвимость находится в get_page_template() в wp-includes/template.php. Когда присутствует переменная запроса pagename, функция формирует page-{$pagename}.php, но не вызывает validate_file() для этого значения, чтобы проверить наличие обхода каталога. Затем имя файла-кандидата передаётся в locate_template(), которая объединяет его с путём каталога темы и проверяет только file_exists() — она не проверяет, что разрешённый путь остаётся внутри каталога темы. Поэтому имя шаблона, содержащее ../, может разрешиться в читаемый PHP-файл за пределами активной темы, который будет включён и выполнен.
GET /?page_id=<опубликованная страница>&pagename=<дважды закодированная полезная нагрузка обхода> → WP_Query разрешает page_id, сопоставляет опубликованную страницу (избегает 404) → get_page_template() выполняет urldecode() для pagename, формирует page-{$pagename}.php → locate_template() объединяет кандидата с каталогом темы, разрешает через file_exists() → template-loader выполняет realpath() + include
WordPress применяет sanitize_title_for_query() к pagename, которая заменяет литеральные точки (.) на дефисы (-), чтобы блокировать обход. Она работает с уже один раз декодированным вводом и не декодирует рекурсивно. Атакующий отправляет %252e%252e%252f (дважды закодированный ../):
%252e → %2e, %252f → %2fsanitize_title_for_query() видит %2e%2e%2f (без литеральных точек) и пропускает егоget_page_template() внутри снова вызывает urldecode(): %2e%2e%2f → ../page- (например, page-templates/).page_id..php (WordPress добавляет расширение).Примечание для Windows-хостов: Win32 нормализует .. лексически, поэтому обход может сработать даже при отсутствии каталога page-. В Linux этот каталог должен реально существовать.
Условия:
register_argc_argv установлен в Onpearcmd.phpЗлоумышленник подключает pearcmd.php через LFI и злоупотребляет его командой config-create, чтобы записать PHP-файл на сервер, а затем снова подключает этот файл через LFI для выполнения произвольных команд.
CVE-2026-87902 был обнаружен и о нём сообщил Роберт Рессл (Robert Ressl), исследователь безопасности из Швейцарии.
Сообщено через программу WordPress на HackerOne в июле 2026 года. Команда безопасности WordPress координировала исправление и выпустила его вместе с WordPress 7.1.2 22 сентября 2026 года.
| Дата | Событие |
|---|---|
| Июль 2026 | Роберт Рессл сообщает об уязвимости через программу WordPress на HackerOne |
| 22 сентября 2026 | Выпущен WordPress 7.1.2 с исправлением; опубликовано уведомление |
| 22 сентября 2026 | Выпущены бэкпорты безопасности для веток с 7.0 по 4.7 |
| 23 сентября 2026 | Злоумышленники начинают зондировать уязвимые сайты |
| 25 сентября 2026 | CISA добавляет CVE-2026-87902 в каталог KEV |
| Возможность | Описание |
|---|---|
| Определение версии | Определяет версию WordPress через meta generator, RSS-ленту, OPML, readme.html, ?ver= в ресурсах |
| Умный вердикт по версии | Использует сопоставление исправленных версий, чтобы определить, входит ли цель в уязвимый диапазон |
| Обнаружение темы | Извлекает slug активной темы, определяет родительскую тему, находит каталоги page-* |
| Обнаружение ID страниц | Находит действительные ID страниц через REST API, класс тела page-id-, короткие ссылки |
| Валидация LFI-оракула | Использует безопасные файлы, такие как wp-links-opml.php и wp-trackback.php, в качестве оракулов с отрицательными контролями |
| Двойное кодирование обхода | Автоматически дважды процентно кодирует / и ., чтобы обойти sanitize_title_for_query() |
| Эксплуатация RCE через PEAR | Пробует распространённые пути PEAR, записывает и выполняет файлы-маркеры через config-create |
| Массовое сканирование | Многопоточное параллельное сканирование списков целей |
| Вывод результатов | Сохраняет результаты в vuln_lfi.txt и vuln_lfitorce.txt |
pip install requests
python3 CVE-2026-87902.py
Интерактивное меню:
[1] Одиночное сканирование LFI [2] Одиночное сканирование LFI + RCE [3] Массовое сканирование LFI [4] Массовое сканирование LFI + RCE [5] Выход
Выберите [1], введите URL цели:
url > https://target.example.com
Выберите [2], введите URL и команду (по умолчанию id):
url > https://target.example.com cmd > id
Выберите [3] или [4], введите файл, содержащий URL целей (по одному в строке, # для комментариев):
file > targets.txt
| Файл | Содержимое |
|---|---|
| vuln_lfi.txt | Подтверждённые цели с LFI |
| vuln_lfitorce.txt | Цели с успешной RCE |
TIMEOUT = 8 # Таймаут запроса (секунды) THREADS = 200 # Количество параллельных потоков для массового сканирования USE_ALL_ORACLES = False # Использовать все оракулы (точнее, но медленнее)