Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-97347 — Proof-of-concept для CVE-2026-97347 — неаутентифицированный хранимый XSS в плагине WordPress Post Views Stats Counter через заголовок User-Agent, с шагами воспроизведения. | Kitploit
Инструменты/GitHubGitHub/jailbr3ak/cve-2026-97347
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасность
GitHubjailbr3ak/cve-2026-97347

CVE-2026-97347

Proof-of-concept для CVE-2026-97347 — неаутентифицированный хранимый XSS в плагине WordPress Post Views Stats Counter через заголовок User-Agent, с шагами воспроизведения.

Репозиторий
1 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-97347 — Stored XSS в счётчике статистики просмотров записей (плагин WordPress)

ПлагинPost Views Stats Counter
Уязвимая версия≤ 1.1.7
Класс ошибкиStored XSS без аутентификации
Точка входаHTTP-заголовок User-Agent
Место срабатыванияСтраница статистики администратора (options-general.php?page=post_views_stats_admin_menu)
CVSS 3.17.2 High
СтатусНе исправлено на момент раскрытия, исправленных версий до сих пор не известно
ИсследовательNawaf Althurwi

Ошибка

Плагин записывает каждый просмотр страницы, включая заголовок User-Agent посетителя, в пользовательскую таблицу (wp_pvs_counter). Вот где он захватывает заголовок — никакой санитизации нигде на этом пути:

// wp_pvscounter.php
$ua = $_SERVER['HTTP_USER_AGENT'];

Единственная защита на входе — это фильтр ботов, и он представляет собой всего лишь чёрный список подстрок:

// wp_pvscounter.php
function pvs_counter_is_bot() {
    $pvs_bots = get_option('pvs_counter_value_admin_bots');
    ...
    foreach( $pvs_bots as $pvs_bot ) {
        if (stripos( $ua, $pvs_bot ) !== false) {
            $bot = 1;
            return $bot;
        }
    }
}

Список по умолчанию — bot, spider, crawler. Всё, что не содержит эти подстроки, сохраняется. Это весь фильтр.

На стороне вывода страница администратора формирует выпадающий список «зарегистрированных user agent» и выводит сохранённое значение как есть внутри тега <option> — esc_attr() защищает атрибут value, но видимая метка выводится простым echo:

// manage/admin.php
<?php foreach($useragent_bot_list as $useragent_bot): ?>
    <option value="<?php echo (esc_attr($useragent_bot)); ?>"><?php echo $useragent_bot; ?></option>

Таким образом, неаутентифицированный запрос с HTML в заголовке User-Agent выполняется в браузере администратора при следующем открытии страницы статистики плагина. Классический хранимый XSS, без аутентификации, без какого-либо взаимодействия со стороны жертвы, кроме просмотра собственной панели управления.

Ещё одно ограничение, о котором стоит знать: столбец useragent имеет тип varchar(155), поэтому полезная нагрузка должна укладываться в 155 символов.

Воспроизведение

Подходит любой залогированный URL — главная страница /?p=1 вполне годится. Замените TARGET на хост WordPress, а YOUR_PAYLOAD — на то, что вы хотите выполнить в сессии администратора:

curl -s -o /dev/null \
  -H 'User-Agent: </option></select>' \
  'http://TARGET/?p=1'

Замечания по структуре полезной нагрузки:

  • </option></select> выводит значение за пределы разметки выпадающего списка — это не украшение, без него инъекция остаётся запертой внутри тега <option>.
  • Держите строку свободной от bot/spider/crawler (без учёта регистра), иначе запрос отфильтровывается как бот ещё до попадания в базу данных.
  • Держите её в пределах 155 символов.
  • Если нужны пробелы внутри alert(), используйте вместо них &#32; — некоторые HTTP-клиенты искажают пробелы в значениях заголовков.

Однострочник, который я использовал в своей лаборатории:

curl -s -o /dev/null -w 'HTTP %{http_code} - payload stored\n' \
  -H 'User-Agent: </option></select>' \
  'http://packetradar.local:8090/?p=1'

Шаг 1 — сохраняем полезную нагрузку

Отправка полезной нагрузки через заголовок User-Agent

Просто обычный curl. HTTP 200 означает, что просмотр был учтён, а заголовок попал в базу данных.

Шаг 2 — запускаем её

Откройте Settings → Post Views Stats Counter под учётной записью администратора (или просто обновите страницу, если она уже открыта). Полезная нагрузка отображается в составе списка виджетов статистики, и срабатывает onerror:

Выполнение полезной нагрузки на странице статистики администратора

Воздействие

  • Кража cookie / перехват сессии администратора (изменение области S:C — XSS выполняется в wp-admin, поэтому может вызывать admin-ajax и эндпоинты установки плагинов с cookie администратора)
  • Установка и активация плагинов → RCE на сервере
  • Постоянная полезная нагрузка: срабатывает у администратора при каждом посещении страницы статистики, пока запись не будет удалена

Видео эксплойта

демо

Более высокое качество, если хотите перематывать/приостанавливать: exploit-vid.mp4

Ссылки

  • Запись CVE — CVE-2026-97347

  • Запись Wordfence Threat Intelligence — CVE-2026-97347


Протестировано на версии 1.1.7 в WordPress 6.x в локальной среде Docker. Без аутентификации, без взаимодействия с пользователем, кроме открытия страницы статистики.

Скачать инструмент