Le rainbow tables sono uno strumento molto utilizzato nel cracking delle password. In questo articolo, esploreremo come funzionano e come, con la giusta fortuna, possono essere essere utilizzate per il cracking delle password anche più complesse.
Iniziamo dalle basi.
Cos'è un hash?
Una funzione di hash è una funzione matematica che prende un input di qualsiasi tipo e lo trasforma in una stringa di caratteri di lunghezza fissa (ergo, la quantità dei caratteri dell'output è sempre lo stesso). L'output della funzione di hash è univoco per ogni input, il che significa che due input diversi non possono produrre lo stesso output.
# Nel seguente esempio, eseguire una funzione di hash MD5 su una coppia di stringhe identiche, tranne che per la prima maiuscola, produce due risultati completamente diversi.
$ md5sum <<< "Hello World"
e59ff97941044f85df5297e1c302d260
$ md5sum <<< "hello World"
a687cec9c31340aa0d000c212ec64bb7
# Nell'esempio successivo, invece, si applica una funzione di hash MD5 per due volte sullo stesso input, ottenendo come risultando lo stesso output.
$ md5sum <<< "hello"
b1946ac92492d2347c6235b4d2611184
$ echo "hello" | md5sum
b1946ac92492d2347c6235b4d2611184
Le funzioni di hash sono utilizzate in molti contesti informatici, come ad esempio la crittografia delle password o la verifica dell'integrità dei dati.
Questa stringa di caratteri è ciò che viene memorizzato dal sistema quando si crea una password. Quando si tenta di accedere a un account, il sistema prende la password inserita dall'utente, la trasforma in un hash e la confronta con quella memorizzata. Se i due hash corrispondono, l'utente ha accesso all'account. In pratica, l'hashing delle password è un modo per proteggere le password e mantenere sicuri i nostri account online.
Le rainbow tables
Le rainbow tables sfruttano il fatto che l'hashing delle password sia una funzione deterministica, ovvero che la stessa password inserita produce sempre lo stesso hash. Le rainbow tables consistono in una vasta gamma di password precalcolate affiancate ai loro hash corrispondenti.
...
iloveyou 9aa2a870d0001ea6569ec7ab579bd409
qwerty a86850deb2742ec3cb41518e26aa2d89
02111974 e5790b58028288d61469d3377158df43
ForzaAzzurri 13b1afc33e5842f2672f1d94c5175c53
a9138ss@a2m#i d7939e151f8082423250ebee995f6313
Password123 a907ac8f85bbece3069a52a39947b287
...
Questo strumento può essere particolarmente utile per il cracking delle password perché rendono il processo di "recupero" molto più veloce. Invece di dover testare ogni possibile combinazione di caratteri per trovare la password corretta, il cracker può semplicemente cercare l'hash corrispondente nella tabella.
Questo si traduce in una probabilità più alta di riuscita, qualora l'utente utilizzasse una password comune.
Esempio di scenario di attacco
Poniamo il caso di un attaccante che voglia ottenere le credenziali di accesso di un utente all'interno di una infrastruttura aziendale.
A favore di questo esempio, possiamo trascurare le fasi di ricognizione preliminare, di primo accesso all'infrastruttura e i dettagli tecnici delle varie metodologie di attacco (privilege escalation, brute force, harvesting...).
Una volta ottenuto l'accesso all'infrastruttura, l'attaccante effettuerà una ricerca all'interno della rete di postazioni vulnerabili. Poniamo che, con una scansione verticale sulle porte aperte all'interno della rete, venga individuato un server Windows con porta 3306 aperta. Trattandosi della porta utilizzata da un server MySQL, l'attaccante si focalizza su quella macchina e procede ad ottenere accesso al server.
All'interno del database, l'attaccante scorre fra le tabelle e individua una tabella chiamata "users
" . Effettuata una esportazione di tutti i record della tabella, l'attaccante torna sulla sua macchina personale e procede ad effettuare il cracking delle password salvate in formato hash.
Prima di andare "a tentativi" con attacchi a forza bruta, l'attaccante utilizza le sue rainbow tables per cercare tutti gli hash all'interno del database, per escludere inizialmente quali utenti hanno registrato un account con una password già nota.
Non sempre vantaggiose
A fronte di tutto quello che si è detto, le rainbow tables hanno diverse limitazioni.
In primo luogo, esse possono occupare grandi dimensioni, il che le rende difficili da gestire e memorizzare. In secondo luogo, le rainbow tables funzionano solo con algoritmi di hashing specifici. Qualora sistema utilizzasse un algoritmo di hashing diverso da quello preparato, le tabelle perderebbero tutto il loro vantaggio e diventerebbero, di fatto, inutili.
Invincibili? Mica tanto
Ci sono diverse contromisure che possono essere adottate per proteggere il proprio database di password da un attacco con rainbow tables.
Un modo con cui più comuni è l'utilizzo di salt, ovvero l'aggiunta di un valore casuale alla password prima dell'hashing. Questo rende le rainbow tables inutili perché la password originale non è più l'unico elemento che è necessario sapere per generare l'hash.
# Nel seguente esempio potete osservare come l'aggiunta di un "salt" durante il salvataggio di una password all'interno di un database.
# Come esempio, poniamo la password scelta dall'utente come "Firenze2000"
$ md5sum <<< 'Firenze2000'
ba52afe03dc2b1d61161d29e87dd6b25
# Se il database non facesse uso di salt, questo sarebbe l'hash che verrebbe salvato direttamente nel db.
# Ora poniamo che ogni password riceva, come salt, l'ora del giorno in cui l'utente registra un account. Il processo di salvataggio diventerebbe più complesso:
$ password_utente='Firenze2000' # salviamo la pw dell'utente in una variabile
$ orario_registrazione='1540' # salviamo l'orario di registrazione in una variabile (in formato ore e minuti senza separatore)
$ echo "$orario_registrazione$password_utente" # controlliamo il contenuto delle due variabili, visualizzate una successiva all'altra
1540Firenze2000
$ md5sum <<< "$orario_registrazione$password_utente" # infine facciamo l'hash di queste due stringhe per ottenere l'hash della nostra password con salt
3575b08f0387285d92e4a0dbce23990a
# Potete osservare come l'hash della sola password sia completamente diverso da quello ottenuto con un salt.
Alternativamente, ci sono altre contromisure per tutelarsi, tra cui:
- Utilizzare algoritmi di hashing sicuri
Scegliere algoritmi di hashing robusti come SHA-256 o SHA-512 invece di algoritmi ritenuti ormai più deboli come MD5 o SHA-1. Questi algoritmi di hashing sono meno vulnerabili alle attacchi con rainbow tables, poiché le tabelle sono decisamente più lente da generare. - Iterare il processo di hashing
Eseguire più di una volta l'hashing della password può essere utile per rallentare il processo di cracking delle password. Questo rende le rainbow tables meno efficaci perché richiedono molto più tempo e risorse per creare tabelle per ogni iterazione. - Usare password complesse
Bisognerebbe incoraggiare gli utenti del proprio database ad utilizzare password complesse e lunghe. Password più lunghe e complesse sono più complicate da indovinare e sono più difficili da decifrare con un attacco rainbow tables. - Proteggere il proprio database
È fuori discussione avere come prerogativa il mettere in sicurezza il database delle proprie password per ridurre la superficie d'accesso e attacco quanto più possibile.
Alcune indicazioni per mettere in sicurezza il proprio database possono essere: usare una password di amministratore robusta, limitare l'accesso ai soli utenti autorizzati e non concedere eccezioni, effettuare e monitorare dei backup regolari.
In conclusione, le rainbow tables sono decisamente utili poiché rendono il processo di attacco e forzatura di una password molto più veloce, ma ci sono delle limitazioni da non dover trascurare e le contromisure che possono essere adottate da parte degli amministratori di sistema per rendere tutto vano.