attacco di forza bruta ad una password in php, con qualsiasi hash


Oggi vediamo uno script per scoprire la parola originaria da qualsiasi hash, codificata con qualsiasi algoritmo. Grazie ad un brute force attack alla password, appunto per questo per motivi di efficienza è meglio usare il php da terminale.

Nota: il seguente articolo ha il solo scopo di illustrare un semplice algoritmo di forza bruta, non deve essere usato per fini diversi da quelli didattici

Vediamo subito il codice:

<?php
function confronta($lettere, $pass, $n, $hash = "md5"){
	$pass = strtolower($pass);
	$mod = count($lettere);
	$nn = pow($mod,$n);
	$vet = array();
	for($i=0;$i<$nn;$i++){
		for($j=0;$j<$n;$j++)
			$vet[$j] = $lettere[(int)(($i%pow($mod,$n-$j))/pow($mod,$n-$j-1))];
		if($hash(implode("",$vet))==$pass)
			return $vet;
	}
	return false;
}

//variabili
//$lettere = array(" ","!","\"","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~");
$lettere = array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
$pass = md5("cia");
$hash = "md5";
$flag  = false;

//tempo
$time_i = explode(" ",microtime());
$time_i = $time_i[0]+$time_i[1];

//calcolo
print "attendere...\n";
for($i=1;!$flag;$i++)
	if(($vet=confronta($lettere,$pass,$i,$hash))!==false)
		$flag = true;

//tempo
$time_f = explode(" ",microtime());
$time_f = $time_f[0]+$time_f[1];

if($flag)
	print "parola trovata : \"".implode("",$vet)."\" in : ".($time_f-$time_i)." secondi\n";
?>

spieghiamo veloce i parametri da configurare:

  • Il vettore lettere contiene le lettere con cui deve essere create le combinazioni possibili. Ho messo due varianti, una che contiene tutti i caratteri ASCII standard possibili ed una che contiene solo lettere e numeri.
  • La variabille pass contiene la password da trovare. In questo caso faccio l’md5 di “cia”.
  • La variabille hash contiene la funzione dell’algoritmo usato. In questo caso quindi md5.

Il suo funzionamento è abbastanza semplice, la funzione confronta prova tutte le combinazioni di n caratteri, con una determinata hash, fin quando non trova la password. Quindi basta provare prima con un carattere, poi con due e così via, fin quando non si trova la password.

A puro scopo informativo rilascio le funzioni per le hash NTLM , LM e old_password di mysql, altre funzioni come md4, sha1, ecc sono già incluse nella libreria standard del php:

NTLM:

<?php
function NTLMHash($Input) {
  // Convert the password from UTF8 to UTF16 (little endian)
  $Input=iconv('UTF-8','UTF-16LE',$Input);

  // Encrypt it with the MD4 hash
  //$MD4Hash=bin2hex(mhash(MHASH_MD4,$Input));

  // You could use this instead, but mhash works on PHP 4 and 5 or above
  // The hash function only works on 5 or above
  $MD4Hash=hash('md4',$Input);

  // Make it uppercase, not necessary, but it's common to do so with NTLM hashes
 // $NTLMHash=strtoupper($MD4Hash);
 $NTLMHash = $MD4Hash;

  // Return the result
  return($NTLMHash);
}
?>

LM (attenzione non funziona con il php da terminale):

<?php
function LMhash($string)
{
    $string = strtoupper(substr($string,0,14));

    $p1 = LMhash_DESencrypt(substr($string, 0, 7));
    $p2 = LMhash_DESencrypt(substr($string, 7, 7));

    return strtoupper($p1.$p2);
}

function LMhash_DESencrypt($string)
{
    $key = array();
    $tmp = array();
    $len = strlen($string);

    for ($i=0; $i<7; ++$i)
        $tmp[] = $i < $len ? ord($string[$i]) : 0;

    $key[] = $tmp[0] & 254;
    $key[] = ($tmp[0] << 7) | ($tmp[1] >> 1);
    $key[] = ($tmp[1] << 6) | ($tmp[2] >> 2);
    $key[] = ($tmp[2] << 5) | ($tmp[3] >> 3);
    $key[] = ($tmp[3] << 4) | ($tmp[4] >> 4);
    $key[] = ($tmp[4] << 3) | ($tmp[5] >> 5);
    $key[] = ($tmp[5] << 2) | ($tmp[6] >> 6);
    $key[] = $tmp[6] << 1;
   
    $is = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($is, MCRYPT_RAND);
    $key0 = "";
   
    foreach ($key as $k)
        $key0 .= chr($k);
    $crypt = mcrypt_encrypt(MCRYPT_DES, $key0, "KGS!@#$%", MCRYPT_MODE_ECB, $iv);

    return bin2hex($crypt);
}
?>

old_password:

<?php
function old_password($password) {
  if ($password == '')
    return '';
  $nr = 1345345333;
  $add = 7;
  $nr2 = 0x12345671;
  foreach(str_split($password) as $c) {
    if ($c == ' ' or $c == "\t")
      continue;
    $tmp = ord($c);
    $nr ^= ((($nr & 63) + $add) * $tmp) + ($nr << 8);
    $nr2 += ($nr2 << 8) ^ $nr;
    $add += $tmp;
  }

  if ($nr2 > PHP_INT_MAX)
    $nr2 += PHP_INT_MAX + 1;

  return sprintf("%x%x", $nr, $nr2);
}
?>

CC BY-SA 4.0 attacco di forza bruta ad una password in php, con qualsiasi hash by cardinale claudio is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Lascia un commento