MD5/SHA1 Bruteforcer

Published on 2007-10-13 13:32:15.

tags = {  "crypto" "bruteforce" "php"   };

bookmarks = {  Digg! , Del.icio.us! , Google! , Slashdot! , Netscape! , Technorati! , Yahoo! , Stumbleupon! };

Description

The code demonstrates how brute force attacks work.
It's written in PHP and it can reach 96000 Keys/sec.
On a test run, without specifying the string length, it cracked the md5 digest of "test" in 00:03:14.

Content

Save each file using the filename specified and put them in the same directory.
Then try "chmod +x brute_force.php" and "./brute_force.php" OR "php brute_force.php".

brute_force.php:
   1  
   2  #!/usr/bin/php
   3  <?php
   4  
   5  /* $Id: brute_force.php 417 2007-08-17 14:35:06Z zapotek $ */
   6  
   7  /**
   8   * @author:  zapotek <zapotek[at]segfault.gr>
   9   * @version: 0.2
  10   * @name:   MD5/SHA1 BruteForcer
  11   * @description:
  12   *      A simple brute forcer for MD5 and SHA1 hashes.
  13   */

  14  
  15  define( 'VERSION', 0.2 );
  16  
  17  require_once( 'function.brute_force.php' );
  18  require_once( 'function.getopt.php' );
  19  
  20  echo "MD5/SHA1 Bruteforcer v" . VERSION . "\n".
  21         "by Zapotek <zapotek [at] segfault.gr>\n" .
  22         "<http://www.segfault.gr>\n\n";
  23  
  24  // get input options
  25  $args   = @getopt( 'h:m:s:', $argv );
  26  
  27  // read the hash
  28  $hash     = $args['h'];
  29  // get the maximum string length
  30  $max_len  = $args['m'];
  31  // get stats preference
  32  $stats    = $args['s'] == 'on' ? 1 : 0 ;
  33  
  34  // check for sufficient input
  35  if( !$hash ){
  36       echo "Usage:\n\t" .
  37              $argv[0] . " -h <hash> -m <max_len> -s <stats>\n\n" .
  38              "\t<hash>         MD5/SHA1 hash\n" .
  39              "\t<max_len>      The maximum length the encrypted string [optional]\n" .
  40              "\t<stats>        Output stats while cracking [on/off]\n\n";
  41      exit;
  42  }
  43  
  44  // decide the hash algorithm based on hash size
  45  switch( strlen( $hash ) ){
  46     
  47      case 32;
  48          $algo   = "MD5";
  49          break;
  50     
  51      case 40;
  52          $algo   = "SHA1";
  53          break;
  54     
  55      default;
  56          echo "Could not determine the encryption algorithm.\n";
  57          echo "Ensure that the Hash is correct and try again.\n";
  58          exit;
  59  }
  60  
  61  echo "\n$algo hash:\t$hash\n" . str_repeat( "-", 65 );
  62  
  63  $start    = strtotime( "now" );
  64  
  65  $len = 0;
  66  
  67  // loop until we crack the hash or reach the user defined limit
  68  while( ++$len && ( $max_len-- || !$max_len ) ){
  69     
  70      echo "\nAttacking with $len byte strings\n" .
  71              str_repeat( "-", 65 ) .
  72              "\nEstimated string pool:\t" . pow( 75, $len ) . " strings\n" .
  73              str_repeat( "-", 65 ) . "\n";
  74     
  75      $str = brute_force( $hash, $algo, $len, $stats );
  76     
  77      if( $str ){
  78          echo "\nDecrypted string:\t$str\n" .
  79                  str_repeat( "-", 65 ) .
  80                  "\nOperation took:\t\t".
  81                  date( "H:i:s", mktime( 0, 0, strtotime( "now" ) - $start ) ) .
  82                  "\n" . str_repeat( "-", 65 ) . "\n";
  83               exit;
  84      }
  85     
  86      echo "\n[ $len byte keyspace exhausted. Moving on... ]\n\n";
  87  }
  88  
  89  // if we exhausted the keyspace something's wrong...
  90  echo "\nKeyspace exhausted.\n".
  91         "If you got here before the end of *TIME* " .
  92         "you provided either an invalid hash or an invalid max string length...\n"
  93  
  94  ?>
  95   
Code statistics
Physical lines Code lines Comment lines Empty lines Size
94 [ 100.00% ] 56 [ 59.57% ] 15 [ 15.96% ] 23 [ 24.47% ] 2531 bytes
[ Download ]



