Pinkie Pie e Pwnium: storia di un hack

Di - 24 May 2012 - in

Circa due mesi fa, Google Chrome ha sostenuto Pwnium, una gara di hacking volta a trovare bug nel browser. Due concorrenti hanno vinto la gara in maniera molto interessante, e qui vi parlo di uno dei due, che ha per nickname Pinkie Pie (a molti non sfuggirà il gioco sul nome della gara fatto dal concorrente).

Pinkie Pie ha utilizzato in maniera molto furba una catena di sei bug, corretti nel giro di ventiquattro ore dalla loro pubblicazione, che gli hanno permesso di uscire dall’ambiente chiuso e sicuro che viene creato da Google Chrome sul PC che lo ospita.

Prima di spiegare il meccanismo, introduco due tecnologie integrate in Google Chrome, in maniera da chiarire meglio il tutto.

Google Chrome, in maniera al momento sperimentale, supporta il  prerendering. Si tratta di una tecnologia che permette a chi crea il sito internet di chiedere al browser di caricare anche pagine diverse da quella su cui l’utente si trova, prevedendo che l’utente voglia leggerle. In tal modo, quando effettivamente l’utente visiterà quelle pagine, se le troverà caricate istantaneamente. Durante il prerendering, ovviamente, tutti i plugin vengono bloccati, per evitare che alcuni contenuti (video Flash, o musica, o altro) partano prima che l’utente possa vederli. Appena l’utente sceglie di raggiungere la pagina, vengono attivati i plugin.

Nelle ultime versioni, Chrome integra il Native Client (o NaCl). Si tratta di un sistema per eseguire codice macchina per processori x86 ed ARM in un ambiente protetto. In sostanza, grazie a NaCl, eventuali applicazioni web possono far girare programmi efficienti e veloci in un ambiente virtuale chiuso e sicuro, in modo da rendere molto reattive applicazioni che se scritte in javascript potrebbero essere eccessivamente lente e dispendiose.

Il primo bug (bug 117620) scoperto da Pinkie Pie riguarda queste due tecnologie. L’hacker ha scoperto che quando si visualizza una pagina precaricata con il prerendering, vengono avviati tutti i plugin, compresi quelli di NaCl, che dovrebbero invece essere eseguiti solamente se richiesti da applicazioni installate dal Chrome Web Store.

Arrivare ad eseguire codice per NaCl non non è una gran cosa. Come scritto sopra, si tratta di un ambiente chiuso e protetto, anche piú dell’ambiente creato dal browser per eseguire le pagine web, ciò che viene eseguito in tale ambiente non dovrebbe in nessun modo danneggiare o raggiungere il computer che esegue Chrome. Tramite NaCl, però, si ha accesso al GPU command buffer, un’area di memoria nella quale vengono scritti comandi per il processore grafico, in modo da permettere un’efficiente resa di eventuali elementi che richiedono accelerazione grafica. Qui entra in gioco il secondo bug (bug 117656): esiste un comando per sfruttare questo integer underflow nella decodifica dei comandi effettuata dalla GPU:

static uint32 ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer - sizeof(uint32)) / sizeof(T); }

Evidentemente, se size of buffer è minore di sizeof(unit32) si ottiene un valore erroneamente molto grande, che viene poi dato in pasto alla funzione:

static size_t ComputeSize(size_t num_results) { return sizeof(T) * num_results + sizeof(uint32); }

A questo punto il calcolo va in overflow e la funzione ritorna uno zero, invece di un valore che dovrebbe essere almeno uguale a sizeof(uint32).

In questo modo Pinkie ha potuto scrivere otto bytes a sua discrezione oltre la fine del buffer, che in questo caso è il GPU command buffer, mappato nello spazio di indirizzi di entrambi i processi e condiviso per il trasferimento dati tra il processo di NaCl e quello della GPU. Il sistema di allocazione di Windows posiziona i buffer in maniera abbastanza prevedibile, e il processo in NaCl ne può controllare la dimensione e alcuni ordini di allocazione. Questo permette un certo controllo nel posizionare le cose in maniera da sovrascrivere con l’overflow una particolare area.

A questo punto a Pinkie serviva un obiettivo che fosse raggiungibile posizionando ad arte i buffer e che fosse utile sovrascrivere, anche parzialmente, con otto byte. Ha trovato un’altra struttura esposta dalla GPU al sistema NaCl, i GPU bucket, che sono una struttura ad albero (un albero rosso-nero, per i tecnici), dove i primi otto byte di ogni nodo sono il puntatore al nodo successivo.

