Tecnologia

Una favola per non piangere: la minaccia WannaCry spiegata ad un bambino

Nelle scorse settimane siamo stati letteralmente invasi dalle notizie riguardanti il RansomWare chiamato “WannaCry”, che ha infettato un numero spropositato di PC in tutto il mondo. Le segnalazioni riguardavano spesso il funzionamento dei RansomWare, e le modalità per prevenire l’infezione in questo specifico caso, ma solo in pochi casi si soffermavano sul meccanismo con cui WannaCry agisce realmente. Cercherò di spiegarvelo qui, con una semplice favola.

Prima della favola, i compiti!

Se ancora non l’avete fatto, vi conviene correre subito ai ripari. Se avete un Mac oppure un PC Linux, allora potete dormire sogni tranquilli; nel caso in cui stiate usando un PC Windows invece, e specialmente se siete così sciagurati da utilizzare ancora Windows XP, 7 o 8, vi conviene installare subito gli aggiornamenti del sistema operativo e dell’antivirus.

Per essere sicuri, potete anche installare direttamente la patch MS 17-010 di Windows:

>> https://technet.microsoft.com/en-us/library/security/ms17-010.aspx <<

Fatelo, e poi tornate qui… Vi aspetterò per spiegarvi il perché di queste operazioni.

Prologo

Tanto tempo fa (ma neanche troppo), nel lontano regno di MonteRosso, viveva re Finestrone. Era un re ricco e saggio, che governava con giustizia e aveva saputo portare pace e prosperità al suo regno. Voleva molto bene a ciascuno dei suoi sudditi, ma voleva ancora più bene alle sue cinque bellissime figlie, di cui era molto geloso; era così geloso da tenerle sempre ben protette all’interno del suo castello, e nessuno poteva vederle senza il suo permesso.

Il regno era piccolo, ma soleggiato e fertile nella gran parte del suo territorio, e il popolo viveva felice; per questo motivo i grandi regni confinanti avrebbero voluto detronizzare il sovrano e annettersi le sue ricchezze; Re Finestrone decise quindi, non senza sforzo, di promettere a ciascuno dei principi delle terre vicine una delle proprie figlie in moglie, ben sapendo che da solo non avrebbe mai potuto vincere la guerra, e che le figlie prima o poi si sarebbero dovute sposare.

La bellezza e grazia delle cinque principesse era quasi leggendaria, e tutti i regni vicini accettarono con piacere l’accordo. Il re viveva quindi sereno, sicuro di aver assicurato pace al suo regno anche per i decenni a venire.

Nello stesso periodo, nel cuore dell’oscura Foresta del Pianto viveva il piccolo mago Ransomio. La foresta del pianto era all’interno del regno di MonteRosso, al confine con il grande regno del Nord, ma era così buia e intricata da permettere solo al mago e ai suoi folletti di viverci, e per questo motivo Re Finestrone non aveva nessuna autorità su di essa. Ransomio si considerava quindi a tutti gli effetti un Re, e quando venne a sapere dell’accordo con i regni vicini si sentì derubato di un suo diritto, e decise di vendicarsi.

Era un uomo alto e magro, gobbo e con un enorme naso aquilino; nonostante ciò era chiamato piccolo mago, perché sicuramente non poteva essere grande; conosceva infatti solo poche magie, e nessuna di esse incuteva particolare timore.

Ecco la situazione iniziale: noi siamo come Re Finestrone, con un tesoro da proteggere (i nostri files) e delle alte mura difensive (il nostro sistema, con antivirus, firewall e chi più ne ha più ne metta).

I creatori di WannaCry invece sono come il Mago Ransomio: vogliono le nostre ricchezze, e sanno che con dei semplici strumenti possono appropriarsene.

Capitolo primo: le mura del castello

Il mago Ransomio uscì quindi dalla Foresta del pianto, e si recò presso le pendici del monte, coperto d’erba rossa, su cui sorgeva il grande castello reale. A causa della natura delle sue magie, per poter raggiungere il suo scopo egli doveva aver assolutamente accesso alla camera delle principesse; il castello però era protetto da alte mura, inespugnabili per un piccolo mago come lui, e l’ingresso principale era protetto da un plotone di guardie armate fino ai denti.

Inizialmente avrebbe voluto utilizzare il suo potere più grande, che consisteva nel sottomettere al suo volere chiunque, uomini o donne, bambini o anziani, semplicemente afferrando loro una mano; avrebbe quindi voluto controllare una delle serve del castello, per far sì che essa gli rivelasse l’esistenza di un passaggio segreto da cui accedere. Purtroppo per lui, però, per la gelosia del re solo i suoi soldati più fidati potevano entrare o uscire dal castello, ed essi giravano sempre con la loro armatura, che comprendeva una protezione per le mani. Chiese quindi ai suoi folletti di cercare un passaggio segreto, o una debolezza delle mura difensive, ma la ricerca non portò alcun frutto.

