Brute Force PHP Script

August 22, 2008

Last weekend I came across this site, Hack This Site!. I've been able to breeze through the Basic missions for the most part, and the Javascript missions, seriously? It's pretty interesting and I know there are many other sites out there that I'm looking forward to trying out once I get far enough with this one.

I came across one mission where I had to crack a hashed password. I was feeling ambitious enough to go ahead and write a brute force script to tackle the task. I messed around an entire day trying to figure out the right combination of nested-loops to solve the problem. I came to the realization that probably the only practical way of solving this algorithm was recursion, which I had very limited experience in doing. So I started searching the web and finally came across a brute force python script written by Robert Green. I ported it over to PHP, and in a matter of seconds I was moving on to the next mission.

<?php
/*
 * Thanks to Robert Green for this script he wrote in python
 * http://www.rbgrn.net/blog/2007/09/how-to-write-a-brute-force-password-cracker.html
 * I took what we wrote and ported this to PHP
 * 
 * This script was written for PHP 5, but should work with
 * PHP 4 if the hash() function is replaced with md5() or something else
 */

#########################################################
/*                   Configuration                     */

// this is the hash we are trying to crack
define('HASH', '098f6bcd4621d373cade4e832627b4f6');

// 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', 4);


// available characters to try for password
// uncomment additional charsets for more complex passwords
$charset = 'abcdefghijklmnopqrstuvwxyz';
//$charset .= '0123456789';
//$charset .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
//$charset .= '~`!@#$%^&*()-_\/\'";:,.+=<>? ';
#########################################################
$charset_length = strlen($charset);

function check($password)
{	
	if (hash(HASH_ALGO, $password) == HASH) {
		echo 'FOUND MATCH, password: '.$password."\r\n";
		exit;
	}
}


function recurse($width, $position, $base_string)
{
	global $charset, $charset_length;
	
	for ($i = 0; $i < $charset_length; ++$i) {
		if ($position  < $width - 1) {
			recurse($width, $position + 1, $base_string . $charset[$i]);
		}
		check($base_string . $charset[$i]);
	}
}

echo 'target hash: '.HASH."\r\n";
recurse(PASSWORD_MAX_LENGTH, 0, '');

echo "Execution complete, no password found\r\n";


?>

brute force PHP script output


53 Comments

Optimize ur script:

Exp:

<code>

$strLenght = strlen($charset);

for ($i = 0; $i < $strLenght; ++$i) {

[...]

}

</code>

;)

posted by Covi @ Sep 16, 2008 09:26 PM EDT


How could this script be modified to work on a site where there are two intput boxes name: and number, the number filed is 6 characters but can only be from 000000 to 999999? Any suggestions???

posted by Question @ Sep 26, 2008 07:57 PM EDT


cool

posted by some one @ Apr 30, 2009 05:47 AM EDT


Question ,

its too late to reply

but i think this script will not work good at website because there would be loop at user browser

posted by some one @ Apr 30, 2009 05:54 AM EDT


Certainly running this through the browser would not be a good idea. If you wanted to run this through a browser, you would have to do something more advanced, where this script is "forked" or run by another script which actually runs the page.

You could then refresh the page and continously check if the script was finished yet. Or even better, something like a progress bar displayed to the user and continously updated using AJAX.

posted by Sean @ May 2, 2009 06:09 PM EDT


A single call to:

recurse(PASSWORD_MAX_LENGTH, 0, '');

would be more efficient because as the code exists now you are checking all passwords length 1 PASSWORD_MAX_LENGTH -1 times, all passwords length 2 PASSWORD_MAX_LENGTH -2 times, etc

If you have the script display all the passwords attempted, you can see that recurse(2, 0, ''); will also try all passwords of length 1.

posted by Bryan @ May 13, 2009 05:09 PM EDT


@Bryan: Thanks for the comment, that does indeed seem to be more efficient. I'll update the code!

@Covi: Thanks for pointing that out. I'll update the code!

posted by Sean @ May 18, 2009 02:04 AM EDT


I am not sure how I feel about this script... Maybe I am not seeing the order of execution correctly, but it looks to me that this first checks 'aaaa', proceeding to 'aaab', until it gets to 'aaa?', followed by 'aaa '. After which it tries 'aaa', 'aab' .. 'aa?', 'aa ', until it works it's way back to testing single chars from 'a' to a single whitespace. Then it switches to 'baaa' and continues...

I am sure there is a simpler way to explain this, but it just seems inefficient.

First, passwords are rarely this simplistic. Usually, they must be above a certain number of chars, but below another number. Then special characters usually have a few requirements (the password can neither start nor end with a special char). And finally, a password usually can only have a certain number of special chars, and/or special chars can not be next to each-other.

I know this may seem like a lot of extra processing, but when you consider the literally BILLIONS of passwords this saves you from testing, it is worth it...

