Follow up ad una precedente discussione. In questo thread provero’ a condividere informazioni tecniche su vulnerabilita’ che trovo nel mio lavoro part-time come bug bounty hunter. Non conosco il livello tecnico medio dei members, dunque se avete domande o qualcosa non e’ chiaro, chiedete pure.
Questa sera ho trovato una bella vulnerabilita’ in un private program su cui ho iniziato a lavorare oggi. E’ una vulnerabilita’ di tipo XSS
(Cross Site Scripting) che sfrutta una feature dei browser chiamata postMessage.
In breve, postMessage
consente di bypassare la SOP o Same Origin Policy forzata dai browser. SOP, in breve, previene by default che un sito ad una certa origine (dove origine = schema/protocollo + dominio/hostname + porta) di manipulare un sito ad una origine differente. Prima che SOP fu introdotta, era possibile per un sito controllato da un attacker di controllare altri siti, che era una vulnerabilita’ critica. Esempio: era possibile caricare il sito di e.g. una banca in un iframe di un sito controllato dall’attacker, e manipolare il DOM (Document Object Model) della pagina nel sito della banca, o eseguire code, per cambiarne in comportamento, che come potete immaginare e’ critico. Been there, done that
Normalmente, a causa di SOP dunque cross-domain communication non e’ consentita direttamente. Cioe’ sito A non puo’ per esempio modificare il DOM di sito B oppure eseguire custom JavaScript code in sito B. Pero’, come potete immaginare, ci possono essere casi in cui e’ necessario per un sito poter collaborare con un altro sito per esempio con iframe, e un meccanismo per fare questo bypassando la SOP di proposito e’ postMessage
.
Leggete la pagina del link sopra per dettagli, ma in breve postMessage
consente ad un sito di inviare un messaggio ad un sito in altra origine, e l’altro sito puo’ usare il contenuto del messaggio come vuole.
Ovviamente, perche’ si bypassa la SOP, con postMessage
e’ possibile introdurre vulnerabilita’ se a) il sito target usa il contenuto del messaggio in modo poco sicuro, b) il sito target non verifica correttamente la origine del messaggio con una allowlist di qualche tipo.
Con questa premessa, la vulnerabilita’ che ho trovato oggi sfrutta il fatto che il sito target controlla l’origine del messaggio, ma lo fa in maniera poco sicura. Per verificare l’origine usa una regex o Regular Expression abbastanza complicata. Purtroppo per i devs, ma per fortuna mia, hanno dimenticato di aggiungere un $
alla fine della regex, e questo e’ una delle 3 condizioni che mi hanno consentito di fare exploit. Il carattere $
(o un alternativa e’ \Z
) delimita la fine del valore ricercato con la regex; quindi se per esempio la regex e’ ^/www\.something\.com/$
, la regex permette soltanto www.something.com
come origine dei messaggi ricevuti con postMessage
. Dal momento che i devs hanno dimenticato la $
finale (la regex e’ un po’ complessa), questo significa che la regex accetta anche un valore come www.something.com.attacker-site.com
, quindi mi permette di appendere un dominio che controllo.
La seconda condizione in questo caso di oggi, e’ che il sito target si aspetta, tra i messaggi possibili, un messaggio con un oggetto JSON che include una proprieta’ paymentUrl
che normalmente contiene uno URL, come il nome suggerisce.
La terza condizione e’ che il sito target usa il valore di quella proprieta’ per impostare lo URL di un link nella pagina, che invia la vittima alla pagina con i dettagli del pagamento sul sito del payment gateway. Qui i devs hanno dimenticato di sanitizzare lo URL (sanitization e’ un processo che filtra un testo per prevenire l’esecuzione di codice o l’injection di custom HTML).
Queste tre condizioni insieme costituiscono una vulnerabilita’ XSS, che - in breve - mi consente di eseguire codice JavaScript a mio piacimento nel sito target, e nel contesto della vittima.
Steps:
- far visitare alla vittima, in qualche modo, un link ad un sito controllato da me con hostname
www.target.com.something.com
; l’hostname deve essere tale che la vittima, grazie al prefissowww.target.com
pensa che e’ il sito target stesso - questo sito controllato da me carica il sito target in un iframe a piena pagina, cosi’ sembra visualmente che la vittima sta visitando il sito target
- quando la pagina nel mio sito (di attacker) viene caricata, invia un messaggio al sito target nell’iframe con
postMessage
, e come valore dello URL di cui parlavo prima usajava-scr-ipt:al-ert()
(l’alert e’ solo per demo, perche’ posso fare quello che mi pare con JS code a mio piacimento) - quando il sito target riceve il messaggio, accetta l’origine
www.target.com.something.com
a causa del bug nella regex, e imposta l’href
attribute di un link per il pagamento ajava-scr-ipt:al-ert()
- quando la vittima clicca su quel link, il mio codice JavaScript viene eseguito.
L’impatto e’ critico perche’ tra le varie cose con questo attacco posso, per esempio:
- inviare il session cookie ad un sito che controllo, e in questo modo impersonare la vittima e accedere al suo account (account takeover)
- eseguire azioni come se e’ la vittima ad eseguirle
- modificare il contenuto della pagina nel sito target, per esempio per phishing
- fare keylogging, ovvero inviare tutti i tasti premuti dalla vittima ad un server che controllo
- fare hijacking per controllare il browser della vittima (per esempio posso far comparire un login fake di Facebook or Google etc per catturare le credenziali per questi siti)
- accedere a webcamera e microfono se questi sono attivati per il sito target
- etc etc
Tutto qui. E’ stato divertente trovarla :)