WannaCry utilizza DoublePulsar, una Backdoor (cioè un accesso segreto al sistema) probabilmente sviluppato da quei simpaticoni dell’NSA, per trasferire e installare il pacchetto principale del RansomWare all’interno del sistema attaccato. Per i sistemi che erano stati infettati in precedenza da DoublePulsar, non c’è stata via di scampo: WannaCry ha avuto campo libero per portare a termine il suo piano. Negli altri casi, gli attaccanti hanno dovuto prima cercare un metodo per infrangere il sistema e installare la Backdoor.

Ransomio spiò per giorni i soldati, aspettando un momento di distrazione per attaccare. Finse di offrire regali per le principesse, ma i soldati li rifiutavano garbatamente. Li seguì nelle loro ronde in città, ma giravano sempre in gruppo e non abbassavano mai la guardia. Offrì loro da bere, ma la guardia reale era formata solamente dagli elementi migliori dell’esercito, e nessuno di loro beveva in servizio.

Dopo più di un mese, il mago stava ormai per arrendersi. Se ne stava seduto sul ramo di un albero, guardando con aria svanita l’impenetrabile castello, quando all’improvviso notò un omuncolo vestito di nero salire la collina, bussare sulle possenti mura e svanire al loro interno. Rimase sbalordito, e pochi minuti dopo, quando l’omuncolo sbucò dalle mura, lo riconobbe: era il grande mago Bondolo, piccolo di statura ma dotato di grandi poteri.

Ransomio sapeva di non poterlo controllare, perché era molto più potente di lui, quindi decise di rubare il suo segreto. Lo seguì per giorni e capì tutto. Le mura del castello erano state stregate: Bondolo bussava sulle mura in prossimità di un cerchio, disegnato con gesso azzurro, dicendo con la sua vocina “Permesso!”, ed immediatamente ogni singola pietra all’interno del cerchio si spostava, urlando con voce profonda “Avanti!”. Il grande mago usava questo trucchetto per entrare nel castello e nelle case dei più ricchi sudditi del regno, rubando piccole quantità di denaro, solo lo stretto indispensabile per la sua sopravvivenza. Le mura rimanevano aperte a piacimento, permettendo la fuga dell’intruso.

Ransomio provò ad imitare l’esperto collega, ed ecco che subito le mura si aprirono: la sua vendetta era pronta per essere compiuta.

Solitamente, i RansomWare utilizzano gli allegati delle mail o altri trucchi per accedere alle macchine bersaglio: devono approfittare di un’ingenuità dell’utente per accedere al sistema. WannaCry però non ha bisogno di attendere un intervento umano: l’attacco analizza i computer della rete, alla ricerca di quelli in cui è presente la vulnerabilità chiamata MS17-010, riguardante l’implementazione Microsoft del protocollo Server Message Block, per accedere ai sistemi non infettati da DoublePulsar. In particolare, è stato utilizzato l’exploit chiamato EternalBlue, per eseguire del codice arbitrario sulla macchina bersaglio. Lo scopo è molto semplice: accedere alla macchina per installare DoublePulsar.

Indovinate da chi è stato scritto EternalBlue? Esatto, ancora dall’NSA, che una volta scoperta la vulnerabilità ha deciso di utilizzarla a suo vantaggio, invece di avvisare Microsoft. Si sa, gli americani hanno una vera passione per gli accessi non autorizzati… E così, quando il codice scritto dall’NSA è stato rubato, DoublePulsar e EternalBlue sono diventati di pubblico dominio.

Ecco perché è importante installare l’aggiornamento: inibendo EternalBlue, WannaCry non può installare DoublePulsar, limitando l’infezione ai soli casi in cui è l’ingenuità dell’utente a garantire l’accesso.

 

Capitolo secondo: l’incanto delle principesse

Ransomio e i suoi folletti tornarono nella Foresta del Pianto per elaborare il piano. Il mago poteva utilizzare i suoi poteri per realizzare dei lucchetti indistruttibili, in grado di rendere impenetrabile anche l’oggetto che stavano chiudendo; purtroppo potevano essere utilizzati solo per chiudere piccoli cofanetti, altrimenti il loro potere si sarebbe indebolito, ma per i suoi scopi malvagi ciò era sufficiente. Anche le chiavi dei diversi lucchetti erano speciali, perché se ne poteva creare solamente una e non poteva esser copiata in alcun modo. Realizzò una chiave verde per il re Finestrone, una gialla per il più ricco dei sudditi, e poi una viola, arancione, indaco, bianco, nero, marrone… fino a realizzare un totale di 10 chiavi, una per ciascuna delle ricche vittime del mago Bondolo, e per ciascuna di esse forgiò un lucchetto dello stesso colore.

Recuperò poi dai suoi vecchi esperimenti dei lucchetti rossi, che non avevano fessura della chiave, e dei lucchetti blu, che avevano tutti associata una copia della chiave dello stesso colore. Erano dei fallimenti, ed aveva pensato di buttarli via, ma ora finalmente avrebbe potuto servirsene.