Pinkie ha quindi creato nei transfer buffer, comodamente accessibili, una struttura ad albero fatta ad arte e ha fatto in modo che il primo nodo dell’albero dei GPU bucket puntasse alla sua struttura. Facendo questo, ha ottenuto la possibilità di leggere e scrivere indirizzi arbitrarî nello spazio destinato al processo della GPU. Pinkie, in questo modo, grazie anche ad alcuni dati indirizzati in maniera prevedibile da Windows, ha potuto passare codice arbitrario alla GPU e farglielo eseguire.

Anche il processo della GPU è eseguito in un ambiente chiuso e protetto, ma si tratta di un ambiente comunque piú ampio e permissivo di quello usato per il rendering delle pagine web, e a maggior ragione di quello utilizzato per NaCl. Tra i permessi che tale processo ha, vi è quello di elencare e utilizzare le named pipe, una struttura molto semplice per la comunicazione tra processi, atraverso il Chrome IPC Layer. Come altre cose trovate da Pinkie, anche questa di per se non porta grandi rischi, ma anche in questo caso l’hacker ha trovato una piccola ma importante vulnerabilità (bug 117627): subito dopo che Chrome attiva un nuovo renderer (il sistema per eseguire e visualizzare HTML e javascript), vi è una piccola finestra di tempo in cui la pipe che dovrebbe servire a parlare con il renderer è aperta e visibile alla GPU, ma il renderer non è ancora collegato ad essa. Si può quindi fare in modo che il processo della GPU si colleghi a tale pipe prima del renderer, e finga di essere il renderer stesso.

Poco sopra avevamo detto che il renderer è eseguito in un ambiente chiuso e protetto piú ristretto di quello in cui è eseguito il processo della GPU. Esistono però dei casi particolari di renderer con permessi molto ampî, che servono a visualizzare estensioni o parti di browser (come la pagina delle impostazioni). Il quarto bug scoperto da Pinkie (bug 117417) consiste nella possibilità di fare in modo che un renderer normale passi ad essere un renderer con permessi superiori, in modo da usarlo poi per eseguire il gestore delle estensioni. L’idea è quindi quella di aprire un gestore delle estensioni e collegarsi alla sua pipe prima che lo faccia lui, in maniera tale da impersonarlo, con tutti i privilegi di accesso al sistema che ha.

A questo punto la strada sembrerebbe abbastanza in discesa, ma per uscire definitivamente dall’ambiente protetto di Google Chrome Pinkie ha avuto bisogno di altri due bug. Il primo (bug 117715) gli ha permesso di specificare un percorso di caricamento per le estensioni a suo piacimento, grazie all’impersonamento del renderer. Si tratta di un’operazione che in condizioni normali può essere eseguita solo dal browser. Il secondo (bug 117736) è un errore nel sistema di richiesta di conferma prima dell’attivazione di una estensione NPAPI non pacchettizzata.

Tale estensione serve ad eseguire programmi qualunque sulla macchina che esegue Google Chrome, e serve per permettere alle estensioni di Chrome l’esecuzione di programmi a codice chiuso o comunque compilati e difficili da portare in javascript. Tale sistema è ovviamente rischiosissimo, e in condizioni normali può venire utilizzato soltanto da estensioni scaricate dal Chrome Web Store e controllate a mano da specialisti.

Grazie a questi ultimi bug, Pinkie ha potuto installare il suo plug-in con NPAPI in maniera da eseguire un qualunque programma con gli stessi permessi dell’utente che sta utilizzando Chrome (e su Windows, specialmente su versioni non recenti, troppo spesso tali permessi sono molto ampî, per negligenza degli utenti).

Ecco quindi tutte le operazioni eseguite da questo bravo hacker per riuscire ad evadere dall’ambiente chiuso e sicuro di Google Chrome, che è fiore all’occhiello del nostro browser preferito fin dal suo debutto. Tali bug, come ho scritto all’inizio, sono tutti stati immediatamente corretti, ma può essere molto interessante studiarseli sulle loro pagine, anche per semplici fini didattici.

Complimenti, dunque, a Pinkie Pie, anche solo per il nickname, e al team di Google che dandoci un browser Open Source permette che errori di questo tipo possano venire scoperti, resi pubblici e corretti in tempi brevi.

Via | Chromium Blog

Leave a Reply

Lorenzo Breda Articolo scritto da

Studente di Informatica a Roma, si occupa di programmazione web sopratutto lato server, e di accessibilità del web. Utilizza e ama Debian GNU/Linux, e si interessa di fisica, fumetto, trekking e fotografia (gli ultimi due possibilmente abbinati). Collabora con Googlab da aprile 2012.

Contatta l'autore

Previous post:

Next post: