Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
joomla-articles-catid — Joomla 6.1.3 - Alta - Remota - ACL - POST /api/v1/content/articles ignora las ACL por categoría | Kitploit
Herramientas/GitHubGitHub/abraxas/joomla-articles-catid
Autenticación y AutorizaciónAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónSeguridad de APIsLabs y Práctica
GitHubabraxas/joomla-articles-catid

joomla-articles-catid

Joomla 6.1.3 - Alta - Remota - ACL - POST /api/v1/content/articles ignora las ACL por categoría

15hace 9 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
Ver Repositorio

Abraxas Labs - joomla-articles-catid

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

Análisis: https://abraxaslabs.tech/research/joomla-articles-catid

joomla-articles-catid

Clase: Privilegio residual Alcance: Remoto

Joomla CMS 6.1.3 (0f2d4de) - Open Source Matters

La comprobación ArticleController::allowAdd del administrador verifica com_content.category.{catid}. api/components/com_content/src/Controller/ArticlesController.php no tiene allowAdd. Después, ApiController::add() llama a allowAdd() sin datos, por lo que el catid del JSON nunca entra en la comprobación. El allowAdd base es verdadero si el usuario puede crear en cualquier categoría.

Un usuario de API de clase Manager, al que se le ha concedido core.login.api y permiso de creación en una categoría, puede enviar un artículo mediante POST a una categoría en la que está denegado en la interfaz de usuario.

IDaún sin CVE
ClasePrivilegio residual / omisión de autorización
AlcanceRemoto (token de API con core.login.api)
CWECWE-863
CVSSMedio: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
ProductoJoomla CMS
Afectado6.1.3 (0f2d4de4729eb951e0878fec98c7990da07915b2), POST /api/index.php/v1/content/articles
AutenticaciónToken de API para Manager (grupo 6) con core.login.api, core.manage de com_content y core.create en una sola categoría. Sin Super User. El valor predeterminado de core.login.api es solo para Super User.
LicenciaGNU Affero GPL v3.0
Laboratoriosolo 127.0.0.1

Qué puede hacer un atacante

Usar un token de API que no es de Super User y que puede crear en una categoría para publicar en categorías en las que está prohibido. No se convierten en Super User a partir de este privilegio residual. Se trata de una publicación no autorizada, no de una toma de control del sitio ni de una lectura de artículos ocultos.

PrivilegioMétodo / rutaTipoDemostrado en laboratorio o inferido
Crear un artículo en una categoría a la que se le deniegaPOST /api/index.php/v1/content/articles JSON catid de BintegridadDemostrado en laboratorio. HTTP 200, #__content id=1, catid=9 (Press), título poc-art-JOOMLA-ARTICLES-CATID-WITNESS
Colocar una copia publicada en Official notices / Press mientras solo se permiten borradoresMismo POST, state=1integridadDemostrado en laboratorio la creación en Press denegada. Inferido para cualquier otro recurso de categoría con core.create denegado
Editar un artículo existente mediante la APIPATCH /api/index.php/v1/content/articles/{id}n/aInferido cerrado para este Manager. El allowEdit base requiere el componente core.edit; las reglas de laboratorio de com_content otorgan core.edit a Author (4), no a Manager (6). El laboratorio no ejecutó PATCH
Eliminar un artículo mediante la APIDELETE /api/index.php/v1/content/articles/{id}n/aInferido cerrado. El allowDelete base requiere el componente core.delete. El laboratorio no ejecutó DELETE
Guardar un artículo en la categoría permitida A desde el administradorPOST ... task=article.save jform[catid]=AprevistoDemostrado en laboratorio abierto según lo previsto. HTTP 200, no denegado
Guardar un artículo en la categoría denegada B desde el administradorMisma tarea, jform[catid]=Bn/aDemostrado en laboratorio cerrado. HTTP 200 con "not permitted" / create-not-permitted (UI allowAdd en com_content.category.B)
Acceder a la API con un Manager estándar (sin core.login.api)Token Bearer / X-Joomla-Tokenn/aInferido cerrado. El valor predeterminado de core.login.api es solo para Super User (grupo 8). Este laboratorio lo concede primero al grupo 6
Misma brecha en contacts / banners / newsfeedsPOST /api/index.php/v1/contacts (y similares) con catid ajenointegridadInferido. Esos controladores de API también carecen de allowAdd. El laboratorio no los ejercitó
RCE de Super User / instaladorn/an/aCerrado. Manager sigue siendo Manager

Cómo lo encontré

Fijé la versión 6.1.3 tras la oleada de JSST de 2026-07/08. La API de Groups ya requiere core.admin. El servicio web de Media ya requiere core.edit en la sobrescritura. La API de Articles todavía pasa por ApiController y considera que "crear en cualquier categoría" es suficiente para cada catid.

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

Comprobación 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'));
}

La interfaz de usuario del administrador ya depende de 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();
}

Falsos pasos ya registrados: leer el HTTP 200 de la UI como permitido (la denegación de B es el cuerpo "not permitted"); tratar el componente core.create como el agujero (el Manager del laboratorio no tiene ninguno; una categoría permitida es suficiente para el recuento base de getAuthorisedCategories); un Manager estándar sin core.login.api. Teatro: una reverse shell. El oráculo es API 200 en Press más UI permitida en Drafts más UI denegada en Press.

Restos del mismo pin: levels API, menu items API, media override.

Laboratorio

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

o

cd lab
./run.sh

Dirígete solo a http://127.0.0.1:19550. Imagen joomla:6.1.3-php8.3-apache más 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 es el siguiente autoincremento de #__content (1 en una instalación limpia de 6.1.3). ui-a / ui-b devuelven HTTP 200; la denegación de B es el cuerpo "not permitted" de la UI, no un estado 403.

La corrección

Descargar herramienta