[Source]Bruteforcer MD5

Iniciado por Debci, 29 Agosto 2010, 13:05 PM

0 Miembros y 2 Visitantes están viendo este tema.

Debci

Si! LO he conseguido, he hecho que el algoritmo sea dinámico y ampliable, he empezado a trabajar de nuevo en el para un projecto que requiere una comunicación de red, para realizar checksums, y modificar otros por fuerza bruta.

Tal como esta el codigo puesto (podeis modificar 2 parametros para ampliarlo), puede descifrar cualquier cadena de texto de 3 caracteres que contenga A,B,C por lo que yo he usado como ejemplo el siguiente hash:
md5("ACB") = 79661ff25e39af70fc48d7785f587e85;

Vamos a cualquier pagina de cifrado MD5 y le metemos el siguiente texto para cifrar:
ACB y obtenemos que la hash es: 79661ff25e39af70fc48d7785f587e85

Si no sabemos como devolverla al estado original ahora viene cuando actua mi programa:
Código (java) [Seleccionar]

import java.lang.String;
import java.math.BigInteger;
import java.security.MessageDigest;root
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Debci
*/
public class Encriptor {


    public static void main(String[] args)
    {
        String resultado = null;
        String match = "79661ff25e39af70fc48d7785f587e85";


        char[] mapaChars = {'A','B','C','D'};
        int longitud = 3;
        int posibles = (int) Math.pow(longitud,mapaChars.length);

        char[] combinacion = new char[longitud];
       
        int[] indice = new int[longitud];
        for(int i = 0; i < posibles;i++)
        {
          for(int x = 0; x < indice.length; x++) {
           if(!(x==indice.length)) {
                  if(indice[x] == mapaChars.length) {
                    indice[x] = 0;
                    indice[x+1]++;
                  }
                }else{
                  indice[x] = 0;
                }
          }

          for(int h = 0; h < longitud; h++) {
              combinacion[h] = mapaChars[indice[h]];
          }

          char[] resultadoTemporal = new char[longitud];
          for(int j = 0; j < combinacion.length; j++) {
              resultadoTemporal[j] = combinacion[j];
          }
          //System.out.println(resultadoTemporal);
          String resultadoFinal = new String(resultadoTemporal);
          String resultadoEncriptado = new String(Encriptor.encriptaMD5(resultadoFinal));
          if(resultadoEncriptado.equals(match))
          {
              resultado = resultadoTemporal.toString();
              System.out.println("Hash crackeada con exito!\n" + resultadoFinal);
              break;
          }

Encriptad cualquier cadena con los caracteres:
Código (java) [Seleccionar]
char[] mapaChars = {'A','B','C','D'};
Añadid los que querais, para crackear cualquier hash, el algoritmo esta diseñado para adaptarse a un nuevo dicionario y a la longitud de la hash variable:
Código (java) [Seleccionar]
int longitud = 3;
Osea que es extensible, pero si aumentamos mucho puede no funcionar por limitaciones de datos tipo int, las posibilidades serian grandiosas y un int no puede con un dato asi de grande, por lo que ya trabajo en un método para no depender de la VM de java y almacenar dicho numero de combinaciones posibles en memoria directamente.
Cabe mencionar que para entender el codigo quizás haya que tener un nivel medio-basico de combinatoria y matematicas estadisticas (sobre todo con probabilidad).

Disfruten el codigo!

Leyer estate tranquilo que esta quedando de coña!

Saludos

Leyer

#1
1. Se te olvido colocar el método estático encriptaMD5(String text);
2. Faltan algunas llaves para finalizar las secuencia
3. En algunos for y condicionales no es necesario {}
4. Podrías mejorarlo para que permita la entrada por argumentos

PD: Dices que no me preocupe ¬¬ si ni te comunicas con migo, necesito saber que llevas y tu saber que llevo hehe

Un saludo.

Debci

Versión mejorada:

Código (java) [Seleccionar]
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package funcional;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author debci
*/
public class Generador {
    private char[] mapaChars;
    private boolean acabado = false;
private Generador(int ArgCount, char[] ArgAlpha) {
    mapaChars = ArgAlpha;
}
public static void main(String[] args) {
    Generador generador = new Generador();
    generador.getAllCombo();
}

private Generador() {

}
public void getAllCombo() {
        String resultado = null;
        String match = "79661ff25e39af70fc48d7785f587e89";


        char[] mapaChars = {'A','B','C','D','E','F','\0'};
        int longitud = 7;
        BigInteger largo = BigInteger.valueOf(mapaChars.length);
       

        BigInteger posibles = largo.pow(longitud);
        System.out.println("[!]Hay " + posibles + " combinaciones posibles.");

        char[] combinacion = new char[longitud];

        int[] indice = new int[longitud];
        while(!acabado)
        {
          try{
          for(int x = 0; x < indice.length; x++) {
           if(!(x==(indice.length))) {
                  if((indice[x] == (mapaChars.length))) {
                    indice[x] = 0;
                    indice[x+1]++;
                  }
                }else{
                  indice[x] = 0;
                }
          }

          for(int h = 0; h < longitud; h++) {
              combinacion[h] = mapaChars[indice[h]];
          }

          char[] resultadoTemporal = new char[longitud];
          for(int j = 0; j < combinacion.length; j++) {
              resultadoTemporal[j] = combinacion[j];
          }

          String resultadoFinal = new String(resultadoTemporal);
          String resultadoEncriptado = new String(this.encriptaMD5(resultadoFinal));
          System.out.println(resultadoFinal + " =======> " + resultadoEncriptado);

          if(resultadoEncriptado.equals(match))
          {
              resultado = resultadoTemporal.toString();
              System.out.println("Hash crackeada con exito!\n" + resultadoFinal);
              break;
          }

          indice[0]++;
          //System.out.println("[!]Quedan " + posibles + " combinaciones.");
         
          if(posibles.equals(BigInteger.ONE)) {
              acabado = true;
          }
           
            posibles = posibles.subtract(BigInteger.ONE);

        }catch(ArrayIndexOutOfBoundsException e){

        }
    }
    }
public static String encriptaMD5(String toEnc)
    {


        MessageDigest mdEnc = null;
        try {
            mdEnc = MessageDigest.getInstance("MD5"); // Encryption algorithm
        } catch (NoSuchAlgorithmException ex) {
            System.err.println("No se ha encontrado el algoritmo.");
        }

            mdEnc.update(toEnc.getBytes(), 0, toEnc.length());

            String md5 = new BigInteger(1, mdEnc.digest()).toString(16);
            return md5;
    }
}


Ahora ya no tiene limite, puedes añadir cuanta longitud te plazca y todos los caracteres al aphabeto que quieras.


Saludos

Blitzkrieg'




egyware

Asi de ser pesado, solo para molestar pero también dejando una propuesta para mejorar el conocimiento.

Me gustaria saber mucho de que complejidad son los algoritmos  presentados aqui en función del largo de la cadena que se desea obtener por ejemplo.
Esto es util ya que si quiero desencryptar un MD5 cuanto tiempo me tomara a priori sin a ejecutar tal algoritmo.

Espero que me respondan.

Saludos  ;D ;D ;D

Novlucker

Recuerden que yo no se nada de JAVA, pero recién en ese segundo code has dejado bien lo de las posibilidades.

En el primer code tienes ....
Código (java) [Seleccionar]
int posibles = (int) Math.pow(longitud,mapaChars.length);
Lo cual es igual a decir 3^4, y no es eso, sino que es 4^3, por eso anteriormente había dicho que no estaba bien :P
AAA
AAB
AAC
AAD
ABA
ABB
ABC
ABD
ACA
ACB
ACC
ACD
ADA
ADB
ADC
ADD
BAA
BAB
BAC
BAD
BBA
BBB
BBC
BBD
BCA
BCB
BCC
BCD
BDA
BDB
BDC
BDD
CAA
CAB
CAC
CAD
CBA
CBB
CBC
CBD
CCA
CCB
CCC
CCD
CDA
CDB
CDC
CDD
DAA
DAB
DAC
DAD
DBA
DBB
DBC
DBD
DCA
DCB
DCC
DCD
DDA
DDB
DDC
DDD

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

jdc

Para no hacerlo cada vez no sería mejor guardar todo en una base de datos?

Por ejemplo "palabra" y "md5" asi luego  sólo se compara el md5 ingresado y se muestra la palabra a la que corresponda. En este caso la fuerza bruta no es muy óptima.

Por lo demás sería bueno que se consideren números y letras xD sin contar mayúsculas y minúsculas que enmonstruesen mas aún esto...

La base de datos sería inmensa pero sería trabajo de sólo una vez, lo mismo que la espera.

Debci

#7
Claro que si, pero primero debo conseguir un hd de por lo menos 1 Tb (como minimo) y luego hacerlo para que saque todas las hashes desde un solo digito(longitud de la cadena 1) hasta por ejemplo 15 digitos.

Cita de: egyware en 30 Agosto 2010, 05:36 AM
Asi de ser pesado, solo para molestar pero también dejando una propuesta para mejorar el conocimiento.

Me gustaria saber mucho de que complejidad son los algoritmos  presentados aqui en función del largo de la cadena que se desea obtener por ejemplo.
Esto es util ya que si quiero desencryptar un MD5 cuanto tiempo me tomara a priori sin a ejecutar tal algoritmo.

Espero que me respondan.

Saludos  ;D ;D ;D
Pues dependeria mucho de tu ordenador, y del algoritmo en si, además este es inutil si no conoces la longitud de la cadena pasada a hash.
EDITO:
Añadida mejora multifuncional:
Ahora si selecionamos una cadena de 16 caracteres, comprobara los de 1, 2 ,3 ,4 ,5... no solamente generara cadenas de 16, por loq ue ahora crackea todo tipo de hashes con un límitem establecido.

Código (java) [Seleccionar]
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package funcional;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author debci
*/
public class Generador {
    private char[] mapaChars;
    private boolean acabado = false;
private Generador(int ArgCount, char[] ArgAlpha) {
    mapaChars = ArgAlpha;
}
public static void main(String[] args) {
    Generador generador = new Generador();
    generador.getAllCombo();
}

private Generador() {

}
public void getAllCombo() {
        String resultado = null;
        String match = "79661ff25e39af70fc48d7785f587e89";


        char[] mapaChars = {'A','B','C','D','E','F',' '};
        int longitud = 7;
        BigInteger largo = BigInteger.valueOf(mapaChars.length);
       

        BigInteger posibles = largo.pow(longitud);
        System.out.println("[!]Hay " + posibles + " combinaciones posibles.");

        char[] combinacion = new char[longitud];

        int[] indice = new int[longitud];
        while(!acabado)
        {
          try{
          for(int x = 0; x < indice.length; x++) {
           if(!(x==(indice.length))) {
                  if((indice[x] == (mapaChars.length))) {
                    indice[x] = 0;
                    indice[x+1]++;
                  }
                }else{
                  indice[x] = 0;
                }
          }
          //Asignamos la combinación numérica al vector de caracteres
          for(int h = 0; h < longitud; h++) {
              combinacion[h] = mapaChars[indice[h]];
          }

          char[] resultadoTemporal = new char[longitud];
          for(int j = 0; j < combinacion.length; j++) {
              resultadoTemporal[j] = combinacion[j];
          }

          String resultadoFinal = new String(resultadoTemporal);
          String cadenaFormateada = new String();
          /* Formateamos la cadena quitandole los espacios existentes para */
          /* generar todas las formas posibles                             */
          for (int x = 0; x < resultadoFinal.length(); x++) {
               if (resultadoFinal.charAt(x) != ' ') {
                 cadenaFormateada += resultadoFinal.charAt(x);
              }
          }
          String resultadoEncriptado = new String(this.encriptaMD5(cadenaFormateada));
          System.out.println(cadenaFormateada + " =======> " + resultadoEncriptado);

          if(resultadoEncriptado.equals(match))
          {
              resultado = resultadoTemporal.toString();
              System.out.println("Hash crackeada con exito!\n" + resultadoFinal);
              break;
          }

          indice[0]++;
          //System.out.println("[!]Quedan " + posibles + " combinaciones.");
         
          if(posibles.equals(BigInteger.ONE)) {
              acabado = true;
          }
           
            posibles = posibles.subtract(BigInteger.ONE);

        }catch(ArrayIndexOutOfBoundsException e){

        }
    }
    }
public static String encriptaMD5(String toEnc)
    {


        MessageDigest mdEnc = null;
        try {
            mdEnc = MessageDigest.getInstance("MD5"); // Encryption algorithm
        } catch (NoSuchAlgorithmException ex) {
            System.err.println("No se ha encontrado el algoritmo.");
        }

            mdEnc.update(toEnc.getBytes(), 0, toEnc.length());

            String md5 = new BigInteger(1, mdEnc.digest()).toString(16);
            return md5;
    }
}

Ahora ya crackea con un limite, osea si le dices 16 caracteres de limite, prueba con todas las longitudes anteriores, usando el ingenio lo que he hecho ha sido añadir el caracter ' ' al dicionario y luego parsear las cadenas para que lo elimine creando asi todo tipo de cadenas.

Saludos
Saludos