Braindisorder If you are not free to choose wrongly and irresponsibly, you are not free at all.

23Jan/110

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.

1Nov/089

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.

Filed under: Code 9 Comments
30Oct/080

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!

Filed under: Code No Comments