Non è sufficiente microtime () o mt_rand () per reimpostare la password?

4

In Qualcuno può fornire riferimenti per implementare correttamente i meccanismi di reimpostazione automatica della password delle applicazioni Web? viene menzionato l'uso di una strong casualità crittografica per generare il token di ripristino che viene inviato via email.

Se usassimo microtime (), un utente malintenzionato potrebbe indovinare solo entro 1 secondo in modo da dover applicare la forza bruta a migliaia di possibili token. Tuttavia, il token può scadere dopo un singolo tentativo fallito.

Con mt_rand () un utente malintenzionato dovrebbe reimpostare 700 password per ottenere informazioni sufficienti a mettere insieme lo stato casuale, ma supponendo che ogni chiamata sia consecutiva .. le altre persone che fanno uso del sito farebbero chiamare il trigger mt_rand che l'utente malintenzionato non ne è a conoscenza.

Quindi sembra che in entrambe le situazioni l'attaccante sia ostacolato. Ovviamente è meglio prevenire che curare, quindi è meglio usare numeri casuali crittografici, ma mi chiedo se non sia una vera vulnerabilità.

    
posta Community 02.08.2012 - 18:25
fonte

4 risposte

7

Questo paper mostra diversi metodi di attacco sulle funzioni casuali di PHP. Alla fine del foglio puoi trovare un esempio di funzione di generazione di token sicuro.

    
risposta data 02.08.2012 - 21:31
fonte
2

No, mt_rand () e microtime () non sono assolutamente sicuri. Questi sono entrambi numeri a 32 bit. Una chiave decente è completamente casuale (non temporale) e di dimensioni almeno pari a 128 bit. Inoltre mt_rand () non è crittograficamente sicuro, quindi non produce numeri veramente casuali che potrebbero essere utilizzabili per questa attività.

Hai bisogno di ottenere la chiave a 128 bit da / dev / urandom, che è meglio, è di 16 o 32 caratteri, e quindi puoi eseguirne l'hash con sale, o criptare con AES usando un'altra chiave simmetrica a 128 bit, che puoi ottenere da / dev / random, che è più lento, ma l'entropia è più alta.

    
risposta data 02.08.2012 - 20:38
fonte
1

Descrivi l'utilizzo di microtime() e dici che un tentativo errato invalida il token. Innanzitutto, un utente malintenzionato prova a eseguire un ripristino da un account che controlli per vedere come viene generato il token. Forse scoprono che assomiglia a una codifica di un set unico in un determinato fuso orario. L'attaccante cerca di stimare il ritardo del sistema (tempo di rete, tempo della CPU). Sì, è probabile che un tentativo particolare fallisca. Ma se il tuo attaccante con la sua botnet prova circa 10 tentativi al minuto, ci vorrebbe circa un giorno (se possono stimare il tempo a ~ 0.1 s prima di entrare in gioco) o una settimana (~ 1 s precisione).

Sicuramente potresti bloccare l'account del meccanismo di reset della password dopo troppi tentativi errati (ma come sarebbe stato sbloccato?), questo potrebbe frustrare gli utenti legittimi? Oh hai messo un captcha sulla pagina? Sappiamo bene che l'attaccante deve usare il turk meccanico amazzonico per sconfiggere il captcha al costo di ~ $ 2 per mille captcha (quindi costa ~ $ 20 per entrare in un account con un captcha). Ma di nuovo, se riesci a trovare facilmente i nomi di accesso di una lista (ad esempio nella pagina di creazione dell'account se ti informa che un nome utente è già in uso), non devono attaccare alcun account specifico. Ad esempio, cambiano il conto che attaccano quasi ogni volta; possibilmente (con botnet) cambiare l'IP quasi sempre, ecc.

In breve, è piuttosto banale implementarlo in modo sicuro a prova di proiettile, quindi perché mai vorresti farlo in modo insicuro, dove ti aspetti che un attaccante fuori dalla strada abbia un 1 su 100000 di entrare in un particolare tentativo? Contro ottenere una stringa casuale a 128 bit dove avrebbero avuto un 1 su 340.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000 di possibilità di indovinarlo a caso.

    
risposta data 02.08.2012 - 22:32
fonte
1

Questo è uno dei casi limite in cui, sebbene non si possa rispondere in modo definitivo con un chiaro, deciso "No! Ecco come potrei romperlo". , uno ha ancora da dire "... ma perché vuoi farlo se è così facile farlo bene?" .

Un utente malintenzionato può sfruttare microtime utilizzato come token? Almeno in teoria, la risposta deve essere: "Definitivamente e facilmente" . Non ho provato, quindi non potrei dire per certo quanto sia difficile, ma è certo che sia possibile.

Un attaccante può sfruttare microtime inserito in mt_rand ? Forse, improbabile, quasi certamente no. Almeno non con una probabilità di successo irresistibilmente alta, e non senza un lavoro considerevole. Significa che è sicuro? No.

D'altra parte, non ti costa davvero nulla per
a) usa un token con più bit (32 in realtà non è molto)
b) usa un token che è imprevedibile (generatore casuale strong)

Userei un token a 64 bit (128 se sei paranoico). L'utilizzo di un token a 128 bit è ovviamente molto più sicuro contro il brute forzato, ma poiché i token hanno una durata limitata di alcuni minuti e la quantità di richieste che possono essere inviate in rete è limitata, 64 bit dovrebbero andare bene (e in caso in cui l'utente deve digitare la chiave, significa solo la metà del problema per l'utente, inoltre solo utilizzando 64 bit si esaurirà il generatore dall'entropia più lentamente).

Se il tuo server ha un uplink gigabit, non può ricevere più di 1,1 milioni di frame al secondo (supponendo UDP e 8 byte di payload). Se i tuoi token sono validi per un periodo di tempo "normale", ad es. 15 minuti, la possibilità di riuscire a ottenere un successo durante la saturazione del collegamento durante quel periodo è 10 -11 . Inoltre, a parte le ridotte probabilità di successo, se qualcuno saturerà completamente il link per diversi minuti, questo probabilmente non passerà inosservato.
Anche l'installazione di una enorme botnet non sarà di grande aiuto. Ovviamente possono farlo, ma non importa cosa, non ci sono più frame che possono passare attraverso il cavo (limitazione fisica).

Confrontalo in uno scenario in cui potrei indovinare un token corretto da un altro token che mi hai inviato o che ho origliato con una possibilità di, diciamo 1 su 100 (questo dovrebbe essere fattibile per un timer con la risoluzione di microtime ) semplicemente guardando l'orologio! Oppure confrontalo con uno scenario in cui posso ricavare lo stato del tuo generatore da 623 messaggi consecutivi.

Anche se sono piuttosto improbabile che abbia successo in una volta, ci sono galassie tra questo e un approccio sicuro (ed entrambi ti costano lo stesso).

    
risposta data 25.09.2015 - 16:02
fonte

Leggi altre domande sui tag