mt_rand() verwendet den Mersennetwister-Algorithmus, um zufällige Ganzzahlen zurückzugeben. Der folgende Artikel stellt Ihnen jedoch hauptsächlich die relevanten Informationen zur Sicherheit von mt_rand()-Zufallszahlen in PHP vor. Sie brauchen Freunde, auf die Sie sich beziehen können
Vorwort
Ich habe vor einiger Zeit viele Sicherheitslücken im Zusammenhang mit mt_rand() ausgegraben, und das waren sie auch Grundsätzlich Fehler. Verstehen Sie die Verwendung von Zufallszahlen. Hier möchte ich einen weiteren Fallstrick des offiziellen PHP-Website-Handbuchs erwähnen. Schauen Sie sich die Einführung zu mt_rand() an: Chinesische Version ^cn Englische Version ^en Sie können sehen, dass die englische Version eine zusätzliche gelbe Warnung enthält >
This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.
Pseudozufallszahl
wobei „seed“ der Zufallszahlen-Seed ist und i die Häufigkeit angibt, mit der diese Zufallszahlenfunktion aufgerufen wird. Wenn wir die beiden Werte von i und rand gleichzeitig kennen, können wir den Wert von Seed leicht berechnen. Beispielsweise werden rand=21 und i=2 in die Funktion 21=seed+(2*10) eingesetzt, um Seed=1 zu erhalten. Ist es nicht sehr einfach? Nachdem wir den Startwert erhalten haben, können wir den Wert von Rand berechnen, wenn i ein beliebiger Wert ist. rand = seed+(i*10)
PHPs automatisches Seeding
PHPAPI void php_mt_srand(uint32_t seed) { /* Seed the generator with a simple uint32 */ php_mt_initialize(seed, BG(state)); php_mt_reload(); /* Seed only once */ BG(mt_rand_is_seeded) = 1; } /* }}} */ /* {{{ php_mt_rand */ PHPAPI uint32_t php_mt_rand(void) { /* Pull a 32-bit integer from the generator state Every other access function simply transforms the numbers extracted here */ register uint32_t s1; if (UNEXPECTED(!BG(mt_rand_is_seeded))) { php_mt_srand(GENERATE_SEED()); } if (BG(left) == 0) { php_mt_reload(); } --BG(left); s1 = *BG(next)++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680U; s1 ^= (s1 << 15) & 0xefc60000U; return ( s1 ^ (s1 >> 18) ); }
<?php //pid.php echo getmypid();
<?php //test.php $old_pid = file_get_contents('http://localhost/pid.php'); $i=1; while(true){ $i++; $pid = file_get_contents('http://localhost/pid.php'); if($pid!=$old_pid){ echo $i; break; } }
<?php //pid1.php if(isset($_GET['rand'])){ echo mt_rand(); }else{ echo getmypid(); }
<?php //pid2.php echo mt_rand();
<?php //test.php $old_pid = file_get_contents('http://localhost/pid1.php'); echo "old_pid:{$old_pid}\r\n"; while(true){ $pid = file_get_contents('http://localhost/pid1.php'); if($pid!=$old_pid){ echo "new_pid:{$pid}\r\n"; for($i=0;$i<20;$i++){ $random = mt_rand(1,2); echo file_get_contents("http://localhost/pid".$random.".php?rand=1")." "; } break; } }
old_pid:972 new_pid:7752 1513334371 2014450250 1319669412 499559587 117728762 1465174656 1671827592 1703046841 464496438 1974338231 46646067 981271768 1070717272 571887250 922467166 606646473 134605134 857256637 1971727275 2104203195
smldhz@vm:~/php_mt_seed-3.2$ ./php_mt_seed 1513334371 Found 0, trying 704643072 - 738197503, speed 28562751 seeds per second seed = 735487048 Found 1, trying 1308622848 - 1342177279, speed 28824291 seeds per second seed = 1337331453 Found 2, trying 3254779904 - 3288334335, speed 28811010 seeds per second seed = 3283082581 Found 3, trying 4261412864 - 4294967295, speed 28677071 seeds per second Found 3
<?php mt_srand(735487048);//手工播种 for($i=0;$i<21;$i++){ echo mt_rand()." "; }
php_mt_seed
Wir wissen bereits, dass die Erzeugung von Zufallszahlen von einer bestimmten Funktion abhängt, die oben als rand = seed+(i*10)
angenommen wurde. Für eine so einfache Funktion können wir natürlich direkt (mündlich) eine Lösung (Gruppe) berechnen, aber die von mt_rand() tatsächlich verwendete Funktion ist recht komplex und kann nicht invertiert werden. Eine effektive Cracking-Methode besteht darin, alle Seeds umfassend aufzuzählen, eine Zufallszahlenfolge basierend auf dem Seed zu generieren und diese dann mit einer bekannten Zufallszahlenfolge zu vergleichen, um zu überprüfen, ob der Seed korrekt ist. php_mt_seed^phpmtseed ist ein solches Tool. Es ist sehr schnell und die Ausführung des 2^32-Bit-Seeds dauert nur wenige Minuten. Es kann mögliche Seeds basierend auf dem Ausgabeergebnis eines einzelnen mt_rand() direkt auflösen (Beispiel oben). Natürlich kann es auch Seeds auflösen, die die MIN-MAX-Ausgabe begrenzen, wie mt_rand(1,100)
(nützlich in den folgenden Beispielen).
Sicherheitsprobleme
Nachdem ich so viel gesagt habe: Warum sind Zufallszahlen unsicher? Tatsächlich ist an der Funktion selbst nichts auszusetzen, und der Beamte gibt auch klar an, dass die generierten Zufallszahlen nicht für Sicherheitsverschlüsselungszwecke verwendet werden sollten (obwohl dies im Handbuch der chinesischen Version nicht steht). Das Problem besteht darin, dass der Entwickler nicht erkennt, dass es sich hierbei nicht um eine echte Zufallszahl handelt. Wir wissen bereits, dass Samen aus einer bekannten Folge von Zufallszahlen explodiert werden können. Mit anderen Worten: Solange es auf einer Seite eine Ausgabe-Zufallszahl oder deren Ableitungswert (umkehrbaren Zufallswert) gibt, ist die Zufallszahl auf einer anderen Seite keine „Zufallszahl“ mehr. Zu den gängigen Beispielen für die Ausgabe von Zufallszahlen gehören Verifizierungscodes, zufällige Dateinamen usw. Zur Sicherheitsüberprüfung werden gängige Zufallszahlen verwendet, beispielsweise zum Abrufen von Kennwortüberprüfungswerten wie Verschlüsselungsschlüsseln usw. Ein ideales Angriffsszenario:
Wenn Sie mitten in der Nacht darauf warten, dass Apache (Nginx) alle PHP-Prozesse zurücknimmt (um sicherzustellen, dass der nächste Besuch erneut gestartet wird), besuchen Sie einmal die Bestätigungscodeseite. Kehren Sie die Zufallszahl basierend auf den Zeichen des Bestätigungscodes um und explodieren Sie dann Zufallszahlen-Seeds basierend auf Zufallszahlen. Besuchen Sie dann die Seite zum Passwortabruf. Der generierte Link zum Passwortabruf basiert auf Zufallszahlen. Wir können diesen Link einfach berechnen und das Administratorkennwort abrufen...XXOO
Instanz
PHPCMS MT_RAND SEED Crack führt zu Authkey Leck. Yu Niu schreibt besser als ich, lesen Sie einfach sein
Discuz x3.2 Authkey Leak ist tatsächlich ähnlich. Der offizielle Patch wurde veröffentlicht und Interessierte können ihn selbst analysieren.
Das obige ist der detaillierte Inhalt vonVertiefendes Verständnis der Sicherheit von mt_rand()-Zufallszahlen in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!