function.brute_force.php:
   1  
   2  <?php
   3  
   4  /*
   5   * $Id: function.brute_force.php 77 2007-07-16 00:27:34Z zapotek $
   6   *
   7   *   brute_forcer <description>
   8   *   Copyright (C) 2007   zapotek
   9   *
  10   *   This program is free software; you can redistribute it and/or modify
  11   *   it under the terms of the GNU General Public License as published by
  12   *   the Free Software Foundation; either version 2 of the License, or
  13   *   (at your option) any later version.
  14   *
  15   *   This program is distributed in the hope that it will be useful,
  16   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18   *   GNU General Public License for more details.
  19   *
  20   *   You should have received a copy of the GNU General Public License along
  21   *   with this program; if not, write to the Free Software Foundation, Inc.,
  22   *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23   */

  24   
  25  /**
  26   * @author           zapotek
  27   * @project name:   brute_forcer
  28   * @description:    function file for the brute_force() function
  29   *
  30   */

  31   
  32  /**
  33   * Function for brute forcing MD5/SHA1 hashes using ASCII strings.
  34   *
  35   * @param   $hash   string  the hash to crack
  36   * @param   $algo   string  the encryption algorithm to use [MD5/SHA1]
  37   * @param   $len    int     the estimated length of the encrypted string
  38   * @param   $stats  bool    set to true if you want stats while cracking
  39   *
  40   * @return  mixed   string if the crack operation succeeded/false if not
  41   *
  42   */

  43  function brute_force( $hash, $algo, $len, $stats = 0 ){
  44     
  45      // calculate the number of max string combos
  46      $keyspace = pow( 75, $len );
  47     
  48      $start = strtotime( "now" );
  49     
  50      // create the initial key
  51      $key = str_repeat( '0', $len );
  52     
  53      // loop until we exhaust the keyspace
  54      for( $x = 0; $x < $keyspace; $x++ ){
  55          // create a random ASCII string
  56          for( $y=0; $y < $len; $y++ ){
  57             
  58              // move on to the next char if haven't run out of them
  59              if( $key[$y] != "z" ){
  60                  $key[$y] = chr( ord( $key[$y] ) + 1 );
  61                  // zero the rest of the string out
  62                  if( $y > 0 ){
  63                      for( $z = 0; $z < $y; $z++ ){
  64                          $key[$z] = "0";
  65                      }
  66                  }
  67             
  68              break;
  69              }
  70             
  71          }
  72  
  73          // digest the random string to get it's hash
  74          $algo = strtolower( $algo  );
  75          $gen_hash = ( $algo == "md5" ) ? md5( $key ) : sha1( $key );
  76     
  77          // if the hashes match we're done...
  78          if( $hash == $gen_hash ){
  79              return $key;
  80          }
  81         
  82          if( !$stats ) continue;
  83         
  84          // return some stats if the option is enabled
  85          if( $x % 24000 == 0 ){
  86              $x2++;
  87              if( $x2 == 4 ){
  88                  $x2    = 0;
  89                  $time  = strtotime( "now" ) - $start;
  90                  $start = strtotime( "now" );
  91                 
  92                  if( $time == 0 ) $time = 1;
  93                      $rate = ( 24000 * 4 ) / $time;
  94                     
  95                      echo "    $x/$keyspace ( $key ) [ $rate Keys/sec ]".
  96                             " [" . round( 100 - ( ( $keyspace - $x ) / $keyspace ) * 100, 3 ) . "%]".
  97                             " [" . gmdate( "H:i:s",
  98                                          round( ( ( $keyspace - $x ) / $rate ),
  99                                                 3 ) ) .
 100                             " left]\n";
 101              }
 102          }
 103      }
 104     
 105      return false;
 106     
 107  }
 108   
 109  ?>
 110   
Code statistics
Physical lines Code lines Comment lines Empty lines Size
109 [ 100.00% ] 46 [ 42.20% ] 43 [ 39.45% ] 20 [ 18.35% ] 3515 bytes
[ Download ]



function.getopt.php:
   1  
   2  <?php
   3  
   4  /*
   5   * $Id: function.getopt.php 74 2007-07-15 03:59:40Z zapotek $
   6   *
   7   *   brute_forcer <description>
   8   *   Copyright (C) 2007   zapotek
   9   *
  10   *   This program is free software; you can redistribute it and/or modify
  11   *   it under the terms of the GNU General Public License as published by
  12   *   the Free Software Foundation; either version 2 of the License, or
  13   *   (at your option) any later version.
  14   *
  15   *   This program is distributed in the hope that it will be useful,
  16   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18   *   GNU General Public License for more details.
  19   *
  20   *   You should have received a copy of the GNU General Public License along
  21   *   with this program; if not, write to the Free Software Foundation, Inc.,
  22   *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23   */

  24   
  25  /**
  26   * @author           zapotek
  27   * @project name:   brute_forcer
  28   * @description:    compatibility file for the getopt() function
  29   *
  30   */

  31   
  32  /**
  33   * Gets options from the command line argument list
  34   *
  35   * @param   $opts   string  semicolon seperated arguement chars to read
  36   * @param   $argv   array   the argument list
  37   *
  38   * @return  array   string  array of option/argument pairs
  39   *
  40   */

  41  if( !function_exists( 'getopt' ) ){
  42      function getopt( $opts, $argv ) {
  43          $opts_array = explode( ':', $opts );
  44         
  45          foreach( $opts_array as $opt ) {
  46              $opt = '-' . $opt;
  47              $key = array_search( $opt, $argv );
  48              $opt = trim( $opt, '-' );
  49             
  50              if ($key && !in_array( $argv[$key+1], $opts_array ) ){
  51                  $result[$opt] = trim( $argv[$key+1] );
  52              } elseif( $key ) {
  53                  $result[$opt] = '';
  54              }
  55          }
  56         
  57          return $result;
  58      }
  59  }
  60  
  61  ?>
  62  
  63   
Code statistics
Physical lines Code lines Comment lines Empty lines Size
62 [ 100.00% ] 20 [ 32.26% ] 32 [ 51.61% ] 10 [ 16.13% ] 1840 bytes
[ Download ]