DomÀnfronting baserat pÄ TLS 1.3. Del 2

Introduktion

I den första delen artiklar gav vi en kort beskrivning av mekanismen encrypted SNI (eSNI). Vi visade hur den kan anvÀndas för att undvika upptÀckter av moderna DPI-system (med exempel pÄ Beeline DPI och den förbjudna RKN Tracker), samt att vi undersökte en ny variant av domÀn-fronting baserad pÄ denna mekanism.

I den andra delen av artikeln gÄr vi vidare till mer praktiska saker som kommer att vara till nytta för RedTeam-specialister i deras utmanande arbete. I slutÀndan Àr vÄrt mÄl inte att fÄ tillgÄng till blockerade resurser (för sÄdana banala saker har vi den gamla goda VPN). Det finns gott om VPN-leverantörer, som man sÀger, för varje smak, fÀrg och budget.

Vi kommer att försöka tillÀmpa mekanismen domÀn-fronting pÄ moderna RedTeam-verktyg, som Cobalt Strike, Empire osv., och ge dem ytterligare möjligheter till mimickring och undvikande av moderna innehÄllsfilter.

Förra gĂ„ngen implementerade vi mekanismen eSNI i OpenSSL-biblioteket och anvĂ€nde den framgĂ„ngsrikt i det bekanta verktyget curl. Men bara med curl, som man sĂ€ger, blir man inte mĂ€tt. Naturligtvis vill vi implementera nĂ„got liknande i högre nivĂ„sprĂ„k. Men tyvĂ€rr, en snabb sökning pĂ„ nĂ€tet gör oss besvikna eftersom stödet för mekanismen eSNI Ă€r fullt implementerat endast i GOLANG. DĂ€rför har vi inte mycket att vĂ€lja pĂ„: antingen skriver vi i rent C eller C++ med hjĂ€lp av det patchade OpenSSL-biblioteket, eller sĂ„ anvĂ€nder vi en separat fork av GOLANG frĂ„n CloudFlare och försöker portera vĂ„rt verktyg dit. I princip finns det ett annat, mer klassiskt men samtidigt arbetskrĂ€vande alternativ – att implementera stöd för eSNI för Python. I slutĂ€ndan anvĂ€nder Python ocksĂ„ OpenSSL för att arbeta med https. Men detta alternativ lĂ€mnar vi till nĂ„gon annan att utveckla, medan vi nöjer oss med implementationen i golang, sĂ€rskilt eftersom vĂ„r Ă€lskade Cobalt Strike Ă€r bra pĂ„ att anvĂ€nda kommunikationskanaler som byggs med tredjepartsmaterial (External C2 channel) – detta kommer vi att berĂ€tta mer om i slutet av artikeln.

Try Harder


Ett av de Go-verktyg vi har implementerat – vĂ„r utveckling för pivoting in i nĂ€tverket – tunneln rsockstun, som för övrigt numera identifieras av Microsofts och Symantecs verktyg som mycket skadlig programvara som syftar till att störa den globala stabiliteten


DomÀnfronting baserat pÄ TLS 1.3. Del 2

Det skulle vara bra att anvĂ€nda den tidigare utvecklingen Ă€ven i det hĂ€r fallet. Men det finns ett litet problem. Det handlar om att rsockstun ursprungligen förutsĂ€tter anvĂ€ndning av en synkron SSL-koppling till servern. Detta innebĂ€r att anslutningen etableras en gĂ„ng och finns kvar under hela tunneleens driftstid. Och som ni förstĂ„r Ă€r https-protokollet inte riktigt designat för ett sĂ„dant arbetslĂ€ge – det fungerar i en begĂ€rs-svar-mod, dĂ€r varje ny http-begĂ€ran existerar inom ramen för en ny tcp-anslutning.

Den största nackdelen med detta system Ă€r att servern inte kan skicka data till klienten innan klienten skickar en ny http-begĂ€ran. Men lyckligtvis finns det mĂ„nga alternativ för att lösa detta problem – strömmande data via http-protokollet (i slutĂ€ndan lyckas vi ju pĂ„ nĂ„got sĂ€tt se vĂ„ra favoritserier och lyssna pĂ„ musik frĂ„n plattformar som kör pĂ„ https, och överföring av video och ljud Ă€r inget annat Ă€n strömmande data). En av teknologierna för att emulera ett fullstĂ€ndigt tcp-anslutning ovanpĂ„ http-protokollet Ă€r WebSockets-teknologin, vars huvudsyfte Ă€r att organisera en fullstĂ€ndig nĂ€tverksanslutning mellan klienten och webbservern.

Till vÄr lycka (hurra!!!), denna teknologi Àr aktiverad som standard i alla CloudFlare-abonnemang och fungerar utmÀrkt tillsammans med eSNI. Det Àr just den vi kommer att anvÀnda för att lÀra vÄr tunnel att anvÀnda domÀn-framÄtsikt och dölja sig för moderna DPI.

Lite om WebSockets

Först och frÀmst kommer vi kortfattat och med enkla ord att förklara vad web sockets Àr, sÄ att alla har en uppfattning om vad vi kommer att arbeta med.

WebSockets-teknologin möjliggör tillfÀllig vÀxling frÄn http-anslutning till standard strömmande data via nÀtverksocket, utan att bryta den etablerade tcp-anslutningen. NÀr klienten vill vÀxla till web socket, lÀgger den till nÄgra http-header i sin http-begÀran. TvÄ obligatoriska huvuden Àr Connection: Upgrade och Upgrade: websocket. Den kan ocksÄ specificera versionen av websocket-protokollet tvingat (Sec-Websockset-Version: 13) och nÄgot som liknar base64-identifierare för webbsocketen (Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==). Servern svarar med http-kod 101 Switching Protocols och sÀtter Àven headers Connection, Upgrade och Sec-WebSocket-Accept. Processen för omkoppling visas tydligt pÄ skÀrmdumpen nedan:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Efter detta kan WebSocket-anslutningen anses vara komplett. Alla data, bÄde frÄn klienten och servern, kommer nu att levereras med WebSocket-headers (de börjar med byte 0x82). Nu behöver inte servern vÀnta pÄ en begÀran frÄn klienten för att skicka data, eftersom tcp-anslutningen inte bryts.

I Go finns det flera bibliotek för att arbeta med websockets. De mest populÀra av dem Àr Gorilla WebSocket och standardbiblioteket WebSocket. Vi kommer att anvÀnda det senare, eftersom det Àr enklare, mindre och fungerar, som sagt, lite snabbare.

I klientkoden för rsockstun mÄste vi byta ut anrop av net.dial eller tls.dial mot motsvarande WebSocket-anrop:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Vi vill göra klientdelen av vĂ„r tunnelerare universell och kunna arbeta bĂ„de via en direkt ssl-anslutning och via WebSocket-protokollet. För detta kommer vi att skapa en separat funktion func connectForWsSocks(address string, proxy string) error {
} i analogi med connectForSocks() och anvĂ€nda den för att arbeta med websockets om serveradressen som angavs vid klientstarten börjar med ws: eller wss: (i fallet med Secure WebSocket).

För serverdelen av tunneleraren kommer vi ocksÄ att göra en separat funktion för att arbeta med websockets. DÀr kommer en instans av http-klassen att skapas och http-anslutningens hanterare (funktionen wsHandler) stÀllas in:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Och all logik för att hantera anslutningen (autorisering av klienten med lösenord, upprÀttande och avslutande av yamux-sessionen) kommer att placeras i WebSocket-anslutningens hanterare:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Vi kompilerar projektet och kör serverdelen:

.\/rsockstun –listen ws:127.0.0.1:8080 –pass P@ssw0rd

Och sedan klientdelen:

.\/rsockstun -connect ws:127.0.0.1:8080 –pass P@ssw0rd

Och vi kontrollerar funktionen pÄ den lokala vÀrden:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

DomÀnfronting baserat pÄ TLS 1.3. Del 2

LÄt oss gÄ vidare till domÀn-fronting

Med websockets verkar vi ha förstÄtt. Nu lÄt oss gÄ direkt till eSNI och domÀn-fronting. Som nÀmnts tidigare, för att arbeta med DoH och eSNI behöver vi ta en speciell Go-gren frÄn företaget CloudFlare. Vi behöver en gren med stöd för eSNI (pwu/esni).

Klona den lokalt eller ladda ner och packa upp motsvarande zip-fil:

git clone -b pwu/esni https://github.com/cloudflare/tls-tris.git

DĂ€refter behöver vi kopiera katalogen GOROOT, byta ut motsvarande filer frĂ„n den klonade grenen och stĂ€lla in den som huvud. För att avlasta utvecklaren har killarna pĂ„ CloudFlare förberett ett speciellt skript – _dev/go.sh. Vi kör bara det. Skriptet tillsammans med makefile kommer att göra allt sjĂ€lv. För intressets skull – ni kan titta inuti makefile för detaljer.

Efter att skriptet har körts, nÀr vi kompilerar projektet, mÄste vi ange den lokala katalogen som GOROOT, som förberetts av skriptet. I vÄrt fall ser det ut sÄ hÀr:

GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" go build 
.

Vidare behöver vi implementera i tunneln funktionen för att begÀra och parsa publika eSNI-nycklar för den aktuella domÀnen. I vÄrt fall kommer detta att vara de publika eSNI-nycklarna frÄn CloudFlare:s frontendservrar. För detta kommer vi att skapa tre funktioner:

func makeDoTQuery(dnsName string) ([]byte, error)
func parseTXTResponse(buf []byte, wantName string) (string, error)
func QueryESNIKeysForHost(hostname string) ([]byte, error)

Funktionsnamnen sĂ€ger i princip sig sjĂ€lva. Fyllningen kommer vi att ta frĂ„n filen esni_query.go, som ingĂ„r i tls-tris. Den första funktionen skapar ett nĂ€tverkspaket med en begĂ€ran till CloudFlare:s DNS-server, som anvĂ€nder protokollet DoH (DNS-over-HTTPS), den andra – parsar begĂ€rans resultat och fĂ„r vĂ€rdena av de publika nycklarna för domĂ€nen, den tredje fungerar som en behĂ„llare för de tvĂ„ första.

DÀrefter lÀgger vi till i vÄr ny skapade funktion för att ansluta till websockets connectForWsSocks funktionen för att begÀra eSNI-nycklar för domÀnen. DÀr serverdelen fungerar stÀller vi in TLS-parametrarna, samt anger namnet pÄ det falska "skyddsapplikationsdomÀnen":

DomÀnfronting baserat pÄ TLS 1.3. Del 2

HĂ€r bör vi notera att den ursprungliga gren av tls-tris inte Ă€r avsedd för anvĂ€ndning av domĂ€nfronting. Följaktligen tillĂ€gnas inte ett falskt servernamn (i klient-hello-paketet skickas ett tomt serverName-fĂ€lt). För att Ă„tgĂ€rda detta mĂ„ste vi lĂ€gga till det motsvarande fĂ€ltet FakeServerName i strukturen TlsConfig. Vi kan inte anvĂ€nda det standardmĂ€ssiga ServerName-fĂ€ltet i strukturen, eftersom det anvĂ€nds av interna TLS-mekanismer och om det skiljer sig frĂ„n det ursprungliga, kommer TLS-handshaken att avslutas med ett fel. Beskrivningen av strukturen TlsConfig finns i filen tls/common.go – den mĂ„ste vi justera:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Dessutom mÄste vi göra Àndringar i filen tls/handshake_client.go, för att anvÀnda vÄrt fÀlt FakeServerName vid bildandet av TLS-handskake:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Det Ă€r allt! Du kan kompilera projektet och kontrollera dess funktion. Men innan du kör kontrollerna mĂ„ste du konfigurera ditt CloudFlare-konto. Hur man sĂ€ger, konfigurera – bara skapa ett konto pĂ„ CloudFlare och koppla din domĂ€n till det. Alla funktioner relaterade till DoH, WebSocket och ESNI Ă€r aktiverade i CloudFlare som standard. Efter att DNS-posterna har uppdaterats kan du kontrollera att din domĂ€n fungerar genom att göra en förfrĂ„gan om eSNI-nycklar:

dig +short txt _esni.df13tester.info 

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Om du ser nĂ„got liknande för din domĂ€n – betyder det att allt fungerar och du kan gĂ„ vidare till testningen.

Starta Ubuntu VPS, till exempel pÄ DigitalOcean. P.S. I vÄrt fall visade sig den just tilldelade IP-adressen frÄn leverantören vara pÄ RKN:s svartlista. SÄ bli inte förvÄnad om nÄgot liknande hÀnder dig. Vi var tvungna att anvÀnda VPN för att komma in pÄ vÄr VPS.

Kopiera den redan kompilerade rsockstun till VPS (förresten, det Ă€r Ă€nnu en fördel med Go – du kan kompilera projekt pĂ„ din egen maskin och köra det pĂ„ vilken Linux som helst, sĂ„ lĂ€nge du följer systemets arkitektur) och starta serverdelen:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Och sedan klientdelen:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Som vi ser har klienten framgÄngsrikt anslutit till servern via CloudFlares frontend-server med hjÀlp av WebSocket. För att kontrollera att tunneln verkligen fungerar som en tunnel kan du göra en curl-förfrÄgan genom den lokala socks5 som Àr öppen pÄ servern:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

LÄt oss nu se vad DPI ser i kommunikationskanalen:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Först konsulterar tunneln, med hjÀlp av DoH-mekanismen, CloudFlares DNS-server för eSNI-nycklar för destinationdomÀnen (paket nr 1-19), och sedan kontaktar den frontend-servern och etablerar en TLS-anslutning, och döljer sig bakom domÀnen www.google.com (detta Àr standardvÀrdet nÀr ingen falsk domÀn anges vid klientens start). För att ange din egen falska domÀn mÄste du anvÀnda parametern -fronfDomain:

DomÀnfronting baserat pÄ TLS 1.3. Del 2

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Nu Àr det en sak till. Som standard Àr instÀllningen för kontot pÄ CloudFlare i lÀget Flexible SSL. Det betyder att https-förfrÄgningar till CloudFlares frontend-servrar frÄn klienterna kommer att vidarebefordras i okrypterad (http) form till vÄr server. DÀrför körde vi serverdelen av tunneln i non-ssl-lÀge (-listen ws:0.0.0.0), snarare Àn (-listen wss:0.0.0.0).

DomÀnfronting baserat pÄ TLS 1.3. Del 2

För att vÀxla till lÀget med full kryptering mÄste du vÀlja Full, eller Full (strict) i fall med den aktuella certifikatet pÄ servern. Efter att ha vÀxlat lÀge kan vi ta emot anslutningar frÄn CloudFlare via https-protokollet. Glöm inte att generera ett self-signed certifikat för serverdelen av tunneln.

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Den nyfikna lÀsaren kanske frÄgar: "Vad sÀgs om klienten för Windows? Det Àr ju sÀkert sÄ att den huvudsakliga anvÀndningen av tunneln Àr att etablera backconnect frÄn företagsdatorer och servrar, och dÀr Àr det som regel alltid Windows. Hur kan jag kompilera tunneln för Windows, och dessutom med en specifik TLS-stack?" LÄt oss nu presentera en annan funktion som visar hur praktisk Go Àr. Vi kompilera för Windows direkt frÄn Kali, helt enkelt genom att lÀgga till parametern GOOS=windows:

GOARCH=amd64 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows  go build -ldflags="-s -w"

Eller den 32-bitars varianten:

GOARCH=386 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows  go build -ldflags="-s -w"

Det Àr klart! Och inga fler komplicerade grejer behövs. Det fungerar verkligen!

DomÀnfronting baserat pÄ TLS 1.3. Del 2

Kompilatorflaggorna -w och -s behövs för att ta bort onödigt skrÀp frÄn den exekverbara filen, vilket gör den mindre med ett par megabyte. Den kan dessutom packas med hjÀlp av UPX för att ytterligare minska storleken.

Avslutande

I artikeln visade vi, med exemplet av en tunneler skriven i Go, tydligt tillĂ€mpningen av den nya teknologin domĂ€n-framtrĂ€dande, som implementerades pĂ„ en ganska intressant egenskap hos protokollet TLS 1.3. PĂ„ samma sĂ€tt kan man anpassa existerande verktyg skrivna i Go för att arbeta genom CloudFlare-servrar, till exempel Merlin — en kĂ€nd C2, eller fĂ„ CobaltStrike Beacon att anvĂ€nda eSNI domĂ€n-framtrĂ€dande nĂ€r man arbetar med Teamserver via External C2 Channel, implementerad i Go, eller pĂ„ standard C++ med en patchad version av OpenSSL, som vi berĂ€ttade om i den föregĂ„ende delen av artikeln. SĂ„, fantasin har inga grĂ€nser.

Exemplet med tunneln och CloudFlare presenteras som ett koncept och det Àr fortfarande svÄrt att sÀga nÄgot om de lÄngsiktiga perspektiven för denna typ av domÀn-framtrÀdande. För nÀrvarande Àr stöd för eSNI endast implementerat av CloudFlare och, i teorin, hindrar inget dem frÄn att stÀnga av denna typ av framtrÀdande och till exempel bryta tls-anslutningar vid oöverensstÀmmelse mellan SNI och eSNI. Framtiden fÄr utvisa. Men för tillfÀllet verkar utsikten att arbeta under "skyddet av kremlin.ru" ganska lockande. Visst?

Den uppdaterade tunnelkoden samt de kompilerade exekverbara exe-filerna finns i en separat gren av projektet pÄ github. För alla potentiella problem med tunneln Àr det bÀttre att skriva issue pÄ projektets sida pÄ GitHub.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster