October 14, 2026
Engenharia de Defesa: Mitigando Ameaças de IP Spoofing e ARP Poisoning com Python e Scapy
Nesses últimos dias tenho estudado muito sobre defesa em profundidade e sempre vejo como os cibercriminosos encontram formas de invadir e…

By Denis Honório
6 min read
Nesses últimos dias tenho estudado muito sobre defesa em profundidade e sempre vejo como os cibercriminosos encontram formas de invadir e burlar os sistemas das empresas. Desta vez, vou através deste artigo compartilhar o meu aprendizado sobre IP Spoofing e ARP Poisoning, e mostrar uma solução bem simples que implementei utilizando o Scapy, uma ferramenta poderosa feita em Python.
É por padrão acreditar que as maiores ameaças a qualquer sistema viram exclusivamente da internet, mas ataques silenciosos de personificação de identidade na rede podem comprometer totalmente a confidencialidade dos dados. Mas, assim como eu, você pode estar se perguntando como isso é possível. Tipo, como alguém pode se passar por você dentro da sua rede?!
Para entermos melhor como algo assim e possivel, devemos primeiro quebrar o ataque em duas partes: o roubo do nome logico e o roubo do endereco fisico.
O que e IP Spoofing ? (A identidade falsificada)
Imagine que alguém clonou o seu cartão de crédito e possui todas as informações necessárias para utilizá-lo. Esse fraudador pode simplesmente usar o seu cartão para fazer compras online por conta própria, já que possui todos os dados que o site exige para provar que é você quem está comprando.
O IP Spoofing (Spoofing significa falsificação) funciona da mesma forma. Para que o impostor consiga se passar por você, ele altera o cabeçalho da requisição de rede e insere o endereço IP da sua máquina ou do seu roteador no campo de origem. Como o servidor de destino tem dificuldade para validar se o número escrito no cabeçalho é verdadeiro ou falso, o atacante consegue iniciar conexões e se passar pelo cliente legítimo de forma totalmente independente.
O que é ARP Poisoning? (O Envenenamento de Endereços)
Se o IP Spoofing é a falsificação dos dados do cartão, o ARP Poisoning (Envenenamento ARP) seria a adulteração do endereço para onde será entregue a mercadoria.
O Protocolo de Resolução de Endereços (ARP) existe desde os primórdios das redes de computadores, pois é esse protocolo que apoia a abordagem em camadas usada pelas redes até hoje. Ele simplesmente permite que os dispositivos perguntem qual dispositivo está atribuído a um determinado endereço IP. O IP serve somente como uma identificação lógica, pois, para um roteador entregar os pacotes de dados, ele precisa, na verdade, do endereço físico da sua placa de rede, o chamado endereço MAC.
O ARP traduz o IP do dispositivo para mostrar onde ele está (ex: o IP 192.168.3.33 está mapeado no MAC a0:e7:0b:96:f2:8a). Cada dispositivo possui uma tabela interna que mapeia quem é quem. Porém, como é uma tecnologia do passado, desenvolvida em uma época que não se preocupava tanto com autenticação, esse protocolo foi baseado puramente na confiança. E é exatamente aí que os cibercriminosos agem para explorar essa fraqueza.
Desenvolvendo a Solução: O Script Detector em Python
Para resolver essa ameaça de forma passiva e eficiente, sem a necessidade de alterar configuracoes de seguranca de todos os dispositivos da rede, desenvolvi um script em Python utilizando a biblioteca Scapy, rodando na minha maquina ubuntu.
O script adota uma abordagem Zero Trust local, que fica continuamente validando a integridade das respostas ARP, monitando o trafego lascivo e constroi uma tabela estatica na memoria RAM(Baseline) na inicializacao do servico.
#!/usr/bin/env python3
import argparse
from scapy.all import sniff, ARP, IP
# Dicionario global para mapear a tabela de IP -> MAC observada no tráfego aéreo
# Estrutura: { '192.168.1.10': 'aa:bb:cc:dd:ee:ff' }
ip_mac_table = {}
def process_packet(packet):
"""
Função de callback que o Scapy chama para cada pacote capturado.
"""
# 1. Verifica se o pacote possui a camada ARP (Address Resolution Protocol)
if packet.haslayer(ARP):
arp_layer = packet[ARP]
# Analisa apenas pacotes do tipo "is-at" (respostas ARP ou Gratuitous ARP)
# op = 2 significa ARP Reply
if arp_layer.op == 2:
src_ip = arp_layer.psrc
src_mac = arp_layer.hwsrc
# Se o IP já foi visto antes na rede, precisamos validar o MAC
if src_ip in ip_mac_table:
old_mac = ip_mac_table[src_ip]
# Se o MAC mudou para o mesmo IP, há um forte indício de Spoofing/MitM!
if old_mac != src_mac:
print(f"\n[ ALERTA DE SPOOFING DETECTADO] IP: {src_ip}")
print(f" [-] MAC Legítimo (Registrado): {old_mac}")
print(f" [!] MAC Suspeito (Atual): {src_mac}")
print(f" [-] Classificação: True Positive (Divergência L2/L3)")
else:
# Se é a primeira vez que vemos o IP, nós o registramos na nossa tabela
ip_mac_table[src_ip] = src_mac
print(f"[+] Dispositivo registrado na tabela -> IP: {src_ip} | MAC: {src_mac}")
# 2. Varredura complementar na camada IP convencional
elif packet.haslayer(IP):
ip_layer = packet[IP]
src_ip = ip_layer.src
src_mac = packet.src # Pega o endereco MAC do cabeçalho Ethernet/802.11
if src_ip in ip_mac_table:
if ip_mac_table[src_ip] != src_mac:
print(f"\n[ ALERTA DE INCONSISTÊNCIA IP/MAC] IP: {src_ip}")
print(f" [-] MAC Esperado: {ip_mac_table[src_ip]}")
print(f" [!] MAC Enviando Pacote: {src_mac}")
def main():
# Configura os argumentos de linha de comando para o script
parser = argparse.ArgumentParser(description="Wi-Fi IP Spoofing Detector usando Scapy")
parser.add_argument("-i", " - interface", required=True, help="Interface de rede para realizar o sniffing (ex: wlan0mon ou eth0)")
args = parser.parse_args()
print(f"[*] Inicializando monitoramento de Spoofing na interface: {args.interface}")
print("[*] Aguardando tráfego de pacotes… (Pressione Ctrl+C para sair)\n")
# Inicia o sniffing do Scapy
# store=0 faz com que o Scapy não guarde os pacotes na memória RAM (evitar overhead)
# prn chama a nossa função de callback para cada pacote capturado
sniff(iface=args.interface, store=0, prn=process_packet)
if __name__ == "__main__":
main()#!/usr/bin/env python3
import argparse
from scapy.all import sniff, ARP, IP
# Dicionario global para mapear a tabela de IP -> MAC observada no tráfego aéreo
# Estrutura: { '192.168.1.10': 'aa:bb:cc:dd:ee:ff' }
ip_mac_table = {}
def process_packet(packet):
"""
Função de callback que o Scapy chama para cada pacote capturado.
"""
# 1. Verifica se o pacote possui a camada ARP (Address Resolution Protocol)
if packet.haslayer(ARP):
arp_layer = packet[ARP]
# Analisa apenas pacotes do tipo "is-at" (respostas ARP ou Gratuitous ARP)
# op = 2 significa ARP Reply
if arp_layer.op == 2:
src_ip = arp_layer.psrc
src_mac = arp_layer.hwsrc
# Se o IP já foi visto antes na rede, precisamos validar o MAC
if src_ip in ip_mac_table:
old_mac = ip_mac_table[src_ip]
# Se o MAC mudou para o mesmo IP, há um forte indício de Spoofing/MitM!
if old_mac != src_mac:
print(f"\n[ ALERTA DE SPOOFING DETECTADO] IP: {src_ip}")
print(f" [-] MAC Legítimo (Registrado): {old_mac}")
print(f" [!] MAC Suspeito (Atual): {src_mac}")
print(f" [-] Classificação: True Positive (Divergência L2/L3)")
else:
# Se é a primeira vez que vemos o IP, nós o registramos na nossa tabela
ip_mac_table[src_ip] = src_mac
print(f"[+] Dispositivo registrado na tabela -> IP: {src_ip} | MAC: {src_mac}")
# 2. Varredura complementar na camada IP convencional
elif packet.haslayer(IP):
ip_layer = packet[IP]
src_ip = ip_layer.src
src_mac = packet.src # Pega o endereco MAC do cabeçalho Ethernet/802.11
if src_ip in ip_mac_table:
if ip_mac_table[src_ip] != src_mac:
print(f"\n[ ALERTA DE INCONSISTÊNCIA IP/MAC] IP: {src_ip}")
print(f" [-] MAC Esperado: {ip_mac_table[src_ip]}")
print(f" [!] MAC Enviando Pacote: {src_mac}")
def main():
# Configura os argumentos de linha de comando para o script
parser = argparse.ArgumentParser(description="Wi-Fi IP Spoofing Detector usando Scapy")
parser.add_argument("-i", " - interface", required=True, help="Interface de rede para realizar o sniffing (ex: wlan0mon ou eth0)")
args = parser.parse_args()
print(f"[*] Inicializando monitoramento de Spoofing na interface: {args.interface}")
print("[*] Aguardando tráfego de pacotes… (Pressione Ctrl+C para sair)\n")
# Inicia o sniffing do Scapy
# store=0 faz com que o Scapy não guarde os pacotes na memória RAM (evitar overhead)
# prn chama a nossa função de callback para cada pacote capturado
sniff(iface=args.interface, store=0, prn=process_packet)
if __name__ == "__main__":
main()O Fluxo de Análise do Código:
- Monitoramento Passivo: O script utiliza a função
sniff()do Scapy para capturar todos os pacotes transitando na interface de rede sem foi selecionada (especificada pelo parâmetro-i wlp2s0). O parâmetrostore=0foi configurado para que o Scapy não guarde os pacotes na memória RAM, evitando overhead e travamentos no host. - Mapeamento de Baseline: Ao registrar os primeiros pacotes legítimos do Gateway e do próprio host, a estrutura armazena a relação estável IP MAC em um dicionário global em Python (
ip_mac_table). - Inspeção de Divergência: Sempre que um pacote do tipo
ARP Reply(onde a operação internaopé igual a2, indicando uma resposta ARP) é detectado, a função de callback entra em ação para extrair o IP de -> origem (psrc) e o MAC correspondente (hwsrc). - Tratamento do Alerta: Se o IP extraído já constar na nossa tabela de integridade, mas o endereço MAC atual for diferente do MAC registrado inicialmente, o script interrompe o fluxo normal e dispara um alerta crítico de segurança no console, classificando o evento imediatamente como True Positive devido à divergência de Camada 2 e Camada 3.
Como validamos se o script estava funcionando ou nao?
Após terminar o script, precisávamos saber o identificador da interface da placa de rede que iríamos usar para que o nosso monitor ficasse observando o tráfego, capturasse qualquer anomalia e nos avisasse. Por algum motivo, inicialmente os comandos de diagnóstico não nos mostravam a interface e tivemos que reiniciar o PC.
Após o reboot, o comando ls /sys/class/net/ retornou com sucesso a lista de adaptadores ativos, revelando o identificador wlp2s0 como a interface sem fio vinculada à placa de rede. Com o nome em mãos, validamos o escopo do endereço IP (192.168.3.33) e o endereço físico MAC legítimo do host (a0:e7:0b:96:f2:8a), permitindo inicializar o monitor com precisão através do comando:
Para validar a detecção, simulei um ataque de ARP Poisoning em uma segunda aba do terminal utilizando este comando:
sudo ./venv/bin/python -c "from scapy.all import send, ARP; send(ARP(op=2, psrc='192.168.3.1', hwsrc='00:11:22:33:44:55', pdst='192.168.3.33'))sudo ./venv/bin/python -c "from scapy.all import send, ARP; send(ARP(op=2, psrc='192.168.3.1', hwsrc='00:11:22:33:44:55', pdst='192.168.3.33'))sudo: Necessário para obter privilégios de superusuário (root), exigência do Linux para injetar ou criar pacotes brutos diretamente na camada física/enlace.-c "...": Flag do Python que permite executar um bloco de código diretamente como uma string no terminal, eliminando a necessidade de criar um arquivo.pyseparado para o ataque.from scapy.all import send, ARP; send(...): Importa a função de envio de pacotes e o construtor do protocolo ARP, disparando a estrutura montada logo em seguida.ARP(op=2): Altera a operação interna do protocolo para o valor2, que força o pacote a se comportar como um ARP Reply (Resposta ARP). Isso faz com que o alvo processe a mensagem imediatamente, mesmo sem ter solicitado.psrc='192.168.3.1': Define o IP de origem lógico (Source IP) como o do Gateway/Roteador da rede. É aqui que o IP Spoofing acontece.hwsrc='00:11:22:33:44:55': Insere o endereço MAC falso do suposto atacante (Hardware Source). O objetivo é associar o IP legítimo do roteador a essa máquina inexistente.pdst='192.168.3.33': Define o IP de destino (Destination IP) apontando diretamente para a nossa máquina de testes, garantindo que o pacote seja processado pelo script detector.
Esse comando fez com que o script que estava rodando na outra aba do terminal gerasse os seguintes registros de alerta:
O script comprovou sua eficácia ao classificar o evento como um True Positive. Ele expôs explicitamente na tela o MAC legítimo armazenado na memória RAM em contraste com o MAC suspeito recebido no pacote malicioso, frustrando a tentativa do atacante de passar despercebido.