Domein fronting gebaseerd op TLS 1.3

Introductie

Domein fronting gebaseerd op TLS 1.3
Moderne filtersystemen voor bedrijfsinhoud van gerenommeerde fabrikanten als Cisco, BlueCoat en FireEye hebben veel gemeen met hun krachtigere tegenhangers: DPI-systemen, die actief worden geïmplementeerd op nationaal niveau. De essentie van het werk van beiden is het inspecteren van inkomend en uitgaand internetverkeer en, op basis van zwart/witte lijsten, een besluit nemen om de internetverbinding te verbieden. En aangezien ze allebei in de basis van hun werk op vergelijkbare principes vertrouwen, zullen de methoden om deze te omzeilen ook veel gemeen hebben.

Een van de technologieën waarmee u zowel DPI als bedrijfssystemen zeer effectief kunt omzeilen, is domeingerichte technologie. De essentie ervan is dat we naar een geblokkeerde bron gaan, ons verschuilend achter een ander, publiek domein met een goede reputatie, dat uiteraard door geen enkel systeem zal worden geblokkeerd, bijvoorbeeld google.com.

Er zijn al heel wat artikelen over deze technologie geschreven en er zijn veel voorbeelden gegeven. De populaire en onlangs besproken DNS-over-HTTPS- en gecodeerde SNI-technologieën, evenals de nieuwe versie van het TLS 1.3-protocol, maken het echter mogelijk om een ​​andere optie voor domeinfronting te overwegen.

De technologie begrijpen

Laten we eerst een paar basisconcepten definiëren, zodat iedereen begrijpt wie wie is en waarom dit allemaal nodig is. We noemden het eDNI-mechanisme, waarvan de werking verder zal worden besproken. Het eSNI-mechanisme (encrypted Server Name Indication) is een veilige versie van SNI, alleen beschikbaar voor het TLS 1.3-protocol. Het belangrijkste idee is om onder andere informatie te versleutelen over naar welk domein het verzoek wordt verzonden.

Laten we nu eens kijken hoe het eSNI-mechanisme in de praktijk werkt.

Laten we zeggen dat we een internetbron hebben die wordt geblokkeerd door een moderne DPI-oplossing (laten we bijvoorbeeld de beroemde torrent-tracker rutracker.nl nemen). Wanneer we proberen toegang te krijgen tot de website van een torrent-tracker, zien we het standaardstrookje van de provider dat aangeeft dat de bron is geblokkeerd:

Domein fronting gebaseerd op TLS 1.3

Op de website van de RKN staat dit domein daadwerkelijk vermeld in de stoplijsten:

Domein fronting gebaseerd op TLS 1.3

Wanneer je whois opvraagt, zie je dat het domein zelf ‘verborgen’ is achter de cloudprovider Cloudflare.

Domein fronting gebaseerd op TLS 1.3

Maar in tegenstelling tot de ‘specialisten’ van RKN hebben meer technisch onderlegde medewerkers van Beeline (of geleerd door de bittere ervaring van onze beroemde toezichthouder) de site niet domweg verboden op IP-adres, maar hebben ze de domeinnaam aan de stoplijst toegevoegd. U kunt dit eenvoudig verifiëren als u kijkt welke andere domeinen achter hetzelfde IP-adres verborgen zijn, een van hen bezoekt en ziet dat de toegang niet is geblokkeerd:

Domein fronting gebaseerd op TLS 1.3

Hoe gebeurde dit? Hoe weet de DPI van de provider op welk domein mijn browser zich bevindt, aangezien alle communicatie verloopt via het https-protocol en we de vervanging van https-certificaten van Beeline nog niet hebben opgemerkt? Is hij helderziend of wordt ik gevolgd?

Laten we proberen deze vraag te beantwoorden door naar het verkeer via Wireshark te kijken

Domein fronting gebaseerd op TLS 1.3