I lucchetti e le chiavi sono spesso utilizzati per descrivere gli algoritmi di cifratura asimmetrica; questi algoritmi utilizzano due chiavi diverse, una per la cifratura e una per la decifratura.

In particolare, la chiave pubblica viene utilizzata per cifrare il messaggio, rendendolo illeggibile; essa può essere distribuita liberamente, perché non può essere utilizzata per decifrare il messaggio, e può essere quindi descritta come un lucchetto, perché tale oggetto può essere chiuso ma non riaperto.

La chiave privata è il vero segreto della cifratura, ed è l’unico modo per decifrare il messaggio: il lucchetto può essere aperto solo con la sua chiave.

WannaCry utilizza tre coppie (pubblica/privata) di chiavi asimmetriche: la AttackerKey (chiave dell’attaccante, rossa nella storia), la DemoKey (chiave di dimostrazione, blu nella storia) e una chiave forgiata direttamente sul pc della vittima, e quindi diversa di volta in volta, chiamata VictimKey (chiave della vittima, di vari colori nella storia).

L’algoritmo di cifratura asimmetrica utilizzato da WannaCry è chiamato RSA, ed è molto utilizzato per le firme digitali. Gli algoritmi di cifratura asimmetrica sono molto lenti e possono cifrare solo piccole quantità di dati, per questo motivo non possono essere utilizzati direttamente; di contro hanno il vantaggio di poter inserire nel codice solo la chiave pubblica: la chiave privata resta nelle mani dell’attaccante, e non può essere individuata. In particolare, il codice contiene solamente le chiavi pubbliche della AttackerKey e della DemoKey, mentre per ciascun pc bersaglio verrà generata al volo la coppia di chiavi della VictimKey

Quella notte, il mago e i suoi folletti andarono al castello, bussarono sulle mura e raggiunsero la camera delle principesse. Esse si svegliarono circondate dai folletti e si misero ad urlare, ma essendo nella stanza più isolata del castello non furono sentite da nessuno. Il mago si avvicinò alla più piccola, di soli otto anni, le toccò gentilmente la mano ed urlò “Fragola!”, perché indossava un pigiamino rosso; la bambina si ritrovò così imprigionata in un’enorme cristallo di sale rosa. Ripetè l’incantesimo del sale cinque volte, una per ciascuna delle principesse terrorizzate, urlando una volta “Treccia!”, e poi ancora “Fiaba!”, e “Torta!”, a seconda di ciò che gli passava per la mente. Giunse quindi all’ultima delle principesse, che aveva appena compiuto vent’anni ed era nel pieno del suo splendore, e subito urlò “Luna!” perché la sua bellezza superava anche quella del grande astro argentato.

Come detto prima, gli algoritmi di cifratura asimmetrica non sono adatti a cifrare grandi quantità di dati. Per questo motivo, spesso essi vengono utilizzati in combinazione con degli algoritmi di cifratura simmetrica, che sono più veloci e possono essere utilizzati su grandi quantità di dati. La cifratura asimmetrica resta comunque necessaria, perché la cifratura simmetrica utilizza una sola chiave per la cifratura e per la decifratura e non è quindi adatta ad essere utilizzata da sola in un RansomWare: inserendo la chiave simmetrica nel codice, basterebbe analizzarlo per annientare l’attacco a livello mondiale. Per questo motivo l’algoritmo di cifratura simmetrica AES viene usato solo per cifrare i file, generando istantaneamente una chiave per ciascuno dei file da infettare.

Una volta imprigionate tutte le principesse, i folletti scrissero su dei bigliettini le parole urlate dal mago. Svuotarono poi i portagioie delle principesse, e misero il bigliettino della più piccola nel primo cofanetto, che venne chiuso con un lucchetto blu, mentre gli altri bigliettini vennero chiusi nel secondo cofanetto, chiuso con il lucchetto verde. Il mago aveva una pessima memoria, e per paura di confondere la chiave verde  con tutte le altre chiavi decise di chiuderla in una terza scatoletta, da lasciare nel castello, che chiuse con il lucchetto rosso. I tre portagioie furono posti di fronte alle cinque colonne di sale, e il piccolo gruppetto uscì dal castello, richiudendo le mura dietro di sé. In quella stessa notte, altre nove case furono visitate dal mago e dai suoi scagnozzi, e per ciascuna di esse furono utilizzati un lucchetto blu, uno rosso e uno di un’altro dei colori preparati allo scopo. I figli di ciascuna delle case vennero così imprigionati, e per l’ultima casa, in cui c’era un solo bambino, venne imprigionato anche l’odioso chihuahua di famiglia, che aveva osato azzannare il mago.

