Domänfronting baserad på TLS 1.3

Inledning

Domänfronting baserad på TLS 1.3
Moderna företagsinnehållsfiltreringssystem från så välkända tillverkare som Cisco, BlueCoat, FireEye har ganska mycket gemensamt med sina mer kraftfulla motsvarigheter - DPI-system, som aktivt implementeras på nationell nivå. Kärnan i bådas arbete är att inspektera inkommande och utgående internettrafik och, utifrån svart/vita listor, fatta beslut om att förbjuda internetuppkopplingen. Och eftersom de båda förlitar sig på liknande principer i grunderna för sitt arbete, kommer metoderna för att kringgå dem också att ha mycket gemensamt.

En av de teknologier som gör att du ganska effektivt kan kringgå både DPI och företagssystem är domän-fronting teknologi. Dess kärna är att vi går till en blockerad resurs, gömmer oss bakom en annan, offentlig domän med ett gott rykte, som uppenbarligen inte kommer att blockeras av något system, till exempel google.com.

Det har redan skrivits en hel del artiklar om denna teknik och många exempel har getts. De populära och nyligen diskuterade DNS-over-HTTPS och krypterade-SNI-teknikerna, liksom den nya versionen av TLS 1.3-protokollet, gör det dock möjligt att överväga ett annat alternativ för domänfronting.

Förstå tekniken

Låt oss först definiera lite grundläggande begrepp så att alla har en förståelse för vem som är vem och varför allt detta behövs. Vi nämnde eSNI-mekanismen, vars funktion kommer att diskuteras vidare. eSNI-mekanismen (krypterad servernamnsindikation) är en säker version av SNI, endast tillgänglig för TLS 1.3-protokollet. Huvudtanken är att kryptera bland annat information om vilken domän förfrågan skickas till.

Låt oss nu titta på hur eSNI-mekanismen fungerar i praktiken.

Låt oss säga att vi har en internetresurs som är blockerad av en modern DPI-lösning (låt oss ta, till exempel, den berömda torrent tracker rutracker.nl). När vi försöker komma åt en torrent trackers webbplats ser vi leverantörens standardstubb som indikerar att resursen är blockerad:

Domänfronting baserad på TLS 1.3

På RKN:s webbplats är denna domän faktiskt listad i stopplistorna:

Domänfronting baserad på TLS 1.3

När du frågar whois kan du se att själva domänen är "dold" bakom molnleverantören Cloudflare.

Domänfronting baserad på TLS 1.3

Men till skillnad från "specialisterna" från RKN förbjöd inte mer tekniskt kunniga anställda från Beeline (eller undervisade av den bittra erfarenheten från vår berömda regulator) webbplatsen med IP-adress, utan lade till domännamnet till stopplistan. Du kan enkelt verifiera detta om du tittar på vilka andra domäner som är gömda bakom samma IP-adress, besöker en av dem och ser att åtkomsten inte är blockerad:

Domänfronting baserad på TLS 1.3

Hur går det till? Hur vet leverantörens DPI vilken domän min webbläsare är på, eftersom all kommunikation sker via https-protokollet och vi ännu inte har märkt att Beeline har bytt ut https-certifikat? Är han klärvoajant eller blir jag förföljd?

Låt oss försöka svara på denna fråga genom att titta på trafiken genom wireshark

Domänfronting baserad på TLS 1.3

Skärmdumpen visar att först hämtar webbläsaren serverns IP-adress via DNS, sedan sker en vanlig TCP-handskakning med destinationsservern, och sedan försöker webbläsaren upprätta en SSL-anslutning med servern. För att göra detta skickar den ett SSL Client Hello-paket, som innehåller namnet på källdomänen i klartext. Det här fältet krävs av cloudflares frontend-server för att dirigera anslutningen korrekt. Det är här leverantören DPI fångar oss och bryter vår anslutning. Samtidigt får vi ingen slump från leverantören, och vi ser standardwebbläsarfelet som om sidan är inaktiverad eller helt enkelt inte fungerar:

Domänfronting baserad på TLS 1.3

Låt oss nu aktivera eSNI-mekanismen i webbläsaren, som skrivet i instruktionerna för firefox :
För att göra detta öppnar vi Firefox konfigurationssida about: config och aktivera följande inställningar:

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

Efter detta kommer vi att kontrollera att inställningarna fungerar korrekt på cloudflares webbplats. länk och låt oss prova tricket med vår torrent tracker igen.

Domänfronting baserad på TLS 1.3

Voila. Vår favoritspårare öppnades utan VPN eller proxyservrar. Låt oss nu titta på trafikdumpen i wireshark för att se vad som hände.

Domänfronting baserad på TLS 1.3

Den här gången innehåller ssl-klienten hello-paketet inte uttryckligen destinationsdomänen, utan istället dök ett nytt fält upp i paketet - encrypted_server_name - det är här värdet av rutracker.nl finns, och endast cloudflares frontend-server kan dekryptera detta fält. Och i så fall har leverantören DPI inget annat val än att tvätta händerna och tillåta sådan trafik. Det finns inga andra alternativ med kryptering.

Så vi tittade på hur tekniken fungerar i webbläsaren. Låt oss nu försöka tillämpa det på mer specifika och intressanta saker. Och först kommer vi att lära samma curl att använda eSNI för att arbeta med TLS 1.3, och samtidigt kommer vi att se hur den eSNI-baserade domänfronten själv fungerar.

Domänfronting med eSNI

På grund av det faktum att curl använder standard openssl-biblioteket för att ansluta via https-protokollet, måste vi först och främst tillhandahålla eSNI-stöd där. Det finns inget eSNI-stöd i openssl-mastergrenarna ännu, så vi måste ladda ner en speciell openssl-gren, kompilera och installera den.

Vi klonar förvaret från GitHub och kompilerar som vanligt:

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

$ make
$ cd esnistuff
$ make

Därefter klonar vi förvaret med curl och konfigurerar dess kompilering med vårt kompilerade openssl-bibliotek:

$ 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

Här är det viktigt att korrekt specificera alla kataloger där openssl finns (i vårt fall är detta /opt/openssl/) och se till att konfigurationsprocessen går igenom utan fel.

Om konfigurationen lyckas kommer vi att se raden:

VARNING: esni ESNI aktiverat men märkt EXPERIMENTAL. Använd med försiktighet!

$ make

Efter att ha lyckats bygga paketet kommer vi att använda en speciell bash-fil från openssl för att konfigurera och köra curl. Låt oss kopiera den till katalogen med curl för enkelhetens skull:

cp /opt/openssl/esnistuff/curl-esni 

och gör en test https-förfrågan till cloudflare-servern, samtidigt som du spelar in DNS- och TLS-paket i Wireshark.

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

I serversvaret kommer vi, förutom en hel del felsökningsinformation från openssl och curl, att få ett HTTP-svar med kod 301 från 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/

vilket indikerar att vår begäran levererades till destinationsservern, hördes och behandlades.

Låt oss nu titta på trafikdumpen i wireshark, d.v.s. vad leverantören DPI såg i det här fallet.

Domänfronting baserad på TLS 1.3

Det kan ses att curl först vände sig till DNS-servern för en offentlig eSNI-nyckel för cloudflare-servern - en TXT DNS-förfrågan till _esni.cloudflare.com (paket nr 13). Sedan, med hjälp av openssl-biblioteket, skickade curl en TLS 1.3-förfrågan till cloudflare-servern där SNI-fältet krypterats med den publika nyckeln som erhölls i föregående steg (paket #22). Men förutom eSNI-fältet inkluderade SSL-hello-paketet också ett fält med det vanliga - öppna SNI, som vi kan specificera i valfri ordning (i det här fallet - www.hello-rkn.ru).

Detta öppna SNI-fält togs inte i beaktande på något sätt när det bearbetades av cloudflare-servrar och fungerade endast som en mask för leverantörens DPI. Cloudflare-servern tog emot vårt ssl-hello-paket, dekrypterade eSNI, extraherade det ursprungliga SNI därifrån och bearbetade det som om ingenting hade hänt (den gjorde allt precis som planerat när eSNI utvecklades).

Det enda som kan fångas i det här fallet från en DPI-synpunkt är den primära DNS-förfrågan till _esni.cloudflare.com. Men vi gjorde DNS-förfrågan öppen endast för att visa hur den här mekanismen fungerar från insidan.

För att slutligen dra ut mattan från under DPI använder vi den redan nämnda DNS-over-HTTPS-mekanismen. En liten förklaring - DOH är ett protokoll som låter dig skydda dig mot en man-in-the-middle-attack genom att skicka en DNS-förfrågan över HTTPS.

Låt oss köra begäran igen, men den här gången kommer vi att få offentliga eSNI-nycklar via https-protokollet, inte DNS:

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

Trafikdumpen för begäran visas i skärmdumpen nedan:

Domänfronting baserad på TLS 1.3

Det kan ses att curl först kommer åt mozilla.cloudflare-dns.com-servern via DoH-protokollet (https-anslutning till server 104.16.249.249) för att erhålla värdena för offentliga nycklar för SNI-kryptering från dem och sedan till destinationen server, gömmer sig bakom domänen www.hello-rkn.ru.

Förutom ovanstående DoH-resolver mozilla.cloudflare-dns.com kan vi använda andra populära DoH-tjänster, till exempel från det berömda onda företaget.
Låt oss köra följande fråga:

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

Och vi får svaret:

< 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

Domänfronting baserad på TLS 1.3

I det här fallet vände vi oss till den blockerade rutracker.nl-servern med hjälp av DoH-resolvern dns.google (det finns inget stavfel här, nu har det berömda företaget sin egen förstanivådomän) och täckte oss med en annan domän, som är strikt förbjudet för alla DPI:er att blockera under dödsstraff. Baserat på det mottagna svaret kan du förstå att vår begäran behandlades framgångsrikt.

Som en ytterligare kontroll av att leverantörens DPI svarar på den öppna SNI, som vi sänder som ett skydd, kan vi göra en begäran till rutracker.nl under täckmantel av någon annan förbjuden resurs, till exempel en annan "bra" torrent-spårare:

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

Vi kommer inte att få något svar från servern, eftersom... vår begäran kommer att blockeras av DPI-systemet.

En kort avslutning på första delen

Så vi kunde demonstrera funktionaliteten hos eSNI med openssl och curl och testa driften av domänfronting baserat på eSNI. På samma sätt kan vi anpassa våra favoritverktyg som använder openssl-biblioteket för att fungera "under täckmantel" av andra domäner. Mer information om detta i våra nästa artiklar.

Källa: will.com

Lägg en kommentar