Come forza bruta questo token in php, se è possibile

-6

è possibile forzare questo token (MD5 Hash) del seguente script (PHP) in un momento realistico (0,5h - 24h)? Se la risposta è SI, come potrei farlo, ad esempio con PHP o Python?

$time = microtime();
$secret = MD5('$time' . rand(1, 100));
    
posta user126623 25.06.2016 - 22:52
fonte

2 risposte

2

Come scritto, è abbastanza facile, perché PHP non espanderà le variabili all'interno di virgolette singole. Quindi '$ time' è i cinque caratteri costanti '$', 't', 'i', 'm', 'e', invece di un numero molto lungo e crescente.

Quindi questa potrebbe essere stata una domanda trabocchetto, per indurre qualcuno a dire "è molto difficile" quando in realtà non lo è.

Supponendo che sia stato scritto

md5("{$time}".rand(1, 100));

quindi molto dipenderebbe dalla precisione effettiva del timer della piattaforma attaccata. microtime () restituirà un tempo con microsecondi, ma lo fa chiamando gettimeofday . Potresti quindi avere solo 100.000 tentativi in un solo secondo.

Quindi devi craccare dieci milioni di hash MD5 ogni secondo nel tuo intervallo di tempo. Se sai che l'hash è stato generato in una determinata ora (oggi tra le 15:30 e le 16:30), è necessario eseguire 36.000.000.000 di tentativi.

Su un buon hardware puoi ottenere circa 2-8 milioni di MD5 al secondo , il che significa che il cracking deve essere eseguito per un tempo 1-10 volte il tempo necessario per craccare. Ovviamente, l'utilizzo di più computer ridurrebbe proporzionalmente il tempo richiesto.

Nel peggiore dei casi (vera risoluzione in microsecondi) è necessario circa un giorno per ogni ora di intervallo. Se sai che un hash è stato generato tra le 15:30:00 e le 15:30:15 di oggi (15 secondi), puoi craccarlo in circa sei minuti.

Aggiornamento

Dal tuo commento, se questo è per la sicurezza del tuo sito, ti consiglio vivamente di passare a bcrypt hash (controlla anche il link e la documentazione a cui fa riferimento)

Quindi, per confermare che un token di questo tipo è sicuro, puoi inviare un token creato in questo modo:

$secret = 'YourSiteVerySecretPassword';
$date   = date('YmdHis');
// Put whatever you want in the $token.
$token  = "{$username}:{$date}";
$send   = $token . '-' . $bcrypt->hash($secret . $token);

L'utente ti invierà un link che puoi esplodere ('-') in due parti separate da un trattino:

list($token, $hash) = explode('-', $receivedToken);
if ($bcrypt->verify($secret . $token, $hash)) {
    // Token is valid. You can further explode it using ':',
    // and for example extract the date and time and verify that
    // it is within 24 hours of the current timestamp. Otherwise
    // the token is valid, yes, but it is "stale".
}
    
risposta data 25.06.2016 - 23:17
fonte
0

Questo sarebbe stato un commento ma è diventato troppo lungo, ed è in realtà una risposta: probabilmente stai andando in questo modo nel modo sbagliato.

Quale possibile uso può avere un utente malintenzionato di forzare il token? L'unico segreto protetto dal token è l'ora e il risultato della chiamata a rand ().

Se invii questi token per posta all'utente richiedente e gli chiedi di produrre il token per reimpostare la sua password, l'utente non avrà alcuna difficoltà a capire quale sia il tempo in $ quando ha fatto la richiesta e ottenere il risultato della tua chiamata a rand (), ma a lui non interesserà neanche. Tuttavia, per tu sapere che il token è valido, devi registrarlo nel tuo database del sito web. (Esistono modi per evitare di registrare elementi nel database del tuo sito web, ma sono anche peggio dal punto di vista della sicurezza o eccessivamente complicati.)

Se un utente malintenzionato presenta una richiesta falsa, non ha il token, ma conosce il tempo entro meno di un secondo o giù di lì, quindi con meno di centomila richieste del sito Web può colpire il token corretto. Il tempo per fare md5 (sia su un orologio che su un supercluster) è irrilevante. Se non applichi ulteriore protezione, qualcuno potrebbe probabilmente riuscire a ripristinare la password di qualcun altro, che presumo sia ciò che stai cercando di evitare.

Poiché devi comunque registrare la richiesta di reimpostazione della password nel tuo database, perché non registrare e inviare un token totalmente casuale (insieme a nome utente o ID richiesta e data di scadenza)?

    
risposta data 25.06.2016 - 23:48
fonte

Leggi altre domande sui tag