Saltar al contenido principal
es/blog/obscura/research/network-fingerprinting/

obscura/research/network-fingerprinting

6 min de lectura

Resumen

Señales visibles en la capa TCP/IP y de transporte, antes de cualquier ejecución HTTP o JS.


1. Fingerprint de Pila TCP/IP (JA4T / Satori / p0f)

Mecanismo

El fingerprinting pasivo de SO lee el paquete TCP SYN para identificar el sistema operativo. Cada pila TCP/IP de SO tiene una combinación única de:

  • TTL inicial: 64 (Linux/macOS), 128 (Windows), 255 (Algunos UNIX)
  • Tamaño de ventana: 64240 (Chrome/Linux), 65535 (macOS), 8192 (sistemas antiguos)
  • MSS (Maximum Segment Size): Derivado del MTU
  • Opciones TCP: Orden y selección de MSS, SACK_PERM, TIMESTAMP, NOP, WINDOW_SCALE
  • Flags IP: Comportamiento del bit DF (Don't Fragment)

Formatos

JA4T: 64240_2-4-8-1-3_1452_10

Componente Significado Ejemplo
64240 Tamaño de ventana TCP Windows por defecto
2-4-8-1-3 Orden de opciones TCP (MSS, SACK, TIMESTAMP, NOP, WINDOW) Orden Chrome/Linux
1452 MSS Derivado del MTU
10 Shift count de Window Scale 2^10 = multiplicador 1024

Fingerprint Satori: 64240:64:1:60:M1452,S,T,N,W10:.

Detección de SO

SO Window TTL MSS Opciones
Linux 29200-65535 64 1460 M,S,T,N,W(7-8)
Windows 10/11 64240 128 1460 M,S,T,N,W(10)
macOS 65535 64 1460 M,S,T,N,W(6-7)
Android 29200-65535 64 1460 M,S,T,N,W(7-8)

Impacto en Obscura

Cliente  Contenedor Obscura (terminación TCP)  Internet
                                      
     Pila TCP del cliente          Pila TCP del contenedor
     (visible para Obscura)        (visible para el destino)

El servidor destino ve la pila TCP de Obscura, no la del cliente. Esto es inevitable porque el contenedor termina la conexión TCP del cliente.

Mitigación: Ninguna a nivel TCP. Sin embargo, la mayoría de los servicios de fingerprinting se centran en fingerprints a nivel de aplicación (TLS, HTTP) en lugar de a nivel TCP. El fingerprint TCP solo rara vez identifica a un usuario.


2. Fingerprint TLS (JA3 / JA4)

Ver tls-fingerprinting.md para detalles completos.

Puntos clave para la capa de red:

  • El handshake TLS es la señal más importante a nivel de red
  • Totalmente controlable mediante utls (Go) o Rust TLS personalizado
  • Crítico para Obscura — debe falsificarse o se revela el proxy

3. Fingerprint HTTP/2

Mecanismo

El prefacio de conexión HTTP/2 y las tramas iniciales varían según la implementación.

Señales:

  • Parámetros de la trama SETTINGS (el orden importa):
    • SETTINGS_HEADER_TABLE_SIZE
    • SETTINGS_ENABLE_PUSH
    • SETTINGS_MAX_CONCURRENT_STREAMS
    • SETTINGS_INITIAL_WINDOW_SIZE
    • SETTINGS_MAX_FRAME_SIZE
    • SETTINGS_MAX_HEADER_LIST_SIZE
  • Trama inicial WINDOW_UPDATE
  • Comportamiento de PING
  • Estructura de trama PRIORITY

Ejemplos por Navegador

Navegador Initial Window Max Concurrent Header Table Size
Chrome 6291456 1000 65536
Firefox 131072 100 65536
Safari 1048576 100 65536

Impacto en Obscura

Si se usa net/http de Go para HTTP/2, el servidor ve el fingerprint HTTP/2 de Go. Debe implementar HTTP/2 personalizado o usar una librería que permita anular SETTINGS.


4. Fingerprint QUIC / HTTP/3

Problema

HTTP/3 se ejecuta sobre QUIC (UDP). Las conexiones QUIC están cifradas de extremo a extremo, incluyendo la capa de transporte:

Cliente  QUIC (UDP 443)  Servidor
                          
    Cifrado            Cifrado
    (no se puede inspeccionar)  (no se puede inspeccionar)

Los parámetros de transporte QUIC, IDs de conexión e información de versión son visibles en el handshake inicial, pero el proxy no puede modificarlos.

Estrategia

Bloquear UDP 443 para forzar la caída a HTTP/2 o HTTP/1.1 sobre TCP:

iptables -A FORWARD -p udp --dport 443 -j DROP

Esto evita que las conexiones QUIC eviten el proxy.

Compensación: Latencia ligeramente mayor (TCP vs QUIC), sin 0-RTT, sin migración de conexión.


5. Fingerprints Basados en Temporización

5.1 Rendimiento de Temporización

performance.now()  // Marca de tiempo de alta resolución en ms (precisión sub-milisegundo)
performance.timeOrigin
performance.getEntriesByType('navigation')

Mitigación: Redondear performance.now() a resolución de 100ms mediante inyección JS:

const originalNow = performance.now.bind(performance)
performance.now = () => Math.round(originalNow() / 100) * 100

5.2 Clock Skew

Los servidores pueden medir la desviación del reloj comparando valores de Date.now() entre peticiones.

Mitigación: Redondear la resolución de Date.now().

5.3 Temporización de Red mediante Carga de Recursos

Los sitios miden la latencia midiendo cuánto tardan los recursos en cargarse:

const start = performance.now()
fetch('/image.png').then(() => {
  const rtt = performance.now() - start
})

Mitigación: No se puede prevenir completamente — el proxy añade su propia latencia pero la temporización relativa sigue filtrando información.


6. Fuga de IP por WebRTC

Mecanismo

WebRTC evita el proxy usando servidores STUN/TURN para descubrir la IP real.

const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
})
pc.createDataChannel('test')
pc.createOffer().then(d => pc.setLocalDescription(d))
pc.onicecandidate = e => {
  if (e.candidate) {
    // e.candidate.candidate contiene la dirección IP
    console.log(e.candidate.candidate)
  }
}

Mitigación mediante Inyección JS

// Bloquear WebRTC completamente
Object.defineProperty(window, 'RTCPeerConnection', { value: undefined })
Object.defineProperty(window, 'RTCDataChannel', { value: undefined })
Object.defineProperty(window, 'RTCSessionDescription', { value: undefined })

Efecto

Configuración Fuga WebRTC Detección
WebRTC disponible La IP se filtra No detectado
WebRTC bloqueado Sin fuga Detectable (ausencia de característica)

7. Fingerprint DNS

Señales

  • IP del resolver DNS (Cloudflare 1.1.1.1 vs Google 8.8.8.8 vs ISP)
  • DNS sobre HTTPS vs DNS sobre TLS vs DNS plano
  • EDNS0 client subnet (revela ubicación de red aproximada)
  • Soporte DNSSEC

Mitigación

Obscura controla el DNS completamente. Usar un upstream consistente centrado en privacidad (Quad9 9.9.9.9 o Cloudflare 1.1.1.1) y eliminar EDNS0 client subnet.


Conclusiones para Obscura

Vector Controlable Prioridad Notas
Fingerprint TCP/IP No (heredado del contenedor) Baja Baja entropía, rara vez usado solo
Fingerprint TLS (mediante utls) Crítica Debe falsificarse o se revela el proxy
Fingerprint HTTP/2 Parcial Media Requiere impl. HTTP/2 personalizada
QUIC/HTTP/3 Bloquear o heredar Media Bloquear UDP 443
Ataques de temporización Parcial Baja Redondear performance.now()
Fuga de IP por WebRTC (bloquear mediante JS) Alta Crítico para usuarios de VPN
Fingerprint DNS Alta Obscura controla el DNS