_____
 / ____|
| |  __
| | |_ |
| |__| |
 \_____|
  ___
 / _ \
| (_) |
 \___/
 _ __
| '__|
| |
|_|
 _
| |
| |
| |
| |
|_|
  __ _ 
 / _` |
| (_| |
 \__,_|
 _ __  
| '_ \ 
| | | |
|_| |_|
 _ 
(_)
 _ 
| |
| |
|_|
      ___    ___    _ __ ___  
     / __|  / _ \  | '_ ` _ \ 
 _  | (__  | (_) | | | | | | |
(_)  \___|  \___/  |_| |_| |_|
Reverse, Repurpose, Resolve

Audit delle password su Windows

2019-04-18

Audit delle password, come e perchè

"Audit delle password" sembra un modo gentile per giustificare qualcosa che non suona bene, cioè vedere se le password di qualcun altro sono "sicure". Proviamo a fare un passo indietro. Se amministrate un sistema più o meno grande in ambito aziendale, vi troverete a far fronte a diverse esigenze: quelle degli utenti (pochi impicci sul lavoro) e quelle della sicurezza IT, nonché quelle legate alle normative vigenti (ad esempio il GDPR) e ai regolamenti aziendali. Non è questo il posto per descrivere come arrivare ad un equilibrio adeguato, ma senza dubbio si arriva sempre a definire una password policy, ovvero come devono essere gestite le password degli utenti. Lo scopo è far si che le password siano sufficientemente sicure per ciò che devono proteggere e che non "vadano in giro" troppo facilmente. Per questo motivo si impostano solitamente diversi criteri che vengono resi obbligatori:

La complessità può essere ottenuta in vari modi, tipicamente obbligando l'utente ad utilizzare almeno un carattere per ognuno degli insiemi facilmente disponibili: lettere minuscole, lettere maiuscole, numeri e simboli (ad es. $%&/+-^=!). A cosa serve fare ciò? Serve a rendere estremamente complessa l'opera di decifratura mediante brute force (per tentativi) delle password. Dovendo provare solo le lettere minuscole abbiamo 25 possibili caratteri per ogni posizione, quindi una password di 8 caratteri minuscoli richiede 25^8 tentativi per essere certamente recuperata. Se aggiungiamo anche le maiuscole ed il resto indicato sopra abbiamo 25+25+10+10 possibilità per ogni posizione, quindi 70^8 combinazioni (molte di più). All'atto pratico è molto difficile indovinare una password di questo tipo, anche con le tecnologie attuali.

Quindi con relativamente poca fatica possiamo ottenere delle password solide. Il fatto di doverle cambiare (durata massima) e non poter riciclare le vecchie (durata minima e storia) fa si che il tempo necessario a trovare una password sia superiore al tempo di vita della stessa, rendendo così inutile il processo (o, meglio, aumentandone il costo).

Nel mondo Windows di cui parliamo, intendendo un ambiente aziendale e quindi con un dominio, quanto indicato sopra si ottiene con le Group Policies. Le utenze cui vengono applicate devono sottostare a quanto definito e le loro password vengono registrate sul disco del Domain Controller protette da un algoritmo di hash e da una chiave; inoltre i file veri e propri non sono facilmente accessibili.

Ma perché potrebbero esserci password non conformi alle regole? Assunto che le Group Policies funzionino correttamente, e di solito succede, è possibile che queste non siano applicate a tutti i rami della directory che contengono gli account, quindi alcuni utenti avranno i vincoli ed altri no (o li avranno differenti). E' possibile che le policies siano applicate successivamente all'impostazione delle password, è possibile che esistano vecchi account con la password che non espira mai (è un'opzione, vedi sotto) ed impostate magari molto tempo addietro. E' possibile che qualcuno rispetti le regole di complessità ma usi password facilmente indovinabili: ad esempio Pa$$w0rd rispetta le regole, ma è debole perché presente in molti "dizionari", cioè collezioni di password comuni. Windows non ha integrato un meccanismo per controllare l'esistenza della password in un elenco di quelle utilizzate spesso, c'è necessità di prodotti terzi per farlo.

Quindi tornando alle procedure aziendali (o alle norme vigenti), può essere necessario effettuare regolarmente degli audit delle password, ovvero la verifica che quelle in uso rispettino i criteri definiti. Tuttavia questo può essere piuttosto difficile visto che non le possiamo leggere dal disco e nemmeno chiederle agli utenti. Vediamo quindi di cosa abbiamo bisogno per procedere, ottenere il risultato in poco tempo ed in maniera ripetibile.

I passi che dovremo percorrere sono 3:
  1. Ottenere il database degli hash delle password
  2. Estrarlo in una forma lavorabile
  3. Verificare le password deboli

Ottenere il database delle password

Nel tempo si sono succeduti su Windows diversi modi per ottenere gli hash delle password, più o meno "puliti" e funzionanti. La maggior parte richiede l'utilizzo di tool che vengono scaricati da siti abbastanza dubbi (ricordate che vanno eseguiti con privilegi elevati) e vengono comunque spesso bloccati dagli antivirus. Noi però non stiamo effettuando un'operazione di hacking da telegiornale e partiamo da una posizione di vantaggio: siamo gli amministratori della rete. Microsoft ha integrato in ntdsutil uno strumento (IFM) che può essere utilizzato per eseguire attività di installazione automatizzata, ma che ben si adatta a questa attività. Essendo supportato e parte dei corsi, siamo sicuri che sarà supportato ancora a lungo.

Aprendo quindi un cmd su un Domain Controller ed eseguiamo ntdsutil. I comandi in sequenza da dare (uno per riga) sono i seguenti:

activate instance ntds
ifm
create full c:\my-audit
quit
quit
(di nuovo, dobbiamo uscire da due contesti)

NTDS audit

Quello che succede è che viene effettuato uno snapshot del disco per poter accedere ai file di registro e directory che sono aperti in maniera esclusiva e non accessibili altrimenti, quindi viene eseguita una procedura di compattazione e verifica di coerenza del database di Active Directory.

Alla fine ci troviamo con due sotto directory nella c:\my-audit, una che comprende i dati della directory e una che contiene un paio di pezzi del registro di sistema. In uno di questi (SYSTEM) c'è la chiave per decifrare alcune sezioni della prima ed estrarre gli hash. Prendiamo quindi il file ntds.dit da Active directory e SYSTEM (non ha estensione) da registry e copiamoli per semplicità in una directory temporanea (c:\auditing) sulla workstation di lavoro. Possiamo chiudere il DC, non ci servirà più, ma prima di farlo eliminiamo la directory c:\my-audit dove abbiamo lasciato dei file potenzialmente sensibili.

Estrarre gli hash

Anche per questa operazione esistono (e sono esistiti) diversi tool. Quello che uso ora e che funziona bene si chiama NTDSAudit lo trovate qui: https://github.com/Dionach/NtdsAudit/releases. E' open source e viene aggiornato. Per funzionare richiede di sapere dove è il file .dit dell'Active Directory e dove è quello della sezione SYSTEM del registro, esattamente i due che abbiamo messo nella nostra c:\auditing.

NTDS audit

Va lanciato così:

ntdsaudit.exe c:\Auditing\ntds.dit -s c:\Auditing\SYSTEM --pwdump c:\Auditing\hashes.txt -u c:\Auditing\utenti.csv

(la parte evidenziata è un comando solo su una riga)
Il parametro --pwdump indica dove andare a creare il file con gli hash delle password e -u indica il nome del file CSV (importabile in Excel o Calc) che comprende le informazioni sugli utenti. Durante l'esecuzione inoltre viene mostrata una tabella riassuntiva che esamina le anomalie più frequenti: ne parliamo in seguito.

Concentriamoci quindi sul file hashes.txt. Contiene una riga per ogni utente e la forma è la seguente:

fake.domain\Administrator:500:AAFFB435B51CC4EEA3335599B5140AFE:3DAF4315815FE4555C08B635554AE99B:...

La parte che ci interessa per ora è AAFFB435B51CC4EEA3335599B5140AFE:3DAF4315815FE4555C08B635554AE99B, cioè l'hash della password e non è semplice da leggere. Quindi procediamo.

Verificare le password deboli

A questo punto abbiamo gli hash delle password e abbiamo da scegliere tra la pillola rossa e quella blu. Intendiamoci, con questo file e gli strumenti di cui parleremo è possibile "crackare" le password di tutti gli utenti di dominio avendo tempo e risorse necessari, ma noi stiamo effettuando un audit, che è cosa diversa. L'idea è perciò di utilizzare gli strumenti in maniera molto veloce configurandoli per trovare solo le password che riteniamo "insicure" allo scopo di eliminarle.

Come nei casi precedenti, nel tempo si è usato di tutto per crackare gli hash Windows, da programmi più o meno esotici alle rainbow tables. Per quello che vogliamo fare noi ne possiamo usare uno dei due seguenti, anche averli entrambi aiuta: il primo è hashcat, il secondo è il solito john, disponibile in diverse incarnazioni.

Partiamo da john (versione originale, versione enhanced "jumbo"): non ho mai provato a compilarlo su Windows, ma che ci siate riusciti o meno l'uso è piuttosto semplice:

./john --format=nt /tmp/hashes.txt --single

John the ripper in azione

Questo esegue una sessione molto minimale di cracking. Per vedere se e cosa ha trovato il comando è lo stesso di prima con --show invece che --single. Questo mostra l'insieme delle password trovate e registrate nel potfile.

./john --format=nt /root/hashes.txt --show

Potete anche lanciarlo senza l'opzione --single: in questo caso parte una sessione un pochino più complessa e con uso di un dizionario (vediamo in seguito). Potete fermarla con ctrl-c oppure q in ogni momento e vedere con l'opzione --show cosa è stato trovato.

L'altra possibilità è usare hashcat. Ci sono due vantaggi: lo trovate pronto e compilato per Windows ed utilizza bene le GPU per il cracking più pesante. Non è il caso in questione visto che vogliamo trovare solo i problemi più grossi e non tutte le password. Inoltre mi permette una digressione sui dizionari: è molto comune usare sempre le stesse password in giro per il mondo, quindi come nell'esempio Pa$$w0rd di prima possiamo avere una password formalmente valida ma ricorrente ed indovinabile.

Per un audit delle password comuni bisogna quindi avere un dizionario da utilizzare. La costruzione di un dizionario (anche detto wordlist) è molto personale e specifica, da sola richiederebbe una trattazione, ma con bene in mente cosa vogliamo fare possiamo iniziare chiedendo a Google qualche dizionario, se ne trovano molti: http://lmgtfy.com/?q=password+dictionary. Per semplicità qui c'è un link ma ne trovate davvero molti. Sicuramente vi conviene arricchirli almeno con le password che sapete essere state in uso nel tempo nel vostro contesto, spesso infatti si ripresentano o vengono usate da più utenti. Assumendo quindi di averne scelto (o costruito) uno e salvato come dict.txt nella nostra directory di lavoro, e trovandoci nella directory dove avete scompattato hashcat lanciamo:

hashcat64.exe -m 1000 c:\Auditing\hashes.txt c: \Auditing\dict.txt

Il parametro -m 1000 dice che stiamo cercando password di Windows/NTLM (hashcat supporta decine di hash diversi). L'esecuzione dovrebbe essere breve e indicare diverse cose, tra cui il numero di password trovate.

hashcat in azione

(Nota: hashcat indica che il dizionario in uso è piccolo e non sufficiente ad un cracking efficiente: lo sappiamo ed è previsto per l'attività che stiamo facendo).

Come per john possiamo vedere i potfile con le password usando il comando show:

hashcat64.exe -m 1000 c:\Auditing\hashes.txt --show

Quello che NON vogliamo trovare sono, appunto, le password in quanto vorrebbe dire che non sono della qualità richiesta. Se ne individuate una attuate la procedura interna di cambio forzato operando sulla directory (Force password change at next logon, nelle opzioni utente) o contattando l'utente.

Sia john che hashcat permettono di fare cose più complesse e sicuramente fuori dallo scopo di questo documento: usare entrambi gli strumenti non è banale e dovete rifarvi alla loro documentazione. Sicuramente da fare è il creare attacchi basati sulle mutazioni al dizionario: da una password base come "Ronaldo" non valida nelle nostre regole, è possibile derivare "Ronaldo99!" che potrebbe esserlo. Il riferimento è ai diversi parametri "-a" di hashcat chiamati attacchi ibridi.

Potete poi provare a studiare le "regole" di john e hashcat che permettono di definire la "forma" delle password da provare. Solitamente si usano per cercare davvero le password ma se definite delle regole semplici (ad esempio: 8 numeri di fila) potete migliorare l'audit che state facendo eliminando altre classi di possibili password deboli. State entrando nella foresta del brute force, quindi tempo e risorse cominciano ad avere un peso che potrebbe diventare grande.

Bonus track

Apriamo il file CSV generato al punto 2 in Excel e diamogli un'occhiata. Ci sono per ogni utenza una serie di colonne interessanti in fase di audit. Innanzi tutto alcune indicano gli account privilegiati (Administrator, Domain Admin, Enterprise Admin) che chiaramente devono essere protetti con password più forti. Possiamo poi vedere account disabilitati o scaduti. I secondi sono account a tempo solitamente configurati ad esempio per consulenti esterni che abbiamo un progetto da terminare entro una data. Gli account disabilitati dovrebbero essere tutti quelli delle persone che per un motivo o per l'altro non devono più accedere al dominio. Molto spesso capita che quando una persona lascia l'azienda il suo account resti attivo e questo può portare a diversi problemi. La colonna Last logon ci aiuta a capire quando gli account hanno effettivamente fatto l'ultimo accesso (ci sarebbe da approfondire, prendetela come un'approssimazione). Tipicamente account che non accedono da tempo sono ottimi candidati alla disabilitazione in quanto probabilmente "dimenticati". Password last changed ci dice l'età della password. Anche qui possiamo trovare anomalie con password più vecchie di quanto consentito dalla policy e quindi da cambiare appena (se) possibile. Spesso questi account hanno il temibile flag Password Never Expires, che indica appunto che a quell'utente non è mai richiesto di modificare la propria password. Non è sbagliato in assoluto ad esempio per gli account di servizio, ma sono situazioni di cui essere consapevoli e le password di questi account devono essere particolarmente forti. Infine il Password Not Required: in questo caso spesso si tratta di anomalie e non necessariamente di problemi di sicurezza e non significa direttamente che l'utente in questione possa accedere senza password. Magari ci torneremo, ma qualche idea la trovate da qui e poi col solito Google.

Un riassunto di queste informazioni lo trovate nell'output di NtdsAudit che avete utilizzato in precedenza

NtdsAudit output

Da notare che non essendo gli hash NTLM dotati di salt è possibile sapere quante password uguali ci sono e chi le ha uguali a chi altro. Questo significa anche che una volta trovata per uno di questi utenti, l'abbiamo trovata anche per gli altri.

La scorciatoia

Esistono anche siti dedicati in cui vengono raccolti tutti gli hash ritrovati delle password, come ad esempio Crackstation e altri che potete trovare con semplici ricerche. A volte è sufficiente mettere proprio l'hash della password in Google per scoprire che magari da qualche parte qualcuno ha pubblicato la password originale. Ricordatevi sempre che se utilizzate un sistema online come quello indicato sopra è buona norma modificare gli username nei file di hash e magari non usare un IP del sistema di cui caricate le password. Non sapete a chi andranno in mano i file che caricate!

Per concludere

Cercare di capire se le password del nostro ambiente (dominio in questo caso, ma vale ovunque) sono sufficientemente sicure è un'opera necessaria. Non fidiamoci delle impostazioni che facciamo oggi perché come abbiamo visto ci sono casi in cui ciò potrebbe non essere sufficiente. Ho usato sufficientemente in quanto tutti i parametri legati alla gestione della password non necessariamente sono gli stessi per tutti gli utenti che magari accedono risorse con differenti criticità. Ci sono casi dove la password non è nemmeno l'unico elemento per accedere ad un sistema, ad esempio quando è richiesta un'autenticazione multi fattore che alla password abbina un telefonino, una smart card o un token. E' stata più lunga del previsto, ma se sei arrivato in fondo e hai domande o suggerimenti, yell for sysop!