Le chiavi realizzate vengono utilizzate così: prima di tutto, la chiave privata della VictimKey (la chiave verde) viene cifrata subito dopo la creazione con la AttackerKey pubblica (il lucchetto rosso), in modo tale da necessitare della AttackerKey privata (chiave rossa) per liberare tutti i file cifrati. Poi, ciascuno dei file viene cifrato con una diversa chiave AES (le parole urlate dal mago), generata al momento; ciascuna di queste chiavi viene cifrata o con la VictimKey pubblica o (in piccolissima parte) con la DemoKey pubblica (i lucchetti verde e blu), e salvate con il file corrispondente. Ora tutto è compiuto, per completare l’attacco basta indurre la vittima a pagare.

 

Capitolo terzo: il riscatto

Il mago tornò nella Foresta del Pianto con i suoi folletti, aspettando il giorno successivo per portare a compimento la sua vendetta. La mattina il re si svegliò, e come ogni giorno si recò a svegliare le sue amate figlie; appena entrato nella camera però si accorse della tragedia. A nulla servirono i tentativi dei soldati di spezzare i cofanetti o i blocchi di sale, essi erano indistruttibili. Alle due del pomeriggio, un orribile folletto chiese di poter essere ricevuto in udienza dal re Finestrone, che disperato acconsentì. Il folletto si presentò come servo del supremo mago Ransomio (che supremo non era affatto), dicendo che era stato lui ad imprigionare le fanciulle e che avrebbe potuto salvare loro la vita. Il re inizialmente si infuriò, ed era pronto ad uccidere l’ostile essere, ma si rese presto conto dell’impossibilità di salvare le principesse senza l’intervento del mago. Il folletto quindi fu libero di andarsene, non prima di aver annunciato che le ragazze non sarebbero potute sopravvivere a lungo all’interno del sale, e che sarebbe tornato a mezzogiorno del giorno successivo per ascoltare la decisione del re. La stessa cosa accadde in tutte le altre case.

Qui gli attaccanti adottano un ricatto psicologico. Un’immagine (qui sotto) spiega che i file potranno essere recuperati pagando 300$ entro 3 giorni, oppure 600$ entro 7 giorni. In caso contrario, non sarà più possibile recuperare i propri dati.

Il messaggio utilizza un linguaggio rassicurante, cercando di convincere la vittima della serietà e affidabilità dei malintenzionati, arrivando addirittura a definire il RansonWare “servizio”; allo stesso tempo però cerca di intimorire il malcapitato, utilizzando due conti alla rovescia dall’aspetto inquietante per incrementare l’ansia e la fretta dell’utente.

Tutte le vittime del mago si recarono di corsa al palazzo, per chiedere aiuto al saggio re, ma immediatamente compresero che egli stesso si trovava in una situazione identica. Dopo ore terribili di discussione, decisero di organizzare una trappola per il mago e i suoi scagnozzi.

All’ora pattuita, i folletti tornarono a far visita alle varie case. Il re chiese al malefico essere una prova del fatto che le sue figlie fossero ancora vive, e immediatamente il folletto si sollevò la maglia, e tirando una collana di corda mostrò a tutta la corte una chiave blu, consegnatagli da Ransomio in persona. Utilizzò quindi la chiave per aprire il lucchetto blu, e dal primo cofanetto estrasse il foglietto in essa contenuto, che venne consegnato al re. Egli lo lesse, e sconcertato chiese perché ci fosse scritto “Fragola”. Quando fu pronunciata la parola magica, immediatamente il blocco di sale contenente la figlia più piccola si scompose in piccoli cristalli, e la bambina si ritrovò a terra, svenuta ma ancora viva. In quegli stessi istanti, nelle altre case le altre chiavi blu furono usate per liberare alcuni dei fanciulli, uno per ciascuna delle case a parte l’ultima, in cui per disgrazia del padrone di casa ad essere liberato fu il fastidiosissimo Chihuahua.

Gli attaccanti hanno utilizzato di proposito la DemoKey pubblica (cioè il lucchetto blu), in modo tale da poter dimostrare agli attaccanti di essere in grado di recuperare i file. Il tasto “Decrypt”, infatti, permette di decifrare un piccolo insieme di file, recuperandone le chiavi simmetriche (il primo bigliettino) grazie alla DemoKey privata (la chiave blu, uguale per tutti gli attaccati nel mondo). Questo trucchetto serve a rafforzare ancora di più il messaggio contenuto nella finestra del malware: “Siamo dei criminali, ma siamo affidabili e se seguirai le nostre istruzioni tutto si risolverà per il meglio”.

Immediatamente i soldati si gettarono sul piccolo essere, e si misero a perquisirlo; purtroppo però non trovarono altre chiavi sui suoi vestiti. Provarono anche ad usare la chiave blu per aprire gli altri due lucchetti, ma non fu possibile. Il re quindi capì che la situazione era drammatica, si mostrò rassegnato, e decise di offrire al mago l’enorme diamante posto sul suo scettro. Il folletto rifiutò prontamente, e chiede invece il ricavato delle tasse di quell’anno, da poco giunte al castello. Il re acconsentì, anche perché il diamante valeva molto più del riscatto richiesto, e consegnò tutto quanto al servo del mago.