De schermafbeelding laat zien dat de browser eerst het IP-adres van de server verkrijgt via DNS, vervolgens een standaard TCP-handshake plaatsvindt met de doelserver en vervolgens probeert de browser een SSL-verbinding met de server tot stand te brengen. Om dit te doen, verzendt het een SSL Client Hello-pakket, dat de naam van het brondomein in duidelijke tekst bevat. Dit veld is vereist door de cloudflare frontend-server om de verbinding correct te routeren. Dit is waar de provider DPI ons betrapt en onze verbinding verbreekt. Tegelijkertijd ontvangen we geen stub van de provider en zien we de standaard browserfout alsof de site is uitgeschakeld of simpelweg niet werkt:

Domein fronting gebaseerd op TLS 1.3

Laten we nu het eSNI-mechanisme in de browser inschakelen, zoals beschreven in de instructies voor Firefox :
Om dit te doen openen we de Firefox-configuratiepagina about: config en activeer de volgende instellingen:

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

Hierna zullen we controleren of de instellingen correct werken op de cloudflare-website. link en laten we de truc opnieuw proberen met onze torrent-tracker.

Domein fronting gebaseerd op TLS 1.3

Voila. Onze favoriete tracker werd geopend zonder VPN- of proxyservers. Laten we nu eens kijken naar de verkeersdump in Wireshark om te zien wat er is gebeurd.

Domein fronting gebaseerd op TLS 1.3

Deze keer bevat het hello-pakket van de ssl-client niet expliciet het bestemmingsdomein, maar in plaats daarvan verscheen er een nieuw veld in het pakket - gecodeerde_server_naam - dit is waar de waarde van rutracker.nl is opgenomen, en alleen de cloudflare frontend-server kan dit ontsleutelen veld. En als dat zo is, dan heeft de aanbieder DPI geen andere keuze dan zijn handen te wassen en dergelijk verkeer toe te staan. Er zijn geen andere opties met encryptie.

We hebben dus gekeken naar hoe de technologie in de browser werkt. Laten we nu proberen het op meer specifieke en interessante dingen toe te passen. En eerst zullen we dezelfde krul leren om eSNI te gebruiken om met TLS 1.3 te werken, en tegelijkertijd zullen we zien hoe de op eSNI gebaseerde domeinfronting zelf werkt.

Domeinfronting met eSNI

Omdat curl de standaard openssl-bibliotheek gebruikt om verbinding te maken via het https-protocol, moeten we daar allereerst eSNI-ondersteuning bieden. Er is nog geen eSNI-ondersteuning in de openssl master branches, dus we moeten een speciale openssl branch downloaden, compileren en installeren.

We klonen de repository van GitHub en compileren zoals gewoonlijk:

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

$ make
$ cd esnistuff
$ make

Vervolgens klonen we de repository met curl en configureren we de compilatie ervan met behulp van onze gecompileerde openssl-bibliotheek:

$ 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

Hier is het belangrijk om alle mappen waarin openssl zich bevindt correct te specificeren (in ons geval is dit /opt/openssl/) en ervoor te zorgen dat het configuratieproces zonder fouten verloopt.

Als de configuratie succesvol is, zien we de regel:

WAARSCHUWING: esni ESNI ingeschakeld maar gemarkeerd als EXPERIMENTEEL. Voorzichtig gebruiken!

$ make

Nadat we het pakket succesvol hebben gebouwd, zullen we een speciaal bash-bestand van openssl gebruiken om curl te configureren en uit te voeren. Laten we het voor het gemak met curl naar de map kopiëren:

cp /opt/openssl/esnistuff/curl-esni 

en doe een https-testverzoek aan de cloudflare-server, terwijl u tegelijkertijd DNS- en TLS-pakketten opneemt in Wireshark.

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

In het serverantwoord ontvangen we, naast veel foutopsporingsinformatie van openssl en curl, een HTTP-antwoord met code 301 van 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/

wat aangeeft dat ons verzoek met succes is afgeleverd bij de bestemmingsserver, gehoord en verwerkt.

Laten we nu eens kijken naar de verkeersdump in Wireshark, d.w.z. wat de aanbieder DPI in dit geval zag.

Domein fronting gebaseerd op TLS 1.3

