Frente de dominio basado en TLS 1.3

introducción

Frente de dominio basado en TLS 1.3
Los modernos sistemas de filtrado de contenidos corporativos de fabricantes de renombre como Cisco, BlueCoat y FireEye tienen mucho en común con sus homólogos más potentes: los sistemas DPI, que se están implementando activamente a nivel nacional. La esencia del trabajo de ambos es inspeccionar el tráfico de Internet entrante y saliente y, basándose en listas blancas y negras, tomar la decisión de prohibir la conexión a Internet. Y dado que ambos se basan en principios similares en la base de su trabajo, los métodos para eludirlos también tendrán mucho en común.

Una de las tecnologías que le permite eludir de manera bastante efectiva tanto DPI como los sistemas corporativos es la tecnología de dominio frontal. Su esencia es que accedemos a un recurso bloqueado, escondiéndonos detrás de otro dominio público y de buena reputación, que obviamente no será bloqueado por ningún sistema, por ejemplo google.com.

Ya se han escrito bastantes artículos sobre esta tecnología y se han dado muchos ejemplos. Sin embargo, las populares y recientemente discutidas tecnologías DNS sobre HTTPS y SNI cifrado, así como la nueva versión del protocolo TLS 1.3, permiten considerar otra opción para el frente de dominio.

Entendiendo la tecnología

Primero, definamos algunos conceptos básicos para que todos comprendan quién es quién y por qué se necesita todo esto. Mencionamos el mecanismo eSNI, cuyo funcionamiento se discutirá más adelante. El mecanismo eSNI (indicación de nombre de servidor cifrado) es una versión segura de SNI, disponible solo para el protocolo TLS 1.3. La idea principal es cifrar, entre otras cosas, la información sobre a qué dominio se envía la solicitud.

Ahora veamos cómo funciona el mecanismo eSNI en la práctica.

Digamos que tenemos un recurso de Internet que está bloqueado por una solución DPI moderna (tomemos, por ejemplo, el famoso rastreador de torrents rutracker.nl). Cuando intentamos acceder al sitio web de un rastreador de torrents, vemos el código auxiliar estándar del proveedor que indica que el recurso está bloqueado:

Frente de dominio basado en TLS 1.3

En el sitio web de RKN, este dominio aparece en las listas de exclusión:

Frente de dominio basado en TLS 1.3

Cuando consulta whois, puede ver que el dominio en sí está "oculto" detrás del proveedor de nube Cloudflare.

Frente de dominio basado en TLS 1.3

Pero a diferencia de los "especialistas" de RKN, los empleados de Beeline con más conocimientos técnicos (o enseñados por la amarga experiencia de nuestro famoso regulador) no prohibieron estúpidamente el sitio por dirección IP, sino que agregaron el nombre de dominio a la lista de bloqueo. Puedes verificar esto fácilmente si observas qué otros dominios están ocultos detrás de la misma dirección IP, visitas uno de ellos y ves que el acceso no está bloqueado:

Frente de dominio basado en TLS 1.3

¿Como sucedió esto? ¿Cómo sabe el DPI del proveedor en qué dominio se encuentra mi navegador, ya que todas las comunicaciones se realizan a través del protocolo https y aún no hemos notado la sustitución de los certificados https de Beeline? ¿Es clarividente o me están siguiendo?

Intentemos responder esta pregunta observando el tráfico a través de Wireshark.

Frente de dominio basado en TLS 1.3

La captura de pantalla muestra que primero el navegador obtiene la dirección IP del servidor a través de DNS, luego se produce un protocolo de enlace TCP estándar con el servidor de destino y luego el navegador intenta establecer una conexión SSL con el servidor. Para hacer esto, envía un paquete de saludo de cliente SSL, que contiene el nombre del dominio de origen en texto sin cifrar. Este campo es requerido por el servidor frontend de Cloudflare para poder enrutar correctamente la conexión. Aquí es donde nos pilla el proveedor DPI, rompiendo nuestra conexión. Al mismo tiempo, no recibimos ningún resguardo del proveedor y vemos el error estándar del navegador como si el sitio estuviera deshabilitado o simplemente no funciona:

