203 lines
4.5 KiB
Python
203 lines
4.5 KiB
Python
# /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()
|