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.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-70376 — Advisory e PoC em Python para CSRF no Pluck CMS: verificação de Referer fail-open aliada a upload de extensão dupla permite implantação de webshell e execução remota de código. | Kitploit
Ferramentas/GitHubGitHub/ilhomjonr/cve-2026-70376
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoAprendizado e Educação
GitHubilhomjonr/cve-2026-70376

CVE-2026-70376

Advisory e PoC em Python para CSRF no Pluck CMS: verificação de Referer fail-open aliada a upload de extensão dupla permite implantação de webshell e execução remota de código.

Ver Repositório
6há 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

CVE-2026-70376 — CSRF em todo o site no Pluck CMS → RCE

Verificação de Referer fail-open + sem tokens CSRF + upload de extensão dupla

Uma única visita de administrador a uma página apaga conteúdo, injeta páginas e instala um webshell

CVE CVSS 3.1 CWE CWE

Product Status Researcher

Visão geral · Resumo · Causa raiz · Cadeia de ataque · Exploit · Mitigação · Cronologia


📋 Visão geral

CVE IDCVE-2026-70376
ID de rastreamentoPT-2026-68036
Produtopluck-cms/pluck — Pluck CMS (PHP baseado em arquivos)
Afetado4.7.x até 4.7.21-dev / master atual
FraquezaCWE-352 (CSRF) · CWE-434 (upload sem restrições, amplificador)
CVSS v3.18.0 — Alta · AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:H
VetorRede · sem privilégios · uma visita de página do admin (UI:R)
ImpactoDestruição de conteúdo/DoS, injeção de conteúdo armazenado, RCE em Apache/mod_php
Introduzidocommit f79f916 (dez. 2019) — lógica vulnerável presente desde então
PesquisadorIlhomjon Rustamov (@IlhomjonR)

🔎 Resumo

O painel administrativo do Pluck não possui tokens CSRF por requisição em nenhum lugar do código-fonte. Toda ação administrativa que altera estado é controlada por uma única função, requestedByTheSameDomain(), cuja única defesa é uma comparação do host do Referer — e essa verificação falha em aberto (fail-open): quando uma requisição chega sem nenhum cabeçalho Referer, a função retorna true e a ação é permitida.

Como uma página do atacante controla totalmente se um Referer é enviado (<meta name="referrer" content="no-referrer">), qualquer administrador autenticado que visite uma página maliciosa pode ser forçado a executar ações privilegiadas entre sites (cross-site). Diversas ações destrutivas são executadas via GET, e o Pluck não define nenhum atributo SameSite no PHPSESSID (os navegadores aplicam SameSite=Lax, que ainda acompanha navegações GET de nível superior), portanto elas são alcançáveis entre sites nas configurações padrão dos navegadores.

Uma falha secundária no filtro de upload permite que o mesmo CSRF instale um arquivo de extensão dupla shell.php.jpg — transformando o CSRF em um RCE drive-by em hospedagens Apache/mod_php.


🧬 Causa raiz

1. Verificação de Referer fail-open — data/inc/functions.admin.php

function requestedByTheSameDomain() {
    if (isset($_SERVER['HTTP_HOST'])) { $myDomain = $_SERVER['HTTP_HOST']; }
    elseif (isset($_SERVER['SCRIPT_URI'])) { $myDomain = $_SERVER['SCRIPT_URI']; }
    else { $myDomain = NULL; }

    if (isset($_SERVER['HTTP_REFERER'])) { $requestsSource = $_SERVER['HTTP_REFERER']; }
    else { $requestsSource = NULL; }

    $referelDomain = parse_url($requestsSource, PHP_URL_HOST);

    if ($myDomain != NULL && $requestsSource != NULL &&
        (strcmp(trim($myDomain), trim($referelDomain)) === 0)) {
        return true;                 // Referer host == our host  -> allow
    } elseif ($myDomain == NULL || $requestsSource == NULL) {
        show_error("Be carefull with clicking links, ...", 1);
        return true;                 // Referer ABSENT -> FAIL OPEN -> allow  <==
    } else {
        return false;                // Referer host mismatch -> block
    }
}

Uma requisição entre sites com um Referer estrangeiro é corretamente rejeitada (o ramo else), o que gera uma falsa sensação de proteção — mas o atacante simplesmente suprime o Referer, cai no ramo fail-open, e a requisição é permitida. Não há nenhuma camada de token por trás dessa verificação.

A barreira é aplicada uma única vez em admin.php e é confiável para todo o switch de ações:

$isCSRF = requestedByTheSameDomain();
if (isset($_GET['action']) && $isCSRF) {
    switch ($_GET['action']) {
        case 'deletefile':  include_once('data/inc/deletefile.php');  break;
        case 'deleteimage': include_once('data/inc/deleteimage.php'); break;
        case 'deletepage':  include_once('data/inc/deletepage.php');  break;
        case 'module_delete': /* ... */
        case 'images':      include_once('data/inc/images.php');      break; // upload
        // ...
    }
}

2. Sem SameSite no cookie de sessão (amplificador)

O Pluck nunca chama session_set_cookie_params(), então o PHPSESSID herda o padrão vazio → os navegadores aplicam SameSite=Lax, que ainda acompanha navegações GET de nível superior. As ações expostas via GET (deletefile, deleteimage, deletepage, module_delete, theme_delete, logout) são, portanto, forjáveis com uma única visita a uma página.

3. Upload de extensão dupla — data/inc/images.php (amplificador de RCE)

if (in_array($_FILES['imagefile']['type'],                       // client-controlled MIME
    array('image/pjpeg','image/jpeg','image/png','image/gif'))) {
    $imagewhitelist = array('jfif', '.png', '.jpg', '.gif', 'jpeg');
    if (!in_array(strtolower(substr($_FILES['imagefile']['name'], -4)), $imagewhitelist)) {
        show_error($lang['general']['upload_failed'], 1);         // only checks LAST 4 chars
    } else {
        copy($_FILES['imagefile']['tmp_name'], 'images/'.latinOnlyInput($_FILES['imagefile']['name']));
        // ...
    }
}

Ambas as verificações são trivialmente contornadas:

  • o tipo MIME vem do cliente ($_FILES[...]['type']) → defina image/jpeg;
  • apenas os últimos 4 caracteres do nome do arquivo são validados → shell.php.jpg termina em .jpg e passa.

O arquivo é gravado em images/shell.php.jpg; em uma hospedagem Apache/mod_php com tratamento de múltiplas extensões, ele é executado como PHP.


⛓️ Cadeia de ataque

Uma única visita de administrador autenticado a uma página — sem clique.

flowchart LR
    A[Admin logado no Pluck] --> B[Abre página do atacante]
    B --> C["meta referrer=no-referrer<br/>suprime o Referer"]
    C --> D[Navegação de nível superior / auto-form para admin.php]
    D --> E["Cookie PHPSESSID Lax acompanha<br/>Referer ausente"]
    E --> F["requestedByTheSameDomain() -> FAIL OPEN -> true"]
    F --> G1[deletefile / deletepage -> destruição / DoS]
    F --> G2[editpage -> injeção de conteúdo armazenado]
    F --> G3["upload de imagens -> shell.php.jpg -> RCE"]

As ações forjáveis incluem:

Baixar ferramenta