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
joomla-articles-catid — Joomla 6.1.3 - Élevé - À distance - ACL - POST /api/v1/content/articles ignore les ACL par catégorie | Kitploit
Outils/GitHubGitHub/abraxas/joomla-articles-catid
Authentification et AutorisationAnalyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'IntrusionSécurité des APILabs et Pratique
GitHubabraxas/joomla-articles-catid

joomla-articles-catid

Joomla 6.1.3 - Élevé - À distance - ACL - POST /api/v1/content/articles ignore les ACL par catégorie

15il y a 9 joursPas 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 →
Voir le dépôt
Partager

Abraxas Labs - joomla-articles-catid

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  joomla-articles-catid

Write-up : https://abraxaslabs.tech/research/joomla-articles-catid

joomla-articles-catid

Classe : Résidu de privilège Portée : Distante

Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters

La méthode administrateur ArticleController::allowAdd vérifie com_content.category.{catid}. api/components/com_content/src/Controller/ArticlesController.php ne possède pas de allowAdd. ApiController::add() appelle ensuite allowAdd() sans données, de sorte que le catid JSON n'entre jamais dans la vérification. La méthode allowAdd de base renvoie vrai si l'utilisateur peut créer dans n'importe quelle catégorie.

Un utilisateur API de classe Manager, disposant de core.login.api et du droit de création sur une seule catégorie, peut publier un article par POST dans une catégorie où il est refusé dans l'interface.

IDpas encore de CVE
ClasseRésidu de privilège / contournement d'autorisation
PortéeDistante (jeton API avec core.login.api)
CWECWE-863
CVSSMoyen : 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
ProduitJoomla CMS
Affecté6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2), POST /api/index.php/v1/content/articles
AuthJeton API pour Manager (groupe 6) avec core.login.api, com_content core.manage, et core.create sur une seule catégorie. Pas de Super User. Par défaut, core.login.api est réservé au Super User.
LicenceGNU Affero GPL v3.0
Lab127.0.0.1 uniquement

Ce qu'un attaquant peut faire

Utiliser un jeton API non-Super-User autorisé à créer dans une catégorie pour publier dans des catégories où il est banni. Il ne devient pas Super User grâce à ce résidu. Il s'agit d'une publication non autorisée, et non d'une prise de contrôle du site ni d'une lecture d'articles masqués.

PrivilègeMéthode / cheminTypeProuvé en laboratoire ou déduit
Créer un article dans une catégorie à laquelle il est refuséPOST /api/index.php/v1/content/articles JSON catid de BintégritéProuvé en laboratoire. HTTP 200, #__content id=1, catid=9 (Press), titre poc-art-JOOMLA-ARTICLES-CATID-WITNESS
Placer une copie publiée dans Official notices / Press alors que seuls les brouillons sont autorisésMême POST, state=1intégritéProuvé en laboratoire : création dans Press refusée. Déduit pour toute autre ressource de catégorie avec core.create refusé
Modifier un article existant via l'APIPATCH /api/index.php/v1/content/articles/{id}n/aDéduit comme fermé pour ce Manager. La base allowEdit nécessite le composant core.edit ; les règles com_content du laboratoire accordent core.edit à Author (4), pas à Manager (6). Le laboratoire n'a pas effectué de PATCH
Supprimer un article via l'APIDELETE /api/index.php/v1/content/articles/{id}n/aDéduit comme fermé. La base allowDelete nécessite le composant core.delete. Le laboratoire n'a pas effectué de DELETE
Enregistrer un article dans la catégorie autorisée A depuis l'administrateurPOST ... task=article.save jform[catid]=AprévuProuvé en laboratoire ouvert comme prévu. HTTP 200, non refusé
Enregistrer un article dans la catégorie refusée B depuis l'administrateurMême tâche, jform[catid]=Bn/aProuvé en laboratoire fermé. HTTP 200 avec « not permitted » / create-not-permitted (UI allowAdd sur com_content.category.B)
Appeler l'API avec un Manager standard (sans core.login.api)Jeton Bearer / X-Joomla-Tokenn/aDéduit comme fermé. Par défaut, core.login.api est réservé à Super User (groupe 8). Ce laboratoire l'accorde d'abord au groupe 6
Même faille sur contacts / banners / newsfeedsPOST /api/index.php/v1/contacts (et équivalents) avec un catid étrangerintégritéDéduit. Ces contrôleurs API manquent également de allowAdd. Le laboratoire ne les a pas testés
RCE Super User / installateurn/an/aFermé. Le Manager reste Manager

Comment je l'ai trouvé

J'ai épinglé la version 6.1.3 après la vague JSST de 2026-07/08. L'API Groups exige déjà core.admin. Le webservice Media exige déjà core.edit sur l'override. L'API Articles passe encore par ApiController et considère « créer dans n'importe quelle catégorie » comme suffisant pour chaque catid.

public function add()
{
    if (!$this->allowAdd()) {
        throw new NotAllowed('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED', 403);
    }
    $recordId = $this->save();
    $this->displayItem($recordId);
}

Vérification de base :

protected function allowAdd($data = [])
{
    $user = $this->app->getIdentity();

    if (!$user->authorise('core.manage', $this->option)) {
        return false;
    }

    return $user->authorise('core.create', $this->option)
        || \count($user->getAuthorisedCategories($this->option, 'core.create'));
}

L'interface d'administration s'appuie déjà sur catid :

protected function allowAdd($data = [])
{
    $categoryId = ArrayHelper::getValue(
        $data,
        'catid',
        $this->input->getInt('filter_category_id'),
        'int'
    );

    if ($categoryId) {
        return $this->app->getIdentity()->authorise(
            'core.create',
            'com_content.category.' . $categoryId
        );
    }

    return parent::allowAdd();
}

Faux pas déjà consignés : lire un HTTP 200 de l'UI comme une autorisation (le refus de B est le corps « not permitted ») ; traiter le composant core.create comme la faille (le Manager du lab n'en a aucun ; une seule catégorie autorisée suffit pour le décompte de base de getAuthorisedCategories) ; un Manager standard sans core.login.api. Théâtre : un reverse shell. L'oracle est un API 200 dans Press plus une autorisation UI sur Drafts plus un refus UI sur Press.

Restes du même pin : levels API, menu items API, media override.

Lab

python3 joomla-articles-catid-Abraxas-Labs.py

ou

cd lab
./run.sh

Ciblez uniquement http://127.0.0.1:19550. Image joomla:6.1.3-php8.3-apache plus mariadb:11.4.

SUCCESS joomla-articles-catid api-http=200 article-id=1 catid=9 cat-a=8 cat-b=9 ui-a=200 ui-b=200 JOOMLA-ARTICLES-CATID-WITNESS

article-id est l'auto-incrément suivant de #__content (1 sur une installation propre de 6.1.3). ui-a / ui-b renvoient HTTP 200 ; le refus de B correspond au corps « not permitted » de l'interface, et non à un statut 403.

Le correctif

Télécharger l’outil