Craccare password del database di KeePassX con John The Ripper
In precedenza ho scritto un articolo in cui sostenevo quanto fosse sicuro il password manager KeepassX ed ora sono qua a spiegare come craccare la password del suo database. No, non è una contraddizione, anzi, quest'articolo vuole dimostrare quanto sia difficile, se non umanamente impossibile, craccare una password forte.
Come già spiegato nell'altro articolo, il database di KeePassX è criptato con AES (Rijndael) 256 bit (default) o Twofish 256 bit (a vostra scelta) quindi spiegherò come tentare di craccare la password del database tramite un attacco con un dizionario di parole (wordlist) o tramite un attacco brute force, ovvero utilizzando un programma che prova tutte le combinazioni possibili di password secondo le regole definite da voi.
Per farlo utilizzeremo il famoso JTR (John The Ripper) che però, nella versione standard non supporta i file di KeePass; così utilizzeremo un programma, scritto in C, che integra questa possibilità.
Innanzitutto scarichiamo la versione di JTR comprensiva del programma C che permette il crack sugli archivi di KeePass, ovvero i file .KDB e .KDBX.
Il programma va compilato e le spiegazioni che seguono si riferiscono a Ubuntu Linux (JTR funziona anche su Windows ma le istruzioni per compilarlo sono ovviamente diverse).
Decomprimiamo il file scaricato (john-1.7.9-jumbo-7.tar.gz) e da terminale accediamo alla directory che abbiamo decompresso.
Per prima cosa facciamo una considerazione sulle prestazioni: i sorgenti scaricati sono impostati per usare un solo core del vostro PC. Se avete un PC con più core (cosa abbastanza comune con i PC di adesso avere un dual core o quad core) e volete poterli sfruttare tutti in modo da ridurre i tempi di crack, dovete modificare il sorgente del file Makefile della directory src commentando l'istruzione
OMPFLAGS =
e de-commentando l'istruzione
OMPFLAGS = -fopenmp -msse2
A questo punto siamo pronti per compilare il programma, quindi accediamo alla directory dei sorgenti
cd src
compiliamo il programma
make clean linux-x86-64-native
dove linux-x86-64-native indica il sistema per il quale deve essere creato l'oggetto. Nel vostro caso potrebbe essere diverso e per capire quali sistemi sono supportati potete usare il comando
make #
ATTENZIONE: se la compilazione termina con il seguente errore:
sha.h:4:25: fatal error: openssl/sha.h: File o directory non esistente #include <openssl/sha.h> ^ compilation terminated. make[1]: *** [dynamic_fmt.o] Errore 1
dovete installare il pacchetto libssl-dev con il comando
sudo apt-get install libssl-dev
quindi ripetete la compilazione.
Terminata la compilazione uscite dalla directory src e testate che JTR funzioni correttamente:
cd .. ./run/john --test
Se tutto OK vedrete testare tutti i tipi di crack gestibili con JTR con un benchmark sulle prestazioni.
E' ora di cominciare a fare sul serio, quindi cominciamo a tentare il crack della password.
Per il test uso un database di KeePassX che si chiama gino.kdb e una semplicissima password: sun.
Iniziamo con il tipo di attacco brute force con i seguenti comandi:
./run/keepass2john /home/paolo/KP_Test/gino.kdb > test.txt ./run/john -incremental:alpha -format:keepass test.txt
Con il paramentro -incremental settato ad alpha diciamo a JTR di eseguire un attacco brute force di tipo alfabetico, ovvero solo con lettere dell'alfabeto minuscole (26 caratteri), quindi niente numeri, niente caratteri speciali e niente lettere MAIUSCOLE.
Si usa per ridurre moltissimo i tempi di crack, ma ha successo solo se la password utilizzata rispetta quei criteri.
Durante l'esecuzione è sufficiente premere un qualunque tasto per vedere la parola che sta provando in quel momento JTR.
L'esito è stato il seguente:
guesses: 1 time: 0:00:03:24 DONE (Sat Mar 15 08:25:21 2014) c/s: 42.09 trying: sun
Per la banale password sun ha impiegato il seguente tempo:
- 3.24 minuti usando UN solo core con incremental mode alpha
- 3.47 minuti usando UN solo core con incremental mode all (ovvero qualunque carattere)
- 1.01 minuti usando 8 core con incremental mode alpha
- 1.08 minuti usando 8 core con incremental mode all
ATTENZIONE: se tentate di ripetere test sullo stesso DB e ottenete il seguente messaggio:
No password hashes left to crack (see FAQ)
eliminate il file john.pot in ./john/run/ perchè in quel file è registrata la password che ha trovato per la prova effettuata. Infatti potete leggerla dando il seguente comando:
./run/john --show test.txt
I test indicati sono stati fatti in configurazione standard definita in ./john/run/john.conf che tra le altre cose prevedono la combinazione di password con un massimo di 8 caratteri. Se pensate che la password abbia più di 8 caratteri dovete modificare il john.conf, ma in questo caso vi conviene lasciar perdere perchè diventate vecchi 😀 ammenochè non abbiate i mega server nell'NSA 👿 .
La password fin qui testata è veramente banale ma è sufficiente modificarla leggermente per rendere lunghissimo il tempo di crack, ad esempio utilizzando la password è sUn.
Innanzitutto l'incremental mode alpha non la troverà mai perchè testa solo caratteri minuscoli.
Provando con l'incremental mode all in configurazione standard (max 8 caratteri) dopo quasi 2 ORE e mezza non aveva ancora trovato la password e aveva testato meno dello 0,01% delle combinazioni possibili.
Di seguito alcuni tentativi:
guesses: 0 time: 0:00:01:00 0.00% c/s: 136 trying: 46984309 - 46876996 guesses: 0 time: 0:00:01:23 0.00% c/s: 141 trying: salasant - 48858721 guesses: 0 time: 0:00:01:26 0.00% c/s: 141 trying: 48858720 - setta guesses: 0 time: 0:00:11:35 0.00% c/s: 150 trying: suristes - cranger1 guesses: 0 time: 0:00:11:48 0.00% c/s: 150 trying: crestert - crister1 guesses: 0 time: 0:00:13:06 0.00% c/s: 150 trying: muf1816 - clasice guesses: 0 time: 0:00:17:01 0.00% c/s: 150 trying: 49660101 - 48888087 guesses: 0 time: 0:00:17:04 0.00% c/s: 150 trying: 48888082 - 46964199 guesses: 0 time: 0:00:17:07 0.00% c/s: 150 trying: 46964197 - stantard guesses: 0 time: 0:00:17:14 0.00% c/s: 150 trying: sandries - samitard guesses: 0 time: 0:02:16:55 0.00% c/s: 154 trying: 49490513 - 49492100 guesses: 0 time: 0:02:17:06 0.00% c/s: 154 trying: 48362969 - 48358837 guesses: 0 time: 0:02:17:29 0.00% c/s: 154 trying: 46282764 - 46272920 guesses: 0 time: 0:02:17:32 0.00% c/s: 154 trying: 46272923 - 46278977 guesses: 0 time: 0:02:18:23 0.00% c/s: 154 trying: satewest - satheens guesses: 0 time: 0:02:18:49 0.00% c/s: 154 trying: shurares - shumiloo guesses: 0 time: 0:02:22:08 0.00% c/s: 154 trying: 177r - soru guesses: 0 time: 0:02:22:25 0.00% c/s: 154 trying: 367r - choy guesses: 0 time: 0:02:22:31 0.00% c/s: 154 trying: p-1a - jw7r guesses: 0 time: 0:02:24:13 0.00% c/s: 154 trying: mikistec - mordisso guesses: 0 time: 0:02:26:21 0.00% c/s: 154 trying: 34274875 - 34262739
Così ho modificato john.conf per dirgli di testare password di 3 caratteri al massimo (MaxLen=3 per incremental mode all).
Con questa configurazione (assolutamente assurda) ha impiegato circa 27 minuti!!!
Di seguito si può notare che l'ha trovata dopo aver provato circa il 28% delle combinazioni di password possibili.
guesses: 0 time: 0:00:00:41 0.64% (ETA: Sat Mar 15 11:37:56 2014) c/s: 124 trying: kks - bap guesses: 0 time: 0:00:01:04 1.06% (ETA: Sat Mar 15 11:31:47 2014) c/s: 136 trying: xap - sm8 guesses: 0 time: 0:00:01:07 1.12% (ETA: Sat Mar 15 11:30:52 2014) c/s: 136 trying: spx - lvy guesses: 0 time: 0:00:05:49 6.02% (ETA: Sat Mar 15 11:27:48 2014) c/s: 147 trying: 00d - 0bw guesses: 0 time: 0:00:05:53 6.08% (ETA: Sat Mar 15 11:27:55 2014) c/s: 147 trying: 0by - 09l guesses: 0 time: 0:00:07:59 8.27% (ETA: Sat Mar 15 11:27:42 2014) c/s: 148 trying: jyS - ehS guesses: 0 time: 0:00:10:09 10.51% (ETA: Sat Mar 15 11:27:44 2014) c/s: 148 trying: Jf0 - Jqv guesses: 0 time: 0:00:13:16 13.76% (ETA: Sat Mar 15 11:27:35 2014) c/s: 149 trying: sSv - eS7 guesses: 0 time: 0:00:13:37 14.12% (ETA: Sat Mar 15 11:27:36 2014) c/s: 149 trying: 1nK - R4M guesses: 0 time: 0:00:15:26 16.01% (ETA: Sat Mar 15 11:27:33 2014) c/s: 149 trying: qKN - 0sE guesses: 0 time: 0:00:19:49 20.50% (ETA: Sat Mar 15 11:27:50 2014) c/s: 148 trying: v-n - 6-w guesses: 0 time: 0:00:20:21 21.03% (ETA: Sat Mar 15 11:27:55 2014) c/s: 148 trying: NO# - s.# guesses: 0 time: 0:00:22:09 22.92% (ETA: Sat Mar 15 11:27:48 2014) c/s: 149 trying: tBc - hBE guesses: 0 time: 0:00:24:15 25.17% (ETA: Sat Mar 15 11:27:31 2014) c/s: 149 trying: *TA - pGg guesses: 0 time: 0:00:25:42 26.70% (ETA: Sat Mar 15 11:27:25 2014) c/s: 149 trying: 5H> - CHw guesses: 0 time: 0:00:26:21 27.41% (ETA: Sat Mar 15 11:27:18 2014) c/s: 149 trying: @lx - @fA sUn (/home/paolo/KP_Test/gino.kdb) guesses: 1 time: 0:00:26:45 DONE (Sat Mar 15 10:17:55 2014) c/s: 149 trying: mUH - zUg
Un altro metodo d'attacco è quello tramite un dizionario di parole elencate in un file di testo, ovvero una wordlist.
Supponendo di impostare la password martellato presente nel file prova.txt di 306.707 parole in ordine alfabetico, il comando da utilizzare è il seguente:
./run/keepass2john /home/paolo/KP_Test/gino.kdb > test_martellato.txt ./run/john --wordlist=./wordlist/prova.txt -format:keepass test_martellato.txt
per trovare la password ha impiegato quasi 16 minuti:
guesses: 0 time: 0:00:12:18 36.55% (ETA: Sat Mar 15 14:45:33 2014) c/s: 154 trying: histoplasmosis - holostome guesses: 0 time: 0:00:12:51 38.36% (ETA: Sat Mar 15 14:45:23 2014) c/s: 154 trying: iem - imaginable guesses: 0 time: 0:00:13:53 41.88% (ETA: Sat Mar 15 14:45:03 2014) c/s: 154 trying: inveigher - ipidae martellato (/home/paolo/Dropbox/Backup/KP/gino.kdb) guesses: 1 time: 0:00:15:52 DONE
Invece, impostando l'ultima password del dizionario (zyzzogeton), per trovarla e quindi utilizzare interamente le 306.707 parole, ha impiegato 33 minuti.
Considerate che un dizionario del genere pesa circa 3 MB e con 306.707 parole non è molto efficace. In internet si possono anche acquistare dizionari molto pesanti di vari GigaByte e ovviamente il tempo di scansione aumenta notevolmente.
Come potete notare da questi test craccare la password del database di keePass è impresa quasi impossibile con una password decente.
Per la cronaca vi segnalo quali sono gli incremental mode possibili per un attacco brute force con questa versione di John The Ripper (li trovate descritti anche in ./john/doc/MODES):
- All: tutti i caratteri (95)
- Alpha: tutte le lettere minuscole (26)
- Digits: tutte le cifre (10)
- Alnum: tutte le lettere minuscole e tutte le cifre (36)
- LanMan: LM hashes (69 caratteri)
Ultima chicca: se non si vogliono usare tutti i core a disposizione è possibile anche specificare quanti usarne tramite l'opzione OMP_NUM_THREADS=n dove "n" è il numero dei core da uutilizzare; ad esempio, se si vogliono utilizzare 5 core degli 8 disponibili il comando sarà:
OMP_NUM_THREADS=5 ./run/john -incremental:all -format:keepass test.txt
Con il monitor delle risorse di Ubuntu è facile controllare l'utilizzo effettivo dei core come dagli esempi indicati di seguito:
Se siete arrivati a leggere fino a questo punto avrete capito alcune cose fondamentali:
- le password devono essere forti: lettere (minuscole e MAIUSCOLE), numeri, caratteri speciali e magari superare gli 8 caratteri
- craccare una password forte è quasi impossibile con normali strumenti
- con una password forte come chiave di criptazione di KeePassX potete dormire sonni tranquilli 😉
One thought on “Craccare password del database di KeePassX con John The Ripper”