Gli attaccanti non sono stupidi, e sanno che i pagamenti “tradizionali” sarebbero immediatamente rintracciabili (come il diamante della storia, troppo riconoscibile per essere rivenduto). Per questo motivo, il pagamento può essere effettuato solamente in bitcoin, che sono totalmente anonimi e che quindi non lasciano alcuna traccia. (Spoiler: per comprendere conclusione della terza parte, forse ti conviene dare un ripassino alla seconda…)

Senza scendere nei dettagli, cerchiamo di capire perché è stato scelto il bitcoin. L’anonimato nelle transazioni effettuate con questa valuta è garantito utilizzando la crittografia: a ciascun portafoglio (o wallet) può essere associato un numero arbitrario di chiavi asimmetriche (generate con algoritmo ECDSA), le cui chiavi pubbliche possono essere usate come indirizzo a cui inviare i bitcoin; poiché queste chiavi non contengono alcuna informazione riguardante il loro proprietario, ed essendo possibile generare una chiave diversa per ciascuna transazione, il bitcoin può essere utilizzato mantenendo segreta la propria identità, rendendo tale valuta perfetta per un attacco come WannaCry.

La finestra del riscatto infatti include nella parte bassa proprio l’indirizzo, cioè la chiave pubblica, destinata all’utilizzo per la singola transazione con questa particolare vittima.

Anche per oggi abbiamo finito… A presto con la quarta e ultima parte della storia e una piccola sorpresa!

Finalmente, è giunto il momento di concludere la nostra fiaba.

L’attacco è andato a buon fine, i malintenzionati sono riusciti a criptare i nostri file e ci hanno anche detto come pagare, dopo averci spaventato con dei minacciosi conti alla rovescia. Ora, vediamo come gli attaccanti possono infine ripristinare i nostri amati file.

Capitolo quarto: la liberazione

Il folletto caricò il riscatto su un piccolo carro, e si preparò a partire; prese poi il cofanetto sigillato con il lucchetto rosso, annunciando che sarebbe ritornato appena possibile, e si allontanò in direzione della Foresta del Pianto. Appena uscito dalla città si ricongiunse con gli altri scagnozzi del mago, ed insieme si recarono dal loro padrone. Dietro di loro, a debita distanza, i soldati della guardia reale ne seguivano le tracce con molta attenzione, sperando di potere in questo modo catturare il mago Ransomio. Quando i folletti entrarono nella foresta, però, i soldati non poterono più continuare il loro inseguimento, e quindi non restò loro altro da fare che aspettare, nella speranza che i folletti o il loro padrone uscissero nuovamente in direzione della capitale. Nel frattempo, il mago stava aspettando pazientemente i suoi servi con i suoi nuovi tesori. Al loro arrivo, si fece consegnare immediatamente i dieci cofanetti chiusi con i lucchetti rossi, perché non voleva che qualcuna delle vittime perisse a causa dell’incantesimo del sale. Con dei forti strattoni aprì i lucchetti uno dopo l’altro: la chiave di questi lucchetti infatti era il mago stesso.

Se l’attaccato accetta di pagare, la AttackerKey privata (cioè la chiave rossa, nella storia il mago stesso) dovrebbe essere utilizzata per decriptare la VictimKey privata (cioè le chiavi di diversi colori della storia). Si noti che la chiave privata dell’attaccante (che è sempre la stessa per tutti gli attaccati) non viene mai trasferita sul pc delle vittime, ma viene sempre custodita con cura e utilizzata solo per decriptare la chiave della vittima.

I soldati si prepararono a catturare le loro prede, scegliendo il nascondiglio migliore per tendere loro un’imboscata. Ma ecco, dal bosco uscirono invece con gran fatica dieci contadini, stregati e controllati dal potere di Ransomio. La trappola ordita dal re era fallita miseramente, ma comunque quei poveretti portavano al collo le chiavi estratte dai cofanetti; i soldati quindi se le fecero consegnare, e si diressero al galoppo verso la città.

Nel frattempo, vocabolario alla mano il sovrano stava pronunciando tutte le parole conosciute, sperando di riuscire a liberare almeno un’altra delle sue figlie. Quando il capo delle guardie fece il suo ingresso, non rivolse alcuna parola al re, ma si diresse a testa bassa in direzione dell’ultimo cofanetto. Il re subito si zittì, ed ecco che la chiave verde riuscì con un click ad aprire il suo lucchetto. All’interno del cofanetto, il soldato trovò i quattro biglietti mancanti, e pronunciandone le parole il re poté quindi liberare tutte le sue figlie. Le casse dello stato erano vuote, ma il suo tesoro più grande era salvo, così come la prole di tutti i ricchi del regno. Nonostante la disavventura, per le strade della capitale fu organizzata una gran festa.

Una volta decriptata la VictimKey privata (la chiave verde, e anche le chiavi degli altri colori) l’attacco è concluso: con questa chiave è infatti possibile decifrare tutte le chiavi simmetriche rimanenti, e quindi attraverso l’algoritmo AES è possibile recuperare l’interezza dei file sul sistema della vittima.

Epilogo

Per tutto il giorno le strade furono invase da gente festante, e si sprecarono bevande e cibi succulenti. A notte fonda però, quando ormai anche i più resistenti festaioli del regno stavano ormai rincasando, avvenne la tragedia: uno ad uno, tutti i ragazzi che erano stati rinchiusi nei cristalli di sale si svegliarono, uscirono silenziosamente dalle loro dimore e si misero in cammino verso la Foresta del Pianto, dove furono accolti e guidati dai folletti di Ransomio. Tutti loro infatti erano stati stregati dal mago nella notte della loro cattura, ed era stato loro ordinato di radunarsi nella selva la notte successiva alla loro liberazione. La mattina, in tutto il regno vi furono profonda tristezza e grida disperate. Il re ordinò a tutti gli uomini di raggiungere la dimora dello stregone per recuperare i ragazzi, anche a costo di estirpare ogni singolo albero, ma la Foresta si dimostrò troppo fitta per essere rasa al suolo. Di tutte le vittime dell’incanto, solo il rabbioso chihuahua rimase con la sua famiglia, incrementando la disperazione del padrone di casa. Il mago Ransomio usò i suoi poteri per far innamorare di sé la più bella tra le principesse, e se la sposò; tutti gli altri ragazzi, invece, vissero per il resto della loro vita nella foresta, lavorando come domestici dello stregone.

Fu però il re Finestrone a subire la sorte peggiore: senza le sue figlie, l’accordo con i grandi regni vicini non poté essere rispettato, e quindi la guerra fu inevitabile. Per il piccolo regno fu una tremenda disfatta, e il povero sovrano fu detronizzato e rinchiuso nelle segrete del castello fino alla fine dei suoi giorni. La fertile terra del MonteRosso fu spartita tra i cinque invasori, ma anche per loro la festa non durò a lungo: dal cuore dell’oscura Foresta del Pianto, infatti, un piccolo mago era libero di tramare nell'ombra...

Perdonatemi, avrei preferito chiudere con il quarto capitolo. Questo epilogo amaro però è giustificato dalla caratteristica del software di cui stiamo parlando.

In tutta questa storia, sono poche le certezze.

Prima di tutto, siamo sicuri del fatto che qualcuna delle vittime ha pagato il riscatto. Non possiamo conoscerne il numero, ma sicuramente qualcuno ha preferito cedere alla richiesta dei criminali piuttosto che perdere i propri file.

Un’altra certezza riguarda le motivazioni di tale attacco: se l’NSA non avesse cercato di trarre guadagno dalle vulnerabilità dei sistemi Windows, e se gli utenti avessero la buona abitudine di tenere costantemente aggiornato il proprio sistema operativo, sicuramente l’attacco non sarebbe avvenuto, o comunque avrebbe avuto dimensioni più contenute.

Resta invece un grande punto interrogativo: gli utenti che hanno pagato sono effettivamente riusciti ad ottenere indietro i propri file?

Purtroppo è difficile dare una risposta a questa domanda. Ciò che è certo è che in passato molte vittime di RansomWare non sono riusciti a recuperare i propri dati, perché gli attaccanti hanno preferito richiedere ulteriori riscatti oppure semplicemente perché non ne erano in grado:  spesso, i RansomWare si limitano a fingere di criptare i dati, provvedendo invece a sovrascrivere i file con delle sequenze di byte casuali e quindi distruggendo totalmente l’informazione contenuta in memoria.

Per concludere, c’è un altro motivo per cui è sconsigliabile pagare un riscatto in questo tipo di situazioni: anche qualora fosse effettivamente possibile recuperare i dati, gli attaccanti otterrebbero un vantaggio incassando il riscatto, e sarebbero quindi invogliati ad organizzare ulteriori crimini nel futuro; per questo, è importantissimo evitare di pagare, in modo da rendere lo sforzo per organizzare l’attacco controproducente.

Se volete minimizzare il rischio di un attacco, quindi, non vi resta che seguire questi semplici consigli:

  • Tenere aggiornato il proprio sistema operativo e l’antivirus
  • Utilizzare il pc con attenzione, evitando di cliccare su allegati o siti internet sospetti
  • Effettuare regolarmente un backup dei dati importanti, facendo bene attenzione a scollegare la memoria dal sistema al termine dell’operazione in modo da proteggere le copie da eventuali attacchi