Frente de dominio basado en TLS 1.3

Ahora habilitemos el mecanismo eSNI en el navegador, como está escrito en las instrucciones para Firefox :
Para ello abrimos la página de configuración de Firefox about: config y active las siguientes configuraciones:

network.trr.mode = 2;
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
network.security.esni.enabled = true

Después de esto, comprobaremos que la configuración funciona correctamente en el sitio web de Cloudflare. enlace y probemos nuevamente el truco con nuestro rastreador de torrents.

Frente de dominio basado en TLS 1.3

Listo. Nuestro rastreador favorito se abrió sin VPN ni servidores proxy. Veamos ahora el volcado de tráfico en Wireshark para ver qué sucedió.

Frente de dominio basado en TLS 1.3

Esta vez, el paquete de saludo del cliente SSL no contiene explícitamente el dominio de destino, sino que apareció un nuevo campo en el paquete: nombre_servidor_encriptado: aquí es donde está contenido el valor de rutracker.nl, y solo el servidor frontend de Cloudflare puede descifrarlo. campo. Y si es así, entonces el proveedor DPI no tiene más remedio que lavarse las manos y permitir ese tráfico. No hay otras opciones con cifrado.

Entonces, analizamos cómo funciona la tecnología en el navegador. Ahora intentemos aplicarlo a cosas más específicas e interesantes. Y primero, le enseñaremos al mismo curl cómo usar eSNI para trabajar con TLS 1.3 y, al mismo tiempo, veremos cómo funciona el dominio frontal basado en eSNI.

Fronting de dominio con eSNI

Debido al hecho de que curl utiliza la biblioteca estándar openssl para conectarse a través del protocolo https, primero que nada debemos brindar soporte eSNI allí. Todavía no hay soporte para eSNI en las ramas maestras de openssl, por lo que necesitamos descargar una rama de openssl especial, compilarla e instalarla.

Clonamos el repositorio de GitHub y compilamos como siempre:

$ git clone https://github.com/sftcd/openssl
$ cd openssl
$ ./config

$ make
$ cd esnistuff
$ make

A continuación, clonamos el repositorio con curl y configuramos su compilación usando nuestra biblioteca openssl compilada:

$ cd $HOME/code
$ git clone https://github.com/niallor/curl.git curl-esni
$ cd curl-esni

$ export LD_LIBRARY_PATH=/opt/openssl
$ ./buildconf
$ LDFLAGS="-L/opt/openssl" ./configure --with-ssl=/opt/openssl --enable-esni --enable-debug

Aquí es importante especificar correctamente todos los directorios donde se encuentra openssl (en nuestro caso, este es /opt/openssl/) y asegurarse de que el proceso de configuración se realice sin errores.

Si la configuración es exitosa, veremos la línea:

ADVERTENCIA: esni ESNI habilitado pero marcado como EXPERIMENTAL. ¡Úselo con precaución!

$ make

Después de compilar exitosamente el paquete, usaremos un archivo bash especial de openssl para configurar y ejecutar curl. Copiémoslo al directorio con curl para mayor comodidad:

cp /opt/openssl/esnistuff/curl-esni 

y realice una solicitud https de prueba al servidor de Cloudflare, mientras graba simultáneamente paquetes DNS y TLS en Wireshark.

$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/

En la respuesta del servidor, además de mucha información de depuración de openssl y curl, recibiremos una respuesta HTTP con el código 301 de cloudflare.

HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 13:12:55 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: max-age=3600
< Expires: Sun, 03 Nov 2019 14:12:55 GMT
< Location: https://www.cloudflare.com/

lo que indica que nuestra solicitud fue entregada exitosamente al servidor de destino, escuchada y procesada.

Ahora veamos el volcado de tráfico en Wirehark, es decir. lo que vio el proveedor DPI en este caso.

Frente de dominio basado en TLS 1.3

Se puede ver que curl primero recurrió al servidor DNS para obtener una clave eSNI pública para el servidor cloudflare: una solicitud DNS TXT a _esni.cloudflare.com (paquete número 13). Luego, utilizando la biblioteca openssl, curl envió una solicitud TLS 1.3 al servidor de cloudflare en la que se cifró el campo SNI con la clave pública obtenida en el paso anterior (paquete #22). Pero, además del campo eSNI, el paquete SSL-hello también incluía un campo con el SNI abierto habitual, que podemos especificar en cualquier orden (en este caso, www.hola-rkn.ru).

Este campo SNI abierto no se tuvo en cuenta de ninguna manera cuando lo procesaron los servidores de Cloudflare y solo sirvió como máscara para el DPI del proveedor. El servidor Cloudflare recibió nuestro paquete ssl-hello, descifró el eSNI, extrajo el SNI original de allí y lo procesó como si nada hubiera pasado (hizo todo exactamente como se planeó al desarrollar eSNI).

Lo único que se puede detectar en este caso desde el punto de vista de DPI es la solicitud de DNS principal a _esni.cloudflare.com. Pero hicimos que la solicitud de DNS se abriera solo para mostrar cómo funciona este mecanismo desde adentro.

Para finalmente quitarle la alfombra a DPI, utilizamos el mecanismo DNS sobre HTTPS ya mencionado. Una pequeña explicación: DOH es un protocolo que le permite protegerse contra un ataque de intermediario enviando una solicitud de DNS a través de HTTPS.

Ejecutemos la solicitud nuevamente, pero esta vez recibiremos claves eSNI públicas a través del protocolo https, no DNS:

ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/

El volcado de tráfico de solicitud se muestra en la siguiente captura de pantalla:

Frente de dominio basado en TLS 1.3

Se puede observar que curl accede primero al servidor mozilla.cloudflare-dns.com a través del protocolo DoH (conexión https al servidor 104.16.249.249) para obtener de él los valores de las claves públicas para el cifrado SNI, y luego al destino. servidor, escondido detrás del dominio www.hola-rkn.ru.

Además del solucionador de DoH mozilla.cloudflare-dns.com anterior, podemos utilizar otros servicios DoH populares, por ejemplo, de la famosa corporación malvada.
Ejecutemos la siguiente consulta:

ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/

Y obtenemos la respuesta:

< HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 14:10:22 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=da0144d982437e77b0b37af7d00438b1a1572790222; expires=Mon, 02-Nov-20 14:10:22 GMT; path=/; domain=.rutracker.nl; HttpOnly; Secure
< Location: https://rutracker.nl/forum/index.php
< CF-Cache-Status: DYNAMIC
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 52feee696f42d891-CPH

Frente de dominio basado en TLS 1.3

En este caso, recurrimos al servidor bloqueado rutracker.nl, utilizando el solucionador DoH dns.google (aquí no hay ningún error tipográfico, ahora la famosa corporación tiene su propio dominio de primer nivel) y nos cubrimos con otro dominio, que es estrictamente Está prohibido que todos los DPI bloqueen bajo pena de muerte. Según la respuesta recibida, puede entender que nuestra solicitud fue procesada exitosamente.

Como comprobación adicional de que el DPI del proveedor responde al SNI abierto, que enviamos como tapadera, podemos realizar una solicitud a rutracker.nl bajo la apariencia de algún otro recurso prohibido, por ejemplo, otro rastreador de torrents "bueno":

$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/

No recibiremos respuesta del servidor, porque... nuestra solicitud será bloqueada por el sistema DPI.

Una breve conclusión de la primera parte.

Entonces, pudimos demostrar la funcionalidad de eSNI usando openssl y curl y probar el funcionamiento del dominio frontal basado en eSNI. De la misma manera, podemos adaptar nuestras herramientas favoritas que utilizan la biblioteca openssl para que funcionen “bajo la apariencia” de otros dominios. Más detalles sobre esto en nuestros próximos artículos.

Fuente: habr.com

Añadir un comentario