Domain fronting basato su TLS 1.3

Introduzione

Domain fronting basato su TLS 1.3
I sistemi di filtraggio dei contenuti moderni delle aziende, di marchi prestigiosi come Cisco, BlueCoat e FireEye, hanno molte affinità con i loro potenti omologhi — i sistemi DPI, che stanno venendo implementati a livello nazionale. La loro funzione principale è quella di ispezionare il traffico internet in entrata e in uscita e, basandosi su liste nere/viola, decidere se bloccare la connessione internet. Poiché entrambi si basano su principi simili, anche i metodi per eluderli presentano molte somiglianze.

Una delle tecnologie che consente di aggirare in modo efficace sia il DPI che i sistemi aziendali è il domain fronting. La sua essenza consiste nel visitare una risorsa bloccata, celandosi dietro un altro dominio pubblico, con una buona reputazione, che non sarà mai bloccato da alcun sistema, per esempio google.com.

Su questa tecnologia sono stati scritti già molti articoli e forniti numerosi esempi. Tuttavia, le tecnologie discusse di recente come DNS-over-HTTPS e encrypted-SNI, oltre alla nuova versione del protocollo TLS 1.3, offrono ulteriori opzioni per il domain fronting.

Esploriamo la tecnologia

Iniziamo definendo alcuni concetti fondamentali, affinché tutti abbiano chiaro chi è chi e a cosa serve il tutto. Abbiamo citato il meccanismo eSNI, la cui funzionalità sarà esaminata in seguito. Il meccanismo eSNI (encrypted Server Name Indication) è una versione protetta dell'SNI, disponibile solo per il protocollo TLS 1.3. La sua essenza principale è quella di crittografare anche le informazioni relative al dominio per il quale viene effettuata la richiesta.

Ora, esaminiamo il funzionamento del meccanismo eSNI nella pratica.

Supponiamo di avere una risorsa internet che viene bloccata da una moderna soluzione DPI (prendiamo ad esempio il famoso tracker torrent — rutracker.nl). Quando tentiamo di accedere al sito del tracker torrent, vediamo il messaggio standard del fornitore che informa che la risorsa è bloccata:

Domain fronting basato su TLS 1.3

Sul sito del RKN, questo dominio risulta effettivamente presente nelle liste di blocco:

Domain fronting basato su TLS 1.3

Eseguendo una richiesta whois, si può osservare che il dominio è 'nascosto' dietro il provider cloud Cloudflare.

Domain fronting basato su TLS 1.3

Ma a differenza dei 'professionisti' del RKN, i più tecnicamente competenti membri del Beeline (o chi ha appreso a proprie spese dall'esperienza del nostro famoso regolatore) non hanno semplicemente bloccato il sito per indirizzo IP, ma hanno inserito in lista nera proprio il nome di dominio. È facile verificarlo, controllando quali altri domini sono nascosti dietro questo stesso indirizzo IP, visitando uno di essi e scoprendo che l'accesso non è bloccato:

Domain fronting basato su TLS 1.3

Ma come si spiega questo? In che modo il DPI del fornitore può sapere a quale dei domini il mio browser sta accedendo, se tutte le comunicazioni avvengono tramite il protocollo HTTPS, e finora non abbiamo notato tentativi di spoofing dei certificati HTTPS da parte di Beeline? È forse un veggente o qualcuno mi sta seguendo?

Cerchiamo di rispondere a questa domanda esaminando il traffico tramite Wireshark.

Domain fronting basato su TLS 1.3

Nello screenshot si vede che prima il browser ottiene l'indirizzo IP del server tramite DNS, poi avviene un normale handshake TCP con il server di destinazione e infine il browser cerca di stabilire una connessione SSL con il server. Per fare ciò, invia un pacchetto SSL Client Hello, in cui è presente il nome del dominio sorgente in chiaro. Questo campo è necessario al server front-end di Cloudflare per instradare correttamente la connessione. Ed è qui che il DPI del fornitore ci sorprende, interrompendo la connessione. In questo caso, non riceviamo alcun messaggio di errore dal fornitore, e vediamo il messaggio di errore standard del browser come se il sito fosse disabilitato o semplicemente non funzionasse:

Domain fronting basato su TLS 1.3

Ora attiviamo il meccanismo eSNI nel browser, come descritto nelle istruzioni per Firefox :
Per fare ciò, apriamo la pagina di configurazione di Firefox about:config e attiviamo le seguenti impostazioni:

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

Dopo di che, verificheremo il corretto funzionamento delle impostazioni sul sito Cloudflare tramite link e riproveremo il trucco con il nostro tracker torrent.

Domain fronting basato su TLS 1.3

Voilà. Il nostro tracker preferito è accessibile, senza alcun uso di VPN o proxy. Ora diamo un'occhiata al dump di traffico in Wireshark per vedere cosa è successo.

Domain fronting basato su TLS 1.3

Questa volta il pacchetto SSL Client Hello non contiene esplicitamente il dominio di destinazione, ma al suo interno è presente un nuovo campo — encrypted_server_name — dove è contenuto il valore rutracker.nl, e solo il server front-end di Cloudflare può decifrare questo campo. Pertanto, il DPI del fornitore non ha altra scelta che alzare le mani e consentire questo traffico. Non ci sono altre opzioni con la crittografia.

Quindi, abbiamo esaminato come funziona la tecnologia nel browser. Ora proviamo a applicarla a cose più specifiche e interessanti. Per iniziare, insegneremo a curl a utilizzare eSNI per lavorare con TLS 1.3, e vedremo anche come funziona il domain fronting basato su eSNI.

Domain fronting con eSNI

Dato che curl utilizza la libreria standard openssl per connettersi tramite il protocollo https, dobbiamo prima assicurare il supporto per eSNI lì. Nelle branche master di openssl, il supporto per eSNI non è ancora disponibile, quindi dobbiamo scaricare un ramo speciale di openssl, compilarlo e installarlo.

Cloniamo il repository da GitHub e compiliamo come al solito:

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

$ make
$ cd esnistuff
$ make

Successivamente, cloniamo il repository di curl e configuriamo la sua compilazione utilizzando la nostra libreria openssl appena creata:

$ 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

È importante specificare correttamente tutte le directory in cui si trova openssl (nel nostro caso, è /opt/openssl/) e assicurarsi che il processo di configurazione sia completato senza errori.

In caso di configurazione riuscita, vedremo la seguente riga:

WARNING: esni ESNI enabled but marked EXPERIMENTAL. Use with caution!

$ make

Dopo aver compilato con successo il pacchetto, utilizzeremo un file bash speciale fornito con openssl per configurare e avviare curl. Copiamolo nella directory di curl per comodità:

cp /opt/openssl/esnistuff/curl-esni 

e faremo una richiesta https di prova al server cloudflare, registrando contemporaneamente i pacchetti DNS e TLS in Wireshark.

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

Nella risposta del server, oltre a molte informazioni di debug da openssl e curl, riceveremo una risposta HTTP con codice 301 da 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/

che indica che la nostra richiesta è stata consegnata con successo al server di destinazione, ricevuta e elaborata.

Ora diamo un'occhiata al dump del traffico in Wireshark, cioè cosa ha visto in questo caso il DPI del provider.

Domain fronting basato su TLS 1.3

Si vede chiaramente che curl ha prima contattato il server DNS per ottenere la chiave pubblica eSNI per il server cloudflare — richiesta DNS TXT su _esni.cloudflare.com (pacchetto n. 13). Poi, utilizzando la libreria openssl, curl ha inviato una richiesta TLS 1.3 al server cloudflare in cui il campo SNI era crittografato con la chiave pubblica ottenuta nella fase precedente (pacchetto n. 22). Inoltre, oltre al campo eSNI, nel pacchetto SSL-hello è stato inserito anche un campo con il normale — aperto SNI, che possiamo specificare in modo arbitrario (in questo caso — www.hello-rkn.ru).

Questo campo di SNI aperto non è stato in alcun modo considerato nell'elaborazione da parte dei server cloudflare e serviva solo come mascheramento per il DPI del provider. Il server cloudflare ha accettato il nostro pacchetto ssl-hello, ha decifrato l'eSNI, estraendo da esso il SNI originale e lo ha elaborato come se nulla fosse (ha fatto esattamente come previsto nello sviluppo di eSNI).

L'unica cosa che si può notare in questo caso dal punto di vista del DPI è la richiesta DNS iniziale su _esni.cloudflare.com. Ma abbiamo fatto la richiesta DNS aperta solo per mostrare come funziona questo meccanismo dall'interno.

Per tagliare completamente il terreno sotto ai piedi del DPI, utilizziamo già menzionato meccanismo DNS-over-HTTPS. Una piccola spiegazione: DOH è un protocollo che permette di proteggersi da attacchi "man-in-the-middle" inviando richieste DNS tramite il protocollo HTTPS.

Effettuiamo nuovamente la richiesta, ma questa volta otteniamo le chiavi pubbliche eSNI tramite il protocollo https, invece che DNS:

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

Il dump del traffico della richiesta è mostrato nello screenshot sottostante:

Domain fronting basato su TLS 1.3

È evidente che, prima, curl contatta il server mozilla.cloudflare-dns.com tramite il protocollo DoH (connessione https al server 104.16.249.249), per ottenere da loro i valori delle chiavi pubbliche per crittografare il SNI, e poi contatta il server di destinazione, coprendosi con il dominio. www.hello-rkn.ru.

Oltre al resolver DoH sopra menzionato mozilla.cloudflare-dns.com, possiamo utilizzare anche altri popolari servizi DoH, ad esempio, dell'omonima corporation del male.
Effettuiamo una richiesta simile:

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

E riceviamo la risposta:

< 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

Domain fronting basato su TLS 1.3

In questo caso, abbiamo effettuato una richiesta al server bloccato rutracker.nl, utilizzando il resolver DoH dns.google (non c'è errore, ora la famosa azienda ha il proprio dominio di primo livello) e ci siamo coperti con un altro dominio, il cui blocco è rigorosamente vietato a tutti i DPI sotto pena di morte. Dalla risposta ricevuta, possiamo capire che la nostra richiesta è stata elaborata con successo.

Come ulteriore verifica che il DPI del provider reagisce all'SNI aperto che stiamo passando come copertura — possiamo eseguire una richiesta a rutracker.nl coprendoci con un altro risorsa vietata, per esempio un altro buon tracker torrent:

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

Non riceveremo risposta dal server, poiché la nostra richiesta sarà bloccata dal sistema DPI.

Una piccola conclusione per la prima parte

Dunque, siamo riusciti a dimostrare il funzionamento di eSNI con openssl e curl e a verificare il funzionamento del domain fronting basato su eSNI. Possiamo adattare i nostri strumenti preferiti che utilizzano la libreria openssl per operare "sotto copertura" di altri domini. Maggiori dettagli su questo nei nostri prossimi articoli.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster