How random is random?
Out of curiosity if the random number functions rand() and mt_rand() in PHP were really random enough I set my quadcore to work and generated 1 billion random numbers between 1 and 10 (inclusive) for each function. I could've made a small random generation script that would simply count occurances, but I thought it would be fun to use MySQL to store the values. A 45 GB database was the result.
MD5 Brute Force with PHP
Dictionary MD5 hacking was fun, but now let's do some brute force! I used part of some code I found and entered some testdata just to prove the concept.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <? set_time_limit(0); function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); } $time_start = getmicrotime(); // algorithm of hash // see http://php.net/hash_algos for available algorithms define('HASH_ALGO', 'md5'); // max length of password to try define('PASSWORD_MAX_LENGTH', 8); $charset = 'abcdefghijklmnopqrstuvwxyz'; #$charset .= '0123456789'; #$charset .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; #$charset .= '~`!@#$%^&*()-_\/\'";:,.+=<>? '; $str_length = strlen($charset); // If no arguments given present usage info if ($_SERVER["argc"] < 1) { print "Usage: attack.php <hash>\n"; exit; } // Get MD5 checksum from command line $hash_password = $_SERVER["argv"][1]; function check($password) { global $hash_password, $time_start; if (hash(HASH_ALGO, $password) == $hash_password) { echo "\n\n" . "FOUND MATCH, password: " . $password . "\n\n"; $time_end = getmicrotime(); $time = $time_end - $time_start; echo "Found in " . $time . " seconds\n"; exit; } } function recurse($width, $position, $base_string) { global $charset, $str_length; for ($i = 0; $i < $str_length; ++$i) { if ($position < $width - 1) { recurse($width, $position + 1, $base_string . $charset[$i]); } check($base_string . $charset[$i]); } } echo "Target hash: " . $hash_password . "\n"; for ($i = 1; $i < PASSWORD_MAX_LENGTH + 1; ++$i) { echo "\n" . "Checking passwords with length:" .$i; $time_check = getmicrotime(); $time = $time_check - $time_start; echo "\n" . "Runtime: " . $time . " seconds"; recurse($i, 0, ''); } echo "Execution complete, no password found\r\n"; ?> |
Target hash: e80b5017098950fc58aad83c8c14978e
Checking passwords with length:1
Runtime: 0.000102043151855 seconds
Checking passwords with length:2
Runtime: 0.000209093093872 seconds
Checking passwords with length:3
Runtime: 0.00194907188416 seconds
Checking passwords with length:4
Runtime: 0.0476939678192 seconds
Checking passwords with length:5
Runtime: 1.09398603439 seconds
Checking passwords with length:6
Runtime: 28.3298618793 seconds
FOUND MATCH, password: abcdef
Found in 29.4669120312 seconds
With the complete charset enabled:
Target hash: e80b5017098950fc58aad83c8c14978e
Checking passwords with length:1
Runtime: 0.00101113319397 seconds
Checking passwords with length:2
Runtime: 0.00128507614136 seconds
Checking passwords with length:3
Runtime: 0.0210931301117 seconds
Checking passwords with length:4
Runtime: 1.49697518349 seconds
Checking passwords with length:5
Runtime: 149.323027134 seconds
Checking passwords with length:6
Runtime: 26291.0229962 seconds
FOUND MATCH, password: abcdef
Found in 26451.9779811 seconds
I'm currently running some 8 character brute forces, but they are taking forever, so I'll post the results later.
MD5 Hacking with PHP
Although I have been working with php and thus md5 hashed passwords for loads of years I have never actually tried to break the md5 hash to see how easy (or not) it is to break it until I stumbled on a site with some examples.
I wanted to give the dictionary example a shot and modified the dictattack script so that it would keep time and show me some form of progress. (I hate software or scripts not showing me that they are actually still busy with at least something.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <? function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); } $time_start = getmicrotime(); // If no arguments given present usage info if ($_SERVER["argc"] < 2) { print "Usage: dictattack.php <MD5 checksum> [ <Dictionary file> ]\n"; exit; } // Get MD5 checksum from command line $md5sum = $_SERVER["argv"][1]; // Open word list - either the one from the command line // or use the default list if (isset($_SERVER["argv"][2]) && is_file($_SERVER["argv"][2])) { $words = file($_SERVER["argv"][2]); } else { $words = file("/usr/share/dict/words"); } // Loop through all words foreach ($words as $word) { $word = rtrim($word); if (md5($word) == $md5sum) { print "Match found! $word = $md5sum\n"; $time_end = getmicrotime(); $time = $time_end - $time_start; print "Found in " . $time . " seconds\n"; exit; } } print "No matches found!\n"; ?> |
Match found! zwirrel = e5b4466aa52137f90cba03ad88381dee
Found in 0.287662982941 seconds
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <? set_time_limit(0); function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); } $time_start = getmicrotime(); // Charset to append characters from $charset = "abcdefghijkmnopqrstuvwxyzABCDEFGHJIKLMNPQRSTUVWXYZ0123456789"; // If no arguments given present usage info if ($_SERVER["argc"] < 2) { print "Usage: dictattack.php <MD5 checksum> [ <Dictionary file> ]\n"; exit; } // Get MD5 checksum from command line $md5sum = $_SERVER["argv"][1]; // Open word list - either the one from the command line // or use the default list if (isset($_SERVER["argv"][2]) && is_file($_SERVER["argv"][2])) { $words = file($_SERVER["argv"][2]); } else { $words = file("/usr/share/dict/words"); } // Loop through all words foreach ($words as $word) { $word = rtrim($word); if (md5($word) == $md5sum) { print "Match found in dictionary! $word = $md5sum\n"; $time_end = getmicrotime(); $time = $time_end - $time_start; print "Found in " . $time . " seconds\n"; exit; } } // Loop through all the words again, but append 2 characters foreach ($words as $word) { $word = rtrim($word); for ($i=0; $i<strlen($charset); $i++) { for ($j=0; $j<strlen($charset); $j++) { $word2 = $word.$charset[$i].$charset[$j]; if (md5($word2) == $md5sum) { print "Match found! $word2 = $md5sum\n"; $time_end = getmicrotime(); $time = $time_end - $time_start; print "Found in " . $time . " seconds\n"; exit; } } } } print "No matches found!\n"; ?> |
Match found! zwirrel16 = d2dc8ee8c936b543a04e96618587c4a7
Found in 913.657567024 seconds
With the charset only using 0-9
Match found! zwirrel16 = d2dc8ee8c936b543a04e96618587c4a7
Found in 24.3986721039 seconds
More later!