diff --git a/python-ofensivo/14_escaner_red_ICMP/network_scaner.py b/python-ofensivo/14_escaner_red_ICMP/network_scaner.py new file mode 100644 index 0000000..4b00523 --- /dev/null +++ b/python-ofensivo/14_escaner_red_ICMP/network_scaner.py @@ -0,0 +1,202 @@ +# /usr/bin/env python3 +""" +Escaner de red ICMP +""" + +import argparse +import ipaddress +import re +import signal +import subprocess +from concurrent.futures import ThreadPoolExecutor +from termcolor import colored + + +def def_handler(sig, frame): + + print(colored( + "\n\n[!] Saliendo del programa...\n", "blue") + ) + exit(1) + + +signal.signal(signal.SIGINT, def_handler) + + +def get_arguments(): + """ + Obtiene los argumentos de la linea de comandos + """ + + parser = argparse.ArgumentParser(description="Escaner de red ICMP") + parser.add_argument( + "-t", "--target", + required=True, dest="target", + help="Host o rango de red a escanear" + ) + args = parser.parse_args() + + return args.target + + +def validar_ip(target_str): + """ + Valida si el target es una IP o un rango de IPs + """ + + # Verificar si es un rango de IPs + rango_match = re.match( + r'^(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})-(\d{1,3})$', target_str) + + if rango_match: + ip_inicio = rango_match.group(1) + + ip_fin = int(rango_match.group(2)) + + try: + # Convertir la IP de inicio a un objeto ipaddress + ipaddress.IPv4Address(ip_inicio) + + # Verificar que el rango sea válido + if 0 <= ip_fin <= 255: + + # Crear un objeto ipaddress para la IP de inicio + inicio = ipaddress.IPv4Address(ip_inicio) + + # Crear un objeto ipaddress para la IP de fin + fin = ipaddress.IPv4Address( + ip_inicio.rsplit('.', 1)[0] + '.' + str(ip_fin) + ) + + # Verificar que la IP de inicio sea menor que la IP de fin + if inicio < fin: + + print(colored( + f"\n[+] Escaneando el rango de IPs: {inicio} - {fin}", + "blue") + ) + rango_ips = ipaddress.summarize_address_range(inicio, fin) + return rango_ips + + else: + + print(colored( + "\n[!] Error: El rango debe ser de menor a mayor", + "red") + ) + return False + + else: + + print(colored( + "\n[!] Error: El rango especificado no es válido", + "red") + ) + return False + + except ipaddress.AddressValueError: + + print(colored( + "\n[!] Error: El rango especificado no son IPs válidas", + "red") + ) + return False + + else: + + # Si no es un rango, verificar si es una IP individual + try: + + ipaddress.IPv4Address(target_str) + print(colored( + f"\n[+] Escaneando IP: {target_str}", "blue") + ) + return target_str + + except ipaddress.AddressValueError: + print(colored( + "\n[!] Error: El target especificado no es una IP válida", + "red") + ) + return False + + +def parse_target(target_str): + """ + Parsea el target y devuelve una lista de IPs + """ + + if "-" in target_str: + + ip_list = target_str.split('-') + + ip_inicio = ip_list[0] + ip_fin = int(ip_list[1]) + + inicio = ipaddress.IPv4Address(ip_inicio) + + fin = ipaddress.IPv4Address( + ip_inicio.rsplit('.', 1)[0] + '.' + str(ip_fin) + ) + + ips_return = [] + + for ip in range(int(ip_inicio.split('.')[3]), ip_fin + 1): + + ip_address = ip_inicio.rsplit('.', 1)[0] + '.' + str(ip) + + ips_return.append(ip_address) + + return ips_return + + else: + + # Si target_str es una IP individual, crear una lista con esa IP + target_list = [target_str] + + return target_list + + +def host_discovwery(target): + + try: + + ping = subprocess.run( + ["ping", "-c", "1", target], + timeout=1, stdout=subprocess.DEVNULL + ) + + if ping.returncode == 0: + + print(colored( + f"[+] {target} está activo", "green") + ) + + except subprocess.TimeoutExpired: + pass + + +def main(): + """ + Funcion principal + """ + + target_str = get_arguments() + + if not validar_ip(target_str): + + print(colored( + "\n[!] Introduce un target válido", "red") + ) + + return + + targets = parse_target(target_str) + + with ThreadPoolExecutor(max_workers=50) as executor: + + executor.map(host_discovwery, targets) + + +if __name__ == "__main__": + main() diff --git a/python-ofensivo/README.md b/python-ofensivo/README.md index 51ec052..bec9c04 100644 --- a/python-ofensivo/README.md +++ b/python-ofensivo/README.md @@ -25,5 +25,6 @@ Quizá encuentres aquí cosas que no están en el vídeo, o viceversa, son apunt | 9. [Bloc de notas](./09_bloc_notas/) | | 10. [Calculadora](./10_calculadora/) | | 11. [Chat cifrado con E2E](./11_chat_cifrado_E2E/) | -| 12 [Escaner de puertos](./12_escaner_puertos/) | -| 13 [Cambiador de MAC](./13_cambiar_mac_address/) | +| 12. [Escaner de puertos](./12_escaner_puertos/) | +| 13. [Cambiador de MAC](./13_cambiar_mac_address/) | +| 14. [Escaner de red ICMP](./14_escaner_red_ICMP/) |