Het is duidelijk dat Curl zich eerst tot de DNS-server wendde voor een openbare eSNI-sleutel voor de cloudflare-server - een TXT DNS-verzoek aan _esni.cloudflare.com (pakket nr. 13). Vervolgens stuurde curl met behulp van de openssl-bibliotheek een TLS 1.3-verzoek naar de cloudflare-server waarin het SNI-veld was gecodeerd met de openbare sleutel die in de vorige stap was verkregen (pakket #22). Maar naast het eSNI-veld bevatte het SSL-hello-pakket ook een veld met de gebruikelijke - open SNI, die we in elke volgorde kunnen specificeren (in dit geval - www.hello-rkn.ru).

Met dit open SNI-veld werd op geen enkele manier rekening gehouden bij de verwerking door cloudflare-servers en diende het alleen als masker voor de provider DPI. De cloudflare-server ontving ons ssl-hello-pakket, decodeerde de eSNI, haalde daar de originele SNI uit en verwerkte deze alsof er niets was gebeurd (hij deed alles precies zoals gepland bij de ontwikkeling van eSNI).

Het enige dat in dit geval vanuit DPI-oogpunt kan worden opgevangen, is het primaire DNS-verzoek aan _esni.cloudflare.com. Maar we hebben het DNS-verzoek alleen opengesteld om te laten zien hoe dit mechanisme van binnenuit werkt.

Om eindelijk het tapijt onder DPI vandaan te halen, gebruiken we het reeds genoemde DNS-over-HTTPS-mechanisme. Een kleine uitleg: DOH is een protocol waarmee u zich kunt beschermen tegen een man-in-the-middle-aanval door een DNS-verzoek via HTTPS te verzenden.

Laten we het verzoek opnieuw uitvoeren, maar deze keer ontvangen we openbare eSNI-sleutels via het https-protocol, niet via DNS:

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

De verzoekverkeersdump wordt weergegeven in de onderstaande schermafbeelding:

Domein fronting gebaseerd op TLS 1.3

Het is te zien dat curl eerst toegang krijgt tot de mozilla.cloudflare-dns.com-server via het DoH-protocol (https-verbinding met server 104.16.249.249) om van hen de waarden van openbare sleutels voor SNI-codering te verkrijgen, en vervolgens naar de bestemming server, verstopt achter het domein www.hello-rkn.ru.

Naast de bovenstaande DoH-resolver mozilla.cloudflare-dns.com kunnen we andere populaire DoH-services gebruiken, bijvoorbeeld van het beroemde kwaadaardige bedrijf.
Laten we de volgende query uitvoeren:

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

En wij krijgen het antwoord:

< 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

Domein fronting gebaseerd op TLS 1.3

In dit geval hebben we ons tot de geblokkeerde rutracker.nl-server gewend, met behulp van de DoH-resolver dns.google (er is hier geen typefout, nu heeft het beroemde bedrijf zijn eigen eerste-niveaudomein) en hebben we onszelf afgedekt met een ander domein, dat strikt verboden voor alle DPI's om te blokkeren op straffe van de dood. Op basis van de ontvangen reactie kunt u begrijpen dat ons verzoek succesvol is verwerkt.

Als extra controle of de DPI van de provider reageert op de open SNI, die wij als dekmantel doorgeven, kunnen we een verzoek doen aan rutracker.nl onder het mom van een andere verboden bron, bijvoorbeeld een andere “goede” torrent-tracker:

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

Wij ontvangen geen reactie van de server, omdat... ons verzoek wordt geblokkeerd door het DPI-systeem.

Een korte conclusie van het eerste deel

We konden dus de functionaliteit van eSNI demonstreren met behulp van openssl en curl en de werking van domeinfronting op basis van eSNI testen. Op dezelfde manier kunnen we onze favoriete tools die de openssl-bibliotheek gebruiken, aanpassen om ‘onder het mom’ van andere domeinen te werken. Meer details hierover in onze volgende artikelen.

Bron: www.habr.com

Voeg een reactie