Prima di salutarvi, vorrei proporvi un programmino scritto in Go che simula il comportamento di WannaCry su tre frammenti di testo, riassumendo  quanto descritto in questi quattro articoli. Buon divertimento!


package main

import (

"bytes"

"crypto/aes"

"crypto/cipher"

"crypto/rand"

"crypto/rsa"

"crypto/sha1"

"encoding/base64"

"encoding/json"

"errors"

"fmt"

"io"

"log"

"strings"

)

func main() {

texts := []string{}

text1 := "Amor, ch’a nullo amato amar perdona, mi prese del costui piacer sì forte, che, come vedi, ancor non m’abbandona."

texts = append(texts, text1)

text2 := "Si conobbero. Lui conobbe lei e se stesso, perché in verità non s’era mai saputo. E lei conobbe lui e se stessa, perché pur essendosi saputa sempre, mai s’era potuta riconoscere così."

texts = append(texts, text2)

text3 := "La vita passa e noi la lasciamo passare come l'acqua del fiume, e solo quando manca ci accorgiamo che manca."

texts = append(texts, text3)

fmt.Println("Preparing...")

fmt.Println("**************")

fmt.Println("Creating Attacker Key...")

attackerPrivateKey, _ := createRsaKeyPair()

fmt.Println("Completed.")

attackerPublicKey := attackerPrivateKey.PublicKey

// attackerPrivateJson, _ := json.Marshal(attackerPrivateKey)

// attackerPublicJson, _ := json.Marshal(attackerPublicKey)

// fmt.Printf("Attacker Private Key: %s\n", attackerPrivateJson)

// fmt.Printf("Attacker Public Key: %s\n", attackerPublicJson)

fmt.Println("**************")



fmt.Println("Creating Demo Key...")

demoPrivateKey, _ := createRsaKeyPair()

fmt.Println("Completed.")

demoPublicKey := demoPrivateKey.PublicKey

// demoPrivateJson, _ := json.Marshal(demoPrivateKey)

// demoPublicJson, _ := json.Marshal(demoPublicKey)

// fmt.Printf("Demo Private Key: %s\n", demoPrivateJson)

// fmt.Printf("Demo Public Key: %s\n", demoPublicJson)

fmt.Println("**************")

fmt.Println("Ready to simulate a WannaCry infection!")



fmt.Println("Our targets are...")

fmt.Printf("---Text 1: %s\n", text1)

fmt.Printf("---Text 2: %s\n", text2)

fmt.Printf("---Text 3: %s\n", text3)

fmt.Println("**************")

fmt.Println("Creating Victim Key...")

victimPrivateKey, _ := createRsaKeyPair()

fmt.Println("Completed.")

victimPublicKey := victimPrivateKey.PublicKey

victimPrivateJson, _ := json.Marshal(victimPrivateKey)

// victimPublicJson, _ := json.Marshal(victimPublicKey)

// fmt.Printf("Victim Private Key: %s\n", victimPrivateJson)

// fmt.Printf("Victim Public Key: %s\n", victimPublicJson)

fmt.Println("**************")

fmt.Println("Encrypting Victim Private Key with Attacker Public Key...")

ekyKey := encryptBufWithRsa(victimPrivateJson, attackerPublicKey)

fmt.Println("Deleting Victim Private Key, to make decrypting impossible...")

victimPrivateKey = nil

victimPrivateJson = nil

fmt.Println("**************")

fmt.Println("Encrypting Texts...")

keys := [][]byte{}



for i := range texts {

fmt.Println("Encrypting text: ", i+1)

fmt.Println("Generating random Symmetric 32 bit key...")

key := generateRandomAesKey()

// fmt.Printf("Key: %s\n", key)

fmt.Println("Encrypting text with AES...")

encryptText, _ := aesEncrypt(key, texts[i])

fmt.Println("Done.")

texts[i] = encryptText

if i == 0 {

fmt.Println("Encrypting Symmetric Key with Demo Public Key...")

encryptKey, _ := rsaEncrypt(key, demoPublicKey)

keys = append(keys, encryptKey)

fmt.Println("Done.")

} else {

fmt.Println("Encrypting Symmetric Key with Victim Public Key...")

encryptKey, _ := rsaEncrypt(key, victimPublicKey)

keys = append(keys, encryptKey)

fmt.Println("Done.")

}

}

fmt.Println("**************")

fmt.Println("Now the texts are like this:")

for i := range texts {

text := texts[i]

fmt.Printf("---Text %d: %s\n", i+1, text)

}

fmt.Println("**************")

fmt.Println("Scared? Don't worry! If you pay, your texts will return like before!")

fmt.Println("Yes, your texts are still alive... We can prove it with a small set of texts!")

fmt.Println("**************")

demoCryptKey := keys[0]

fmt.Println("Decrypting Symmetric Key with Demo Private Key...")

demoKey, _ := rsaDecrypt(demoCryptKey, demoPrivateKey)

fmt.Println("Done.")

fmt.Println("Decrypting text with AES...")

demoCryptText := texts[0]

demoText, _ := aesDecrypt(demoKey, demoCryptText)

texts[0] = demoText

fmt.Println("Done.")

fmt.Println("Here's your text!")

fmt.Printf("---Text 1: %s\n", demoText)

fmt.Println("**************")

fmt.Println("Are you ready to pay? Yes? Good, Good... Eheheheh...")

fmt.Println("Decrypting the Victim Private Key with the Attacker Private Key...")

victimPrivateJson = decryptBufWithRsa(ekyKey, attackerPrivateKey)

var retrievedPrivateKey *rsa.PrivateKey

json.Unmarshal(victimPrivateJson, &retrievedPrivateKey)

fmt.Println("Done.")

fmt.Println("**************")

fmt.Println("Decrypting texts...")

for i := range texts {

if i != 0 {

fmt.Println("Decrypting text: ", i+1)

cryptKey := keys[i]

fmt.Println("Decrypting Symmetric Key with the retrieved Victim Private Key...")

key, _ := rsaDecrypt(cryptKey, retrievedPrivateKey)

fmt.Println("Done.")

fmt.Println("Decrypting text with AES...")

cryptText := texts[i]

text, _ := aesDecrypt(key, cryptText)

texts[i] = text

fmt.Println("Done.")

}

}

fmt.Println("**************")

fmt.Println("Now the texts are like this:")

for i := range texts {

text := texts[i]

fmt.Printf("---Text %d: %s\n", i+1, text)

}

fmt.Println("**************")

fmt.Println("WannaCry simulation completed correctly!")

}



// AES functions



func generateRandomAesKey() []byte {

key := make([]byte, 32)

rand.Read(key)

return key

}

func addBase64Padding(value string) string { m := len(value) % 4 if m != 0 { value += strings.Repeat("=", 4-m) }

return value } func removeBase64Padding(value string) string { return strings.Replace(value, "=", "", -1) } func pad(src []byte) []byte { padding := aes.BlockSize - len(src)%aes.BlockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(src, padtext...) } func unpad(src []byte) ([]byte, error) { length := len(src) unpadding := int(src[length-1]) if unpadding > length { return nil, errors.New("unpad error. This could happen when incorrect encryption key is used") } return src[:(length - unpadding)], nil } func aesEncrypt(key []byte, text string) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } msg := pad([]byte(text)) ciphertext := make([]byte, aes.BlockSize+len(msg)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } cfb := cipher.NewCFBEncrypter(block, iv) cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(msg)) finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext)) return finalMsg, nil } func aesDecrypt(key []byte, text string) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } decodedMsg, err := base64.URLEncoding.DecodeString(addBase64Padding(text)) if err != nil { return "", err } if (len(decodedMsg) % aes.BlockSize) != 0 { return "", errors.New("blocksize must be multipe of decoded message length") } iv := decodedMsg[:aes.BlockSize] msg := decodedMsg[aes.BlockSize:] cfb := cipher.NewCFBDecrypter(block, iv) cfb.XORKeyStream(msg, msg) unpadMsg, err := unpad(msg) if err != nil { return "", err } return string(unpadMsg), nil } //RSA functions func encryptBufWithRsa(buf []byte, pub rsa.PublicKey) [][]byte { res := [][]byte{} chunks := split(buf, 128) for i := range chunks { chunk := chunks[i] encryptChunk, _ := rsaEncrypt(chunk, pub) res = append(res, encryptChunk) } return res } func decryptBufWithRsa(buf [][]byte, priv *rsa.PrivateKey) []byte { res := []byte{} for i := range buf { chunk := buf[i] decryptChunk, _ := rsaDecrypt(chunk, priv) res = append(res, decryptChunk...) } return res } func split(buf []byte, lim int) [][]byte { var chunk []byte chunks := make([][]byte, 0, len(buf)/lim+1) for len(buf) >= lim { chunk, buf = buf[:lim], buf[lim:] chunks = append(chunks, chunk) } if len(buf) > 0 { chunks = append(chunks, buf[:len(buf)]) } return chunks } func createRsaKeyPair() (*rsa.PrivateKey, error) { size := 2048 priv, err := rsa.GenerateKey(rand.Reader, size) if err != nil { log.Fatalf("Failed to generate %d-bit key", size) return nil, err } return priv, err } func rsaEncrypt(in []byte, pub rsa.PublicKey) ([]byte, error) { sha1 := sha1.New() out, err := rsa.EncryptOAEP(sha1, rand.Reader, &pub, in, nil) if err != nil { log.Fatalf("Failed to encrypt message %v", err) return nil, err } return out, nil } func rsaDecrypt(ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) { sha1 := sha1.New() out, err := rsa.DecryptOAEP(sha1, rand.Reader, priv, ciphertext, nil) if err != nil { log.Fatalf("Failed to decrypt message %v", err) return nil, err } return out, nil }

Commenti