Fronting del dominio basato su TLS 1.3

Introduzione

Fronting del dominio basato su TLS 1.3
I moderni sistemi di filtraggio dei contenuti aziendali di produttori rinomati come Cisco, BlueCoat, FireEye hanno molto in comune con le loro controparti più potenti: i sistemi DPI, che vengono attivamente implementati a livello nazionale. L'essenza del lavoro di entrambi è controllare il traffico Internet in entrata e in uscita e, sulla base delle liste nere/bianche, prendere la decisione di vietare la connessione Internet. E poiché entrambi si basano su principi simili alla base del loro lavoro, anche i metodi per aggirarli avranno molto in comune.

Una delle tecnologie che consente di aggirare in modo abbastanza efficace sia i DPI che i sistemi aziendali è la tecnologia di dominio. La sua essenza è che andiamo su una risorsa bloccata, nascondendoci dietro un'altra, di dominio pubblico con una buona reputazione, che ovviamente non verrà bloccata da nessun sistema, ad esempio google.com.

Sono già stati scritti molti articoli su questa tecnologia e sono stati forniti molti esempi. Tuttavia, le popolari e recentemente discusse tecnologie DNS-over-HTTPS e SNI crittografate, nonché la nuova versione del protocollo TLS 1.3, consentono di considerare un'altra opzione per il domain fronting.

Comprendere la tecnologia

Per prima cosa, definiamo alcuni concetti di base in modo che tutti capiscano chi è chi e perché tutto ciò è necessario. Abbiamo menzionato il meccanismo eSNI, il cui funzionamento sarà discusso più avanti. Il meccanismo eSNI (Encrypted Server Name Indication) è una versione sicura di SNI, disponibile solo per il protocollo TLS 1.3. L'idea principale è crittografare, tra le altre cose, le informazioni sul dominio a cui viene inviata la richiesta.

Vediamo ora come funziona nella pratica il meccanismo eSNI.

Supponiamo di avere una risorsa Internet bloccata da una moderna soluzione DPI (prendiamo ad esempio il famoso tracker torrent rutracker.nl). Quando proviamo ad accedere al sito web di un tracker torrent, vediamo lo stub standard del provider che indica che la risorsa è bloccata:

Fronting del dominio basato su TLS 1.3

Sul sito web RKN questo dominio è effettivamente elencato negli elenchi di stop:

Fronting del dominio basato su TLS 1.3

Quando chiedi whois, puoi vedere che il dominio stesso è “nascosto” dietro il fornitore di servizi cloud Cloudflare.

Fronting del dominio basato su TLS 1.3

Ma a differenza degli "specialisti" di RKN, i dipendenti più esperti tecnicamente di Beeline (o istruiti dall'amara esperienza del nostro famoso regolatore) non hanno stupidamente vietato il sito tramite indirizzo IP, ma hanno aggiunto il nome di dominio all'elenco di stop. Puoi verificarlo facilmente se guardi quali altri domini si nascondono dietro lo stesso indirizzo IP, visita uno di essi e vedi che l'accesso non è bloccato:

Fronting del dominio basato su TLS 1.3

Come avviene questo? Come fa il DPI del provider a sapere su quale dominio si trova il mio browser, poiché tutte le comunicazioni avvengono tramite il protocollo https e non abbiamo ancora notato la sostituzione dei certificati https da Beeline? È chiaroveggente o mi stanno seguendo?

Proviamo a rispondere a questa domanda osservando il traffico attraverso WireShark

Fronting del dominio basato su TLS 1.3

Lo screenshot mostra che prima il browser ottiene l'indirizzo IP del server tramite DNS, poi avviene un handshake TCP standard con il server di destinazione e infine il browser tenta di stabilire una connessione SSL con il server. Per fare ciò, invia un pacchetto SSL Client Hello, che contiene il nome del dominio di origine in chiaro. Questo campo è richiesto dal server frontend cloudflare per instradare correttamente la connessione. È qui che ci sorprende il provider DPI, interrompendo la nostra connessione. Allo stesso tempo, non riceviamo alcun stub dal provider e vediamo l'errore standard del browser come se il sito fosse disabilitato o semplicemente non funzionasse:

Fronting del dominio basato su TLS 1.3

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

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

Successivamente, controlleremo che le impostazioni funzionino correttamente sul sito web di cloudflare. collegamento e proviamo di nuovo il trucco con il nostro tracker torrent.

Fronting del dominio basato su TLS 1.3

Ecco. Il nostro tracker preferito si è aperto senza VPN o server proxy. Diamo ora un'occhiata al dump del traffico in Wireshark per vedere cosa è successo.

Fronting del dominio basato su TLS 1.3

Questa volta, il pacchetto hello del client SSL non contiene esplicitamente il dominio di destinazione, ma invece è apparso un nuovo campo nel pacchetto - crypto_server_name - qui è contenuto il valore di rutracker.nl e solo il server frontend cloudflare può decrittografarlo campo. E se è così, il provider DPI non ha altra scelta che lavarsene le mani e consentire tale traffico. Non ci sono altre opzioni con la crittografia.

Quindi, abbiamo esaminato come funziona la tecnologia nel browser. Ora proviamo ad applicarlo a cose più specifiche e interessanti. E per prima cosa insegneremo allo stesso ricciolo come utilizzare eSNI per lavorare con TLS 1.3 e allo stesso tempo vedremo come funziona il domain fronting stesso basato su eSNI.

Fronting del dominio con eSNI

Dato che curl utilizza la libreria standard openssl per connettersi tramite il protocollo https, dobbiamo innanzitutto fornire lì il supporto eSNI. Non c'è ancora supporto eSNI nei rami master di openssl, 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 con curl e configuriamo la sua compilazione utilizzando la nostra libreria openssl compilata:

$ 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

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

Se la configurazione ha esito positivo, vedremo la riga:

ATTENZIONE: esni ESNI abilitato ma contrassegnato come SPERIMENTALE. Usare con cautela!

$ make

Dopo aver creato con successo il pacchetto, utilizzeremo uno speciale file bash di openssl per configurare ed eseguire curl. Copiamolo nella directory con curl per comodità:

cp /opt/openssl/esnistuff/curl-esni 

ed effettuare 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 il 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/

il che indica che la nostra richiesta è stata consegnata con successo al server di destinazione, ascoltata ed elaborata.

Ora diamo un'occhiata al dump del traffico in WireShark, ad es. cosa ha visto il provider DPI in questo caso.

Fronting del dominio basato su TLS 1.3

Si può vedere che curl si è inizialmente rivolto al server DNS per una chiave eSNI pubblica per il server cloudflare: una richiesta DNS TXT a _esni.cloudflare.com (pacchetto n. 13). Quindi, 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 nel passaggio precedente (pacchetto n. 22). Ma, oltre al campo eSNI, il pacchetto SSL-hello includeva anche un campo con il solito - open SNI, che possiamo specificare in qualsiasi ordine (in questo caso - www.ciao-rkn.ru).

Questo campo SNI aperto non è stato preso in considerazione in alcun modo durante l'elaborazione dai server cloudflare e è servito solo come maschera per il provider DPI. Il server cloudflare ha ricevuto il nostro pacchetto ssl-hello, ha decrittografato l'eSNI, ha estratto da lì l'SNI originale e lo ha elaborato come se nulla fosse accaduto (ha fatto tutto esattamente come previsto durante lo sviluppo di eSNI).

L'unica cosa che può essere rilevata in questo caso dal punto di vista DPI è la richiesta DNS primaria a _esni.cloudflare.com. Ma abbiamo reso aperta la richiesta DNS solo per mostrare come funziona questo meccanismo dall'interno.

Per togliere finalmente il terreno sotto i DPI, utilizziamo il già citato meccanismo DNS-over-HTTPS. Una piccola spiegazione: DOH è un protocollo che consente di proteggersi da un attacco man-in-the-middle inviando una richiesta DNS su HTTPS.

Eseguiamo nuovamente la richiesta, ma questa volta riceveremo le chiavi eSNI pubbliche tramite il protocollo https, non 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 seguente:

Fronting del dominio basato su TLS 1.3

Si può notare che curl accede prima al server mozilla.cloudflare-dns.com tramite il protocollo DoH (connessione https al server 104.16.249.249) per ottenere da questi i valori delle chiavi pubbliche per la crittografia SNI, e poi a destinazione server, nascondendosi dietro il dominio www.ciao-rkn.ru.

Oltre al risolutore DoH sopra mozilla.cloudflare-dns.com, possiamo utilizzare altri servizi DoH popolari, ad esempio, della famosa società malvagia.
Eseguiamo la seguente query:

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

E otteniamo 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

Fronting del dominio basato su TLS 1.3

In questo caso ci siamo rivolti al server rutracker.nl bloccato, utilizzando il risolutore DoH dns.google (qui non c'è errore di battitura, ora la famosa azienda ha un proprio dominio di primo livello) e ci siamo coperti con un altro dominio, rigorosamente Vietato il blocco di tutti i DPI pena la morte. Dalla risposta ricevuta puoi comprendere che la nostra richiesta è stata elaborata con successo.

Come ulteriore controllo che il DPI del provider risponda all'SNI aperto, che trasmettiamo come copertura, possiamo fare una richiesta a rutracker.nl con il pretesto di qualche altra risorsa vietata, ad esempio un altro tracker torrent "buono":

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

Non riceveremo risposta dal server perché... la nostra richiesta verrà bloccata dal sistema DPI.

Una breve conclusione della prima parte

Pertanto, siamo stati in grado di dimostrare la funzionalità di eSNI utilizzando openssl e curl e testare il funzionamento del domain fronting basato su eSNI. Allo stesso modo, possiamo adattare i nostri strumenti preferiti che utilizzano la libreria openssl affinché funzionino “sotto le spoglie” di altri domini. Maggiori dettagli a riguardo nei nostri prossimi articoli.

Fonte: habr.com

Aggiungi un commento