posted by Mike @ Nov 30, 2009 09:55 PM EST


Without looking back at the way the code works, you are probably right Mike. This was not made to be robust, but was made to crack a simple MD5 hash over at hackthissite.org

posted by Sean @ Dec 17, 2009 09:20 PM EST


Hi,

I'm trying to convert this into a C++ version, I have it working, however I have come across the problem that mine check many more permutations than necessary. I have copied the logic exactly and rather than receiving output such as:

aaab

aaac

aaad

aaae

aaaf

aaag

aaah

I am getting

aaaa

aaaab

aaaabc

aaaabcd

aaaabcde

aaaabcdef

aaaabcdefg

aaaabcdefgh

etc, please could you try to explain the logic on how it does not go above 4? I tried working it out on paper, but the recursion itself is extremely confusing to write down!

posted by Tim @ Feb 3, 2010 11:56 AM EST


Hello,

I have a PHP script that creates all 4 letter combination with an array.

Check it out

http://lxcblog.com/2010/10/27/create-four-4-letter-domain-name-password-key-combination-php-array-script/

posted by LxC BLOG @ Oct 28, 2010 01:24 PM EDT


Splendid,

How would one set this code up to add to a MySql DB every code it checks. So say aaaa it would add the plane text value and md5 hash to a db, for later reverse lookup. Would this be possible and where would I add the code. Thanks again.

-Drew T

posted by Drew @ Nov 1, 2010 10:41 PM EDT


Nice script, but it is slightly inefficient...

If you set maxlength to 10, it starts out with 10 charachters... People will more often than not use a short password over a long one.

It should go:

a

b

c

...

aa

ab

ac

..

ba

bb

bc

in other words, single charachter first, double second, and so on...

posted by kthxbai2u @ Feb 24, 2011 08:01 PM EST


How to fix this problem?

MD5 Hash password is 6 lenght

Hash: 866f6e8ca66a98b07c940968fc65276a

Fatal error: Maximum execution time of 60 seconds exceeded in /opt/lampp/htdocs/bruteforce_hash_password.php on line 36

posted by NasterHoster @ Apr 26, 2011 09:50 AM EDT


Another thing to do is change to the order of the check to make it faster.

From what I can tell you go mental creating a "todo" style attack on the hash.

if ($position < $width - 1) {

recurse($width, $position + 1, $base_string . $charset[$i]);

}

check($base_string . $charset[$i]);

to

check($base_string . $charset[$i]);

if ($position < $width - 1) {

recurse($width, $position + 1, $base_string . $charset[$i]);

}

Because there is no need to create another recurse if you already found a match.

posted by Paul @ May 7, 2011 09:30 AM EDT


This is what the code looks like in OOP;

<?php

set_time_limit(60);

class hashBruteForce {

private $charset;

private $charset_length;

private $max_len;

private $min_len;

private $preSalt;

private $appSalt;

private $algo;

private $targetHash;

private $errors;

public $debug;

public $answer;

public $processed;

public function __construct($min_len=0,$max_len=5,$preSalt="",$appSalt="",$algo="md5",$charset="",$targetHash="",$debug=false) {

$this->errors = array();

if($min_len>$max_len){ $this->addError('The max length must be larger than or equal to the minimum'); }

if($min_len<0){ $this->addError('The minimum length must be larger than 0'); }

if(!in_array($algo,hash_algos())){$this->addError('This server cannot preform the '.$algo.' algorithm');}

if(strlen($charset)<1){$this->addError('Character set is too short');}

if(strlen($targetHash)<1){$this->addError('Target hash is too short');}

if($this->countErrors()<1){

$this->max_len=$max_len;

$this->min_len=$min_len;

$this->preSalt=$preSalt;

$this->appSalt=$appSalt;

$this->algo=$algo;

$this->targetHash=$targetHash;

$this->min_len=$min_len;

$this->debug=$debug;

$this->charset=$charset;

$this->charset_length=strlen($this->charset);

}

$this->answer=false;

}

public function addError($msg=false){

if($msg==false){

$this->errors[]='Unknown Error';

}else{

$this->errors[]=$msg;

}

}

public function countErrors(){

return count($this->errors);

}

public function getErrors(){

return $this->errors;

}

private function check($password){

if($this->debug){ echo '<br />Checked: '.$password;}

$this->processed++;

if(hash($this->algo, $this->preSalt.$password.$this->appSalt) == $this->targetHash){

return true;

}else{

return false;

}

}

public function start(){

$this->processed=0;

return $this->recurse('',0);

}

private function recurse($base,$position){

for ($i = 0; $i < $this->charset_length; ++$i) {

if($this->answer!=false){return true;}

if($this->check($base . $this->charset[$i])){

$this->answer=$base . $this->charset[$i];

return true;

}

if ($position < $this->max_len - 1) {

$this->recurse($base.$this->charset[$i], $position + 1);

}

}

return false;

}

}

?>

Thought it would be nice for you ;)

posted by Paul @ May 8, 2011 05:48 PM EDT


How to implement brute force in string matching with php ? help me..

posted by fardian @ May 17, 2011 05:46 AM EDT


Holla !

I let you check this code made by myself. May-be it can help someone. I don't have any skill in programmation but this code works.If you have any suggestion it's nice.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>brute-force-php-script</title>

<?php

/*hack.php - beauvaisbruno@gmail.com */

$pass = ($_POST) ? $_POST["pass"] : "pass";

$lenghtMaxToSet = ($_POST) ? $_POST["Lenght"] : "4";

$charset = ($_POST) ? $_POST["charset"] : "eaistnrulodmpcvqgbfjhzxykw";

?>

</head><body style="background:#ddddff;">

<div style="margin: 50px 200px; padding:0; background:#eeeeff; border:solid 1px black;text-align:center;">

<div style="background:#AAAABB;border:solid 1px black;"> File : hack.php - beauvaisbruno@gmail.com</div>

<h1>

<form method="POST" " action="brute-force-php-script.php" >

Lenght of try : <input name="Lenght" type="text" value="<?php echo $lenghtMaxToSet ?>" size="2" maxlength="2" /> <br>

Pass to Find : <input name="pass" type="text" value="<?php echo $pass ?>" size="10" maxlength="10" /></h1>

<h2><em>Paste it : </em>eaistnrulodmpcvqgbfjhzxykw&eacute;&egrave;123456789 </h2>

<h1>Characters to use : <input name="charset" type="text" value="<?php echo $charset ?>" size="50" maxlength="50" /><br>

<input type="submit" value="GO !!!" style="font-size:20px;padding:5px;"></form></h1>

<?php

$passFind = false;

function AddnewLettertoTry($letterAlreadySet, $numberLetterToSet, $IDPreviousLetterSet, $lenghtMaxThisTry){

global $count;

global $pass;

global $charset;

global $passFind;

for ($IDPreviousLetterSet=0; $IDPreviousLetterSet < strlen($charset) && (!$passFind); $IDPreviousLetterSet++) {

$letterAlreadySet[$numberLetterToSet] = $charset [$IDPreviousLetterSet];

if (($numberLetterToSet) < $lenghtMaxThisTry) {

AddnewLettertoTry($letterAlreadySet, $numberLetterToSet+1, $IDPreviousLetterSet, $lenghtMaxThisTry);

}

else {

$count++;

if ($letterAlreadySet == $pass) {

$passFind = true;

echo "<h1 style=\"color:red;\"> try ".$count." succes !!!</h1>";

}

}

}

}

if ($_POST) {

?>

<div style="background:#eedddd; border:solid 1px red; margin:20px;">

<?php

$pass = $_POST["pass"];

$lenghtMaxToSet = $_POST["Lenght"];

$charset = $_POST["charset"];

echo "<h1> Maximu try ~ ".(strlen($charset)+1)." ^ ".($lenghtMaxToSet)." = <b> [ ".(pow (strlen($charset)+1,$lenghtMaxToSet) +strlen($charset))." ]</b> .</h1>" ;

for ($i=1; $i <= ($lenghtMaxToSet) && (!$passFind); $i++)

AddnewLettertoTry(" ", 0, 0,$i);

if ($passFind) {

echo "<h1 style=\"color:red;\"> [".$pass."] has been fund !!!</h1>";

}

}

?></div></div>

</body>

</html>

posted by polz @ Jun 3, 2011 12:32 PM EDT


This site is like a calssorom, except I don't hate it. lol

posted by Jean @ Sep 13, 2011 01:50 AM EDT


Thanky Thanky for all this good ifnormtaion!

posted by Kaedon @ Sep 13, 2011 06:08 AM EDT


olA5Ey <a href="http://exfvvkuzkmvb.com/">exfvvkuzkmvb</a>

posted by gexihl @ Sep 14, 2011 03:22 AM EDT


eraLpR , [url=http://utbhqvbawszq.com/]utbhqvbawszq[/url], [link=http://rodzycvxbjwq.com/]rodzycvxbjwq[/link], http://drulskntriod.com/

posted by kcxlbvk @ Sep 14, 2011 08:12 AM EDT


Many many quality pitons there.

posted by Brendy @ Sep 14, 2011 09:52 PM EDT


Son of a gun, this is so hlepufl!

posted by Lillah @ Sep 14, 2011 10:40 PM EDT


NerABg <a href="http://dzjgdotvltxe.com/">dzjgdotvltxe</a>

posted by okwsuurtwpn @ Sep 16, 2011 05:06 AM EDT


9x1LMS , [url=http://jfmmyxofxtdw.com/]jfmmyxofxtdw[/url], [link=http://nixmwgdwgbhs.com/]nixmwgdwgbhs[/link], http://mcywbyqqceyq.com/

posted by sjcqcn @ Sep 16, 2011 11:35 AM EDT


I am a newbie and just trying things up can anyone please tell me where to find the hash code ,thats mentioned above .it'll be very helpful thanks in advance

posted by newbie @ Oct 23, 2011 06:34 AM EDT


Mighty useful. Make no msiatke, I appreciate it.

posted by Leaidan @ Jan 31, 2012 10:53 AM EST


4 nirbmeioe 2011BoerDespre faza cu programul vieții acestea și viața cealaltă ai destul de multă dreptate. Viața asta este plină de iluzii văz, auz, simț pe cât de reale pe atât de false pot fi. Dar viața cealaltă nu e așa de neagră. Ști tu, paradisul. Dar desigur dacă ne atașăm prea mult de iluzii, neagră va fi. Mulți atei își susțin ideile prin faptul că oamenii au creat paradisul doar pentru că se temeau de moarte. Acuma să fim serioși, decât chinuri veșnice mia bine nimicul morții. În fine putem vorbi despre matrix mult și putem să facem devieri foarte ample, vedem, până la religie. Sper că acest articol va stârni multe discuții. &nbsp;

posted by Siamy @ Jan 31, 2012 01:32 PM EST


That's a genuinely impressive asnwer.

posted by Cheyenne @ Jan 31, 2012 03:48 PM EST


People normllay pay me for this and you are giving it away!

posted by Aggy @ Jan 31, 2012 09:13 PM EST


Never would have thunk I would find this so indispesnbale.

posted by Kaeden @ Feb 1, 2012 12:53 AM EST


Thanks for being on point and on traget!

posted by Valinda @ Feb 1, 2012 02:48 AM EST


Last one to utilize this is a retotn egg!

posted by Jimmy @ Feb 1, 2012 05:54 AM EST


Woah nelly, how about them appels!

posted by Jaylon @ Feb 1, 2012 09:01 AM EST


Articles like these put the consumer in the derivr seat-very important.

posted by Darold @ Feb 1, 2012 10:22 AM EST


7eTZso <a href="http://kgewgmdfgyhq.com/">kgewgmdfgyhq</a>

posted by tjxlcbq @ Feb 1, 2012 11:49 AM EST


I'm so glad that the internet alolws free info like this!

posted by Marel @ Feb 1, 2012 02:07 PM EST


YMMD with that aswner! TX

posted by Ekit @ Feb 1, 2012 05:20 PM EST


Arlitces like this make life so much simpler.

posted by Philly @ Feb 1, 2012 06:47 PM EST


eOYIAz , [url=http://mdyirpwqayfb.com/]mdyirpwqayfb[/url], [link=http://wtyxvrlebchj.com/]wtyxvrlebchj[/link], http://malvfzwjptyt.com/

posted by rnpbmaxoyx @ Feb 2, 2012 06:50 AM EST


NWTjTc <a href="http://ltdhxdaeqjuv.com/">ltdhxdaeqjuv</a>

posted by bsmaqzbo @ Feb 2, 2012 12:31 PM EST


Great post with lots of impotarnt stuff.

posted by Missy @ Feb 2, 2012 10:01 PM EST


Holy shizint, this is so cool thank you.

posted by Stretch @ Feb 2, 2012 10:36 PM EST


I feel satisiefd after reading that one.

posted by Marlie @ Feb 2, 2012 11:21 PM EST


God, I feel like I sohlud be takin notes! Great work

posted by Nash @ Feb 2, 2012 11:41 PM EST


It's imptreaive that more people make this exact point.

posted by Symona @ Feb 2, 2012 11:57 PM EST


A perfect reply! Thanks for tiakng the trouble.

posted by Lotta @ Feb 3, 2012 12:00 AM EST


Full of slaient points. Don't stop believing or writing!

posted by Jacklyn @ Feb 3, 2012 12:53 AM EST


Smack-dab what I was lokoing for-ty!

posted by Kerriann @ Feb 3, 2012 12:59 AM EST


Whoa, thngis just got a whole lot easier.

posted by Frenchie @ Feb 3, 2012 01:29 AM EST


Dude, right on there brohter.

posted by Idalia @ Feb 3, 2012 05:52 AM EST


P8OqZa , [url=http://fidavsjsuuwi.com/]fidavsjsuuwi[/url], [link=http://klofaxkipjmt.com/]klofaxkipjmt[/link], http://vzfmtmypxurw.com/

posted by hfcqea @ Feb 4, 2012 07:54 AM EST


Post Comment

(X)HTML code will not be rendered and will be displayed as is.
Line breaks will automatically be formatted.

CAPTCHA