Meltdown e Spectre: cosa sono e come funzionano (prima parte)

L’anno nuovo si è aperto con una novità per nulla rassicurante (e che, a quanto pare, bolliva in pentola già dagli ultimi mesi del 2017): due bug nei processori dell’era moderna hanno creato un allarme generale che mette sotto accusa una vulnerabilità di tutte le CPU in commercio (Intel, AMD, ARM etc.). Il che significa che tutti noi ne siamo interessati!

Abbiamo già parlato più volta di cosa sia il processore o CPU ma ricordiamolo anche ora: esso è il componente più importante di un computer poiché è ciò che gli permette di operare (qui possiamo dare un’occhiata a spiegazioni ulteriori).

E già che ci siamo definiamo anche cosa sia un bug. La parola bug deriva dall’inglese, appunto, e nel linguaggio comune si traduce con la parola “insetto” o “cimice” intesa anche come microspia; mentre in informatica coincide con un errore, un’imperfezione che tendenzialmente si trova nei software, a livello di codice sorgente, oppure un difetto di qualche componente hardware come nel caso di cui stiamo parlando in questa sede. Questi bug, un po’ come gli insetti, vanno studiati nel tempo e osservati prima di commercializzare un prodotto informatico ma, spesso, alcuni difetti non vengono trovati subito. Un divertente aneddoto relativo alla scelta della parola bug per indicare queste imperfezioni risale alla creazione del computer Mark II nel 1947 quando Grace Hopper ed il suo team trovarono una falena all’interno dei circuiti della macchina che stava creando, con la sua propria presenza, un malfunzionamento e la annotò nei suoi appunti come il primo caso di bug trovato.

Ma torniamo ai bug rilevati attualmente sui nostri processori (che essi siano nei nostri personal computers, smartphones e persino servizi clouds) che, a quanto pare, permettono di rubare i dati del computer su cui sono montati come passwords, foto personali, e-mails, messaggi, documenti, etc. Questi bug sono stati chiamati Meltdown (fusione o collasso) e Spectre (spettro): entrambi permettono di rubare dati che vengono processati sul momento dal pc. Di norma, i programmi non possono leggere dati da altre applicazioni ma, utilizzando questi due bug, si rivela possibile per un software maligno il loro accesso.

Guardiamo, allora, questi due bug con calma, individualmente e nello specifico, per coloro che hanno voglia di approfondire meglio la situazione. In questo post ci soffermeremo su Meltdown per, poi, tra qualche giorno dedicarci, invece, a Spectre: molti articoli, infatti, hanno creato un po’ di confusione tra i due facendoli sembrare collegati tra loro mentre, in realtà, sono solamente stati scoperti e diffusi nel medesimo tempo ed appartengono alla stessa categoria, cioè sono bug dell’hardware ed in specifico della CPU e, quindi, vengono categorizzati come side channel attacks. Il loro utilizzo e come proteggersi non è assolutamente il medesimo. Inoltre, una spiegazione comprensibile anche a chi non si intende particolarmente di computer richiede ulteriori descrizioni di diversi fondamenti che, tendenzialmente, non vengono esplicate.

In ogni caso, la differenza sostanziale tra i due bug è che Meltdown, a causa come vedremo della modalità in cui la CPU esegue le applicazioni, spezza il meccanismo che dovrebbe impedire alle applicazioni stesse di accedere al sistema della memoria in modo arbitrario. Al contrario, Spectre induce delle applicazioni ad accedere a spazi arbitrari della loro memoria. Il primo quindi rompe il sistema in qualche modo, mentre l’altro lo inganna; uno permette alle applicazioni di accedere alla memoria del sistema, mentre il secondo si occupa della memoria delle applicazioni stesse.

MELTDOWN (CVE-2017-5754)

Questo bug è stato trovato da tre diversi ed indipendenti team: Jahn Horn con il suo progetto Google Project Zero, da Werner Haas e Thomas Prescher della Cyberus Technology, e da Daniel Gruss, Moritz Lipp, Stefan Mangard e Michael Schwarz della Graz University of Technology.

In specifico, al contrario di Spectre (che affligge anche altri processori), Meltdown interessa solo le CPU dell’Intel ed alcune ARM. Il nome Meltdown è stato scelto per questo tipo di bug poiché “scioglie” i confini della sicurezza normalmente imposti dall’hardware proprio mettendo in luce i suoi limiti. Quindi, Meltdown può affliggere computer fissi, portatili e cloud che utilizzano tale tipo di processori.

Esso sfrutta gli effetti collaterali di quella che di norma chiamiamo esecuzione dinamica (oppure in inglese out-of-order execution). Generalmente un processore eseguirebbe i calcoli in ordine cronologico (chiamato in-order execution) mentre oggi, grazie all’esecuzione dinamica, propria dei microprocessori di moderna generazione, è possibile eseguire un’operazione il momento in cui gli operandi risultano disponibili.

In altre parole e schematizzando, l’in-order execution deve rispettare i seguenti passaggi:

  1. Il processore recupera dalla propria memoria le operazioni da seguire
  2. Le operazioni vengono inviate all’unità per l’esecuzione se gli operandi sono disponibili
  3. Se gli operandi non sono disponibili durante il ciclo del processore questi attenderà finché non sia possibile utilizzarli tutti.
  4. A questo punto l’operazione può essere inviata all’unità che le permetta di essere eseguita
  5. Il momento in cui l’operazione viene eseguita dall’unità specifica il processore la registra.

Mentre nel caso dei nuovi processori moderni e, quindi, delle nostre CPU attuali ci troviamo di fronte al seguente paradigma o modello:

  1. Il processore recupera dalla propria memoria le operazioni da seguire come avviene nell’in-order execution
  2. Le operazioni vengono inviate in coda, ovvero in buffer
  3. L’operazione del punto 1 attende il suo turno finché gli input operandi non si rendono disponibili
  4. A questo punto l’operazione può essere inviata all’unità che le permetta di essere eseguita
  5. Dopo l’esecuzione dell’operazione i suoi risultati vengono messi in coda a loro volta
  6. Il momento in cui tutte le vecchie operazioni sono state registrate anche la nuova operazione viene aggiunta al file di registro.

Come possiamo notare la differenza sostanziale si trova al punto 2 in cui il processore che utilizziamo oggi permette alle operazioni di non attendere tutto il ciclo di calcolo ma di essere inviato in coda per essere processato appena l’input operando si rende disponibile. Inoltre, nelle CPU che supportano l’out-of-order exectution vengono processate istruzioni prima ancora che il processore sappia se queste siano o meno necessarie e vengano o meno impiegate nei futuri risultati (in molti articoli e nello stesso paper in cui viene descritto Meltdown questa peculiarità viene chiamata speculative execution).

Come sarà quindi evidente l’out-of-order execution risulta un’importante tassello di cui il nostro processore non può fare a meno se non a discapito della propria velocità di calcolo (cosa a cui oggi non possiamo rinunciare: pena periodi di latenza e lunghe attese di fronte al pc) ma, allo stesso tempo, si trova anche alla radice del bug Meltdown!

Ma qual è effettivamente questo bug? Semplice: questo tipo di operazioni, per il modo in cui vengono eseguite, possono generare delle tempistiche diverse nella loro esecuzione il ché apre in qualche modo una “porta” che rende possibile la fuoriuscita di informazioni. In altre parole, questo bug esiste perché i tempi di esecuzione si “impasticciano”, anziché essere eseguiti in ordine come invece avveniva nei vecchi processori, a causa del punto 2 descritto poc’anzi cosicché una delle regole fondamentali della sicurezza, ovvero l’isolamento tra kernel (ovvero il nucleo del nostro sistema che si occupa dell’esecuzione dei programmi) e applicazioni utente, decade.

Ricordiamoci però una cosa importante che pochi articoli hanno sottolineato, ovvero che un malintenzionato per poter sfruttare il bug Meltdown avrà bisogno di:

  • Avere accesso alla nostra rete 
  • Ottenere l’accesso come utente (non serve avere privilegi d’amministrazione)

Questo non è così semplice da attuare come scriverlo perché necessita, per poter penetrare nel sistema, dell’utilizzo del social engineering, o ingegneria sociale (avevamo già spiegato qui in specifico cosa sia ma potremmo definirla come l’arte dell’inganno che, anziché basarsi su conoscenze informatiche, si focalizza sul controllo dell’elemento umano). In ogni caso, potremmo sostenere che questo passaggio serva in ogni tipo di attacco, in maniera più o meno sostenuta, ma l’interessante di Meltdown è che, al contrario delle altre tipologie di penetrazione utilizzabili, non lascia tracce né è possibile per l’antivirus individuarlo. Alla domanda, quindi, possiamo sapere se abbiamo subito un attacco a causa del bug Meltdown dovremmo rispondere di no!

Ma come, effettivamente, funziona questo exploit di Meltdown? Ovvero, come qualcuno può trarre vantaggio di questo bug? Vi sono due passi fondamentali per fare ciò, come viene descritto nel paper dedicato a Meltdown qui pubblicato in pdf, e che noi tenteremo di spiegare in maniera più semplificata: stiamo, infatti, parlando di operazioni di scienze informatiche avanzate che un piccolo “hacker di quartiere” non sarebbe in grado di mettere in atto da solo.

  1. Il primo passaggio di cui tenere conto sarà proprio l’utilizzo dell’out-of-order execution tentando di utilizzare tutti i possibili indirizzi di memoria; ciò sarà possibile cambiando in continuazione le microarchitetture così da riempire la cache della CPUSulla destra abbiamo postato un’immagine semplificata, e desunta dal paper sopramenzionato, che mostra la microarchitettura di uno dei core della CPU Skylake della Intel. Le istruzioni vengono decodificate nella cache, o deposito, chiamata µOPs (posizionata nella prima parte superiore dello schema) dopodiché passano nella parte centrale, l’execution engine, dove avvengono le operazioni dell’out-of-order execution messe in atto da singole unità le quali cercheranno di determinare quale sarà la prossima operazione richiesta così da permettere alla stessa di essere elaborata in anticipo.
    Ora, l’esempio utilizzato nel paper è quello di un toy program, ovvero un “programma giocattolo”, che richiede l’esecuzione di un’istruzione impossibile da elaborare così da innescare l’out-of order execution: ciò significa che la CPU comprendendo che tale istruzione sta richiedendo troppo tempo inizierà ad occuparsi delle seguenti istruzioni senza attendere il risultato della prima. La seconda linea del codice del toy program scritto ordinerà di recuperare degli indirizzi di memoria cosicché la CPU carichi nella propria cache, o deposito, il loro contenuto. Ora, il “programma giocattolo” inizierà a non funzionare più poiché l’eccezione creata dalla prima richiesta fatta (quella d’innesco che risulta impossibile da elaborare) si manifesterà implicando la morte del processo incapacitato a dare una risposta al sistema operativo.
  2. A questo punto, ci troviamo nella seconda parte dell’attacco, dove verrà utilizzato un metodo di timing per vedere se alcune parti della cache, o deposito, sono state o meno riempite (1-0): se la cache impiega un certo tempo per reagire allora significa che è stata riempita con qualcosa. Per recuperare i contenuti della cache e metterli in un byte che sia possibile leggere si dovrà controllare ogni singola linea della cache, con il metodo di timing, per vedere se qualcosa è stato caricato o meno: in questo noioso ed esteso periodo di tempo si ricostruiranno i contenuti della cache sapendo, così, per ogni sua locazione se abbiamo un 1 o uno 0 (linguaggio binario o linguaggio macchina). Il contenuto della cache verrà salvata da qualche parte avendoci permesso di leggere una sola locazione della memoria.

Questo significa che per leggere l’intero spazio della memoria non solo ci vorrà del tempo e la voglia di tradurre il linguaggio macchina ma anche di creare un “programma giocattolo” che nella prima parte si divida in due: il primo si autodistruggerà, mentre il secondo ripeterà quello che ha fatto il precedente creando una propria copia ed autodistruggendosi a sua volta finché non saranno lette tutte le locazioni della memoria.

COSA FARE PER PROTEGGERSI DA MELTDOWN

Meltdown è anche il bug che, rispetto a Spectre, è il più semplice da gestire poiché mitigabile a livello di software: già sono state rese disponibili delle patch, ovvero degli aggiornamenti per i diversi sistemi operativi, che vadano a fermare la condivisione tra il kernel e le applicazioni utente. Mentre, come vedremo in un prossimo post, Spectre risulta meno semplice da correggere. Quindi, continuando a parlare di Meltdown: tutti coloro che possiedono Windows 10, Mac (nome dell’aggiornamento: macOS 10.13.2 High Sierra o superiori), iPhone, iPad, sicuramente avranno già scaricato ed installato l’aggiornamento in automatico; chi ha ancora Windows 8 troverà qui l’aggiornamento mentre chi ha Windows 7 qui, oppure potrà scaricarlo da Windows Update. In ogni caso, qui sotto riportiamo anche le patch di Windows 10, per Meltdown, suddivise a seconda della versione che possediamo:

  • Versione 1709 “Fall Creators Update”: 16299.192, patch KB4056892 | Changelog | Download
  • Versione 1703 “Creators Update”: build 15063.850, patch KB4056891 | Changelog | Download
  • Versione 1607 “Anniversary Update”: build 14393.2007, patch KB4056890 | Changelog | Download
  • Versione 1511 “November Update”: build 10586.1356, patch KB4056888 | Changelog | Download
  • Versione 1507 “Initial release”: build 10240.17738, patch KB4056893 | Changelog | Download

Per quanto riguarda Linux invece toccherà mantenerlo aggiornato dipendentemente dalla versione che possediamo, Ubuntu Debian hanno una pagina specifica dedicata al suddetto (basta cliccare sul nome del sistema operativo per aprirla).

Una patch, o aggiornamento, di sicurezza è stato anche inviato a tutti i sistemi Android in questi giorni.

 
FONTI:

Share the love

Comincia la discussione

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.