DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Inledning

I den första delen Artikel Vi har gett en kort beskrivning av den krypterade SNI-mekanismen (eSNI). De visade hur det kan anvÀndas för att undvika upptÀckt av moderna DPI-system (med hjÀlp av exemplet Beelines DPI och rutrackern som förbjudits av RKN), och undersökte Àven en ny version av domÀnfronting baserad pÄ denna mekanism.

I den andra delen av artikeln gÄr vi vidare till mer praktiska saker som kommer att vara anvÀndbara för RedTeam-specialister i deras svÄra arbete. VÄrt mÄl Àr trots allt inte att fÄ tillgÄng till blockerade resurser (för sÄdana triviala saker har vi en gammaldags VPN). Lyckligtvis finns det, som man brukar sÀga, mÄnga VPN-leverantörer för varje smak, fÀrg och budget.

Vi kommer att försöka tillÀmpa domÀnfronteringsmekanismen pÄ moderna RedTeam-verktyg, sÄsom Cobalt Strike, Empire, etc., och ge dem ytterligare funktioner för mimik och kringgÄende av moderna innehÄllsfiltreringssystem.

Förra gĂ„ngen implementerade vi eSNI-mekanismen i OpenSSL-biblioteket och anvĂ€nde den framgĂ„ngsrikt i det vĂ€lbekanta curl-verktyget. Men, som man sĂ€ger, man kan inte leva bara pĂ„ kurla. SjĂ€lvklart skulle jag vilja implementera nĂ„got liknande i högnivĂ„sprĂ„k. Men tyvĂ€rr gör en snabb sökning genom nĂ€tverkets vidstrĂ€ckta nĂ€tverk oss besvikna, eftersom stöd för eSNI-mekanismen endast Ă€r fullt implementerat i GOLANG. SĂ„ vi har inte mycket att vĂ€lja mellan: antingen skriver vi i ren C eller C++ med hjĂ€lp av det uppdaterade OpenSSL-biblioteket, eller sĂ„ anvĂ€nder vi en separat förgrening av GOLANG frĂ„n CloudFlare och försöker porta vĂ„r verktygslĂ„da dit. I princip finns det ett annat alternativ, mer klassiskt, men samtidigt arbetskrĂ€vande – det Ă€r att implementera eSNI-stöd för Python. Python anvĂ€nder ju trots allt Ă€ven OpenSSL för att hantera https. Men vi lĂ€mnar det hĂ€r alternativet Ă„t nĂ„gon annan att utveckla, och vi sjĂ€lva kommer att vara nöjda med implementeringen pĂ„ Golang, sĂ€rskilt eftersom vĂ„r Ă€lskade Cobalt Strike Ă€r fullt kapabel att arbeta med en kommunikationskanal byggd av tredjepartsmedel (Extern C2-kanal) - vi kommer att prata om detta i slutet av artikeln.

Försök hĂ„rdare


Ett av verktygen som implementerats i Go Àr vÄr utveckling för att koppla in sig i nÀtverket - tunneler rsockstun, som för övrigt nu upptÀcks av Microsoft och Symantec som mycket skadlig programvara som syftar till att störa den globala stabiliteten...

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Det vore bra att anvĂ€nda den tidigare utvecklingen Ă€ven i detta fall. Men hĂ€r uppstĂ„r ett litet problem. PoĂ€ngen Ă€r att rsockstun initialt innebĂ€r anvĂ€ndning av en synkron SSL-kommunikationskanal med servern. Det innebĂ€r att förbindelsen upprĂ€ttas en gĂ„ng och existerar under hela tunneldriften. Och, som du förstĂ„r, Ă€r https-protokollet egentligen inte utformat för detta driftsĂ€tt – det fungerar i request-response-lĂ€ge, dĂ€r varje ny http-förfrĂ„gan finns inom en ny tcp-anslutning.

Den största nackdelen med detta schema Àr att servern inte kan överföra data till klienten förrÀn klienten skickar en ny http-förfrÄgan. Men som tur Àr finns det mÄnga alternativ för att lösa detta problem - strömmande data via http-protokollet (vi lyckas ju trots allt pÄ nÄgot sÀtt titta pÄ vÄra favorit-TV-serier och lyssna pÄ musik frÄn portaler som fungerar pÄ https, och överföringen av video och ljud Àr inget annat Àn strömmande data). En av teknikerna för att emulera driften av en fullfjÀdrad TCP-anslutning över HTTP-protokollet Àr WebSockets-tekniken, vars huvudsakliga essens Àr att organisera en fullfjÀdrad nÀtverksanslutning mellan klienten och webbservern.

Som tur Àr för oss (hurra hurra!!!) ingÄr den hÀr tekniken som standard i alla CloudFlare-planer och fungerar utmÀrkt i kombination med eSNI. Det hÀr Àr precis vad vi kommer att anvÀnda för att lÀra vÄr tunnelerare att anvÀnda domÀnfronting och dölja sig frÄn modern DPI.

Lite om WebSockets

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

Web Socket-tekniken lĂ„ter dig tillfĂ€lligt vĂ€xla frĂ„n en http-anslutning till en vanlig strömmande dataöverföring via ett nĂ€tverksuttag utan att bryta den etablerade TCP-anslutningen. NĂ€r en klient vill byta till en webbsocket anger den flera http-rubriker i sin http-begĂ€ran. TvĂ„ obligatoriska rubriker Ă€r – Anslutning: Uppgradering Đž Uppgradering: websocket. Den kan ocksĂ„ tvĂ„ngsmĂ€ssigt ange websocket-protokollversionen (Sec-Websocket-version: 13) och nĂ„got liknande base64 websocket-identifierare (Sec-WebSocket-nyckel: DAGDJSiREI3+KjDfwxm1FA==). Servern svarar med http-koden 101 Switching Protocols och stĂ€ller Ă€ven in headern. Anslutning, Uppgradering Đž Sec-WebSocket-Acceptera. VĂ€xlingsprocessen visas tydligt pĂ„ skĂ€rmbilden nedan:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Efter detta kan installationen av WebSocket-anslutningen anses vara klar. All data frÄn bÄde klienten och servern kommer nu att levereras med WebSocket-rubriker istÀllet för http (de börjar med byte 0x82). Nu behöver servern inte vÀnta pÄ en begÀran frÄn klienten för att överföra data, eftersom tcp-anslutningen inte Àr bruten.

Golang har flera bibliotek för att arbeta med webbsockets. De mest populÀra av dem Àr Gorilla WebSocket och standard WebSocket. Vi kommer att anvÀnda det senare, eftersom det Àr enklare, mindre och fungerar, som man sÀger, lite snabbare.

I rsockstun-klientkoden mÄste vi ersÀtta net.dial- eller tls.dial-anropen med motsvarande WebSocket-anrop:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Vi vill göra klientdelen av vĂ„r tunnel universell och kapabel att fungera bĂ„de via en direkt SSL-anslutning och via WebSockset-protokollet. För detta skapar vi en separat funktion func connectForWsSocks(adressstrĂ€ng, proxystrĂ€ng) fel {
} i analogi med anslutFörStrumpor() och vi kommer att anvĂ€nda den för att arbeta med web sockets om serveradressen som anges nĂ€r klienten startas börjar med ws: eller wss: (i fallet med Secure WebSocket).

För serverdelen av tunneln kommer vi ocksÄ att skapa en separat funktion för att arbeta med web sockets. Den skapar en instans av http-klassen och stÀller in http-anslutningshanteraren (wsHandler-funktionen):

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Och vi kommer att placera all logik för att bearbeta anslutningen (klientautentisering med lösenord, installation och avslutning av yamux-sessionen) i WebSocket-anslutningshanteraren:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Vi kompilerar projektet och startar 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 arbetet pÄ den lokala vÀrden:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

GÄ vidare till domÀnfronting

Vi verkar ha listat ut webbsockets. Nu gÄr vi vidare till eSNI och domÀnfronting. Som tidigare nÀmnts, för att arbeta med DoH och eSNI behöver vi ta en sÀrskild gren av Golang frÄn företaget. CloudFlare. Vi behöver en filial med eSNI-stöd (pwu/esni).

Vi klonar den lokalt eller laddar ner och packar upp motsvarande zip-fil:

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

Sedan mĂ„ste vi kopiera GOROOT-katalogen, ersĂ€tta motsvarande filer frĂ„n den klonade grenen och stĂ€lla in den som huvudkatalogen. För att bespara utvecklaren detta besvĂ€r har killarna frĂ„n CloudFlare förberett ett speciellt skript – _dev/go.sh. Vi bara lanserar det. Skriptet tillsammans med makefilen kommer att göra allt sjĂ€lva. Av intresse kan du titta inuti makefilen för detaljer.

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

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

DÀrefter behöver vi implementera funktionen för att begÀra och analysera offentliga eSNI-nycklar för den önskade domÀnen i tunneln. I vÄrt fall kommer dessa att vara de kryptografiska eSNI-nycklarna frÄn CloudFlares frontend-servrar. För att göra 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)

Funktionernas namn talar i princip för sig sjÀlva. Vi tar innehÄllet frÄn filen esni_query.go, som Àr en del av tls-tris. Den första funktionen skapar ett nÀtverkspaket med en begÀran till CloudFlare DNS-servern med hjÀlp av DoH-protokollet (DNS-over-HTTPS), den andra analyserar frÄgeresultaten och hÀmtar vÀrdena för domÀnens publika nycklar, och den tredje Àr en behÄllare för de tvÄ första.

DĂ€refter lĂ€gger vi till funktionen web socket connection till vĂ„r nyskapade funktion. connectForWsSocks funktionalitet för att begĂ€ra eSNI-nycklar för en domĂ€n. DĂ€r serverdelen fungerar stĂ€ller vi in ​​TLS-parametrarna och anger Ă€ven namnet pĂ„ den falska "tĂ€ckdomĂ€nen":

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Det bör noteras hĂ€r att tls-tris-grenen initialt inte var utformad för anvĂ€ndning av domĂ€nfronting. DĂ€rför uppmĂ€rksammar den inte det falska servernamnet (ett tomt serverName-fĂ€lt överförs i client-hello-paketet). För att Ă„tgĂ€rda detta mĂ„ste vi lĂ€gga till motsvarande FakeServerName-fĂ€lt i TlsConfig-strukturen. Vi kan inte anvĂ€nda standardfĂ€ltet ServerName i strukturen eftersom det anvĂ€nds av interna tls-mekanismer och om det skiljer sig frĂ„n originalet kommer tls-handskakningen att avslutas med ett fel. Beskrivningen av TlsConfig-strukturen finns i filen tls/common.go – det hĂ€r Ă€r vad vi behöver korrigera:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

DomÀnfrontering 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 FakeServerName-fÀlt nÀr man skapar en TLS-handskakning:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Det Àr allt! Du kan sammanstÀlla projektet och kontrollera arbetet. Men innan du kör kontrollen mÄste du skapa ett CloudFlare-konto. Tja, hur kan jag sÀga att jag ska stÀlla in det? Skapa bara ett konto pÄ Cloudflare och lÀnka din domÀn till det. Alla DoH-, WebSocket- och ESNI-relaterade funktioner Àr aktiverade i CloudFlare som standard. NÀr DNS-posterna har uppdaterats kan du kontrollera domÀnens funktion genom att begÀra eSNI-nycklar:

dig +short txt _esni.df13tester.info 

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Om du ser nÄgot liknande för din domÀn, fungerar allt för dig och du kan gÄ vidare till testning.

Vi lanserar Ubuntu En VPS, till exempel, pÄ DigitalOcean. PS: I vÄrt fall hamnade VPS-IP-adressen vi just fÄtt frÄn vÄr leverantör pÄ Roskomnadzors svarta lista. SÄ bli inte förvÄnad om nÄgot liknande hÀnder dig. Jag var tvungen att anvÀnda en VPN för att komma Ät min VPS.

Vi kopierar den redan kompilerade rsockstun till VPS:en (förresten, detta Àr ytterligare en skönhet med Golang - du kan kompilera projektet sjÀlv och köra det pÄ vilken Linux som helst, bara med tanke pÄ systemets bitvÀrde) och startar serverdelen:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Och sedan klientdelen:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

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

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Nu ska vi se vad DPI ser i kommunikationskanalen:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Först kontaktar tunneleraren, med hjÀlp av DoH-mekanismen, Cloudflares DNS-server för eSNI-nycklar för destinationsdomÀnen (paket #1-19), och kontaktar sedan frontend-servern och upprÀttar en TLS-anslutning, gömd bakom domÀnen. www.google.com (Detta Àr standardvÀrdet nÀr ingen falsk domÀn anges nÀr klienten startas). För att ange din falska domÀn mÄste du anvÀnda parametern -fronfDomain:

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Nu en sak till. Som standard Àr dina CloudFalre-kontoinstÀllningar instÀllda pÄ Flexibelt SSL-lÀge. Det hÀr innebÀr att https-förfrÄgningar till Cloudflares frontend-servrar frÄn klienter kommer att vidarebefordras i okrypterad (http) form till vÄr server. Det Àr dÀrför vi lanserade serverdelen av tunneln i icke-SSL-lÀge ( -listen ws:0.0.0.0), och inte ( -listen wss:0.0.0.0).

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

För att vÀxla till fullstÀndigt krypteringslÀge mÄste du vÀlja full, eller FullstÀndig (strikt) om det finns ett riktigt certifikat pÄ servern. Efter att ha bytt lÀge kommer vi att kunna acceptera anslutningar frÄn CloudFlare via https-protokollet. Glöm inte att generera ett sjÀlvsignerat certifikat för serversidan av tunneln.

DomÀnfrontering baserat pÄ TLS 1.3. Del 2

Den nyfikne lĂ€saren kommer att frĂ„ga: ”Hur Ă€r det med klienten under Windows"Trots allt Ă€r den huvudsakliga anvĂ€ndningen av en tunneler förmodligen att upprĂ€tta en backend-anslutning frĂ„n företagsmaskiner och servrar, och det Ă€r vanligtvis alltid Windows. Hur kompilerar jag en tunneler för Windows, sĂ€rskilt med en specifik TLS-stack?" Nu ska vi introducera ytterligare en funktion som visar hur bekvĂ€mt Golang Ă€r. Vi kompilerar för Windows direkt frĂ„n Kali genom att helt enkelt lĂ€gga till parametern GOOS=windows:

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

Eller 32-bitarsversionen:

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

Alla! Och inget mer krÄngel behövs. Det hÀr fungerar verkligen!

DomÀnfrontering 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 körbara filen, vilket gör den ett par megabyte mindre. Dessutom kan den sedan paketeras med UPX för att ytterligare minska storleken.

I stÀllet för en slutsats

I den hĂ€r artikeln, med hjĂ€lp av exemplet med en tunnelerare skriven i Golang, demonstrerade vi tydligt anvĂ€ndningen av en ny domĂ€nfronteringsteknik, implementerad pĂ„ en ganska intressant funktion i TLS 1.3-protokollet. PĂ„ liknande sĂ€tt kan du anpassa befintliga verktyg skrivna i Golang för att fungera via CloudFlare-servrar, till exempel. Merlin — kĂ€nd C2, eller tvinga CobaltStrike Beacon att anvĂ€nda eSNI-domĂ€nfronting nĂ€r man arbetar med Teamserver via Extern C2-kanal, implementerad i Golang, eller i standard C++ med en uppdaterad version av OpenSSL, som vi pratade om i föregĂ„ende del av artikeln. I allmĂ€nhet finns det ingen grĂ€ns för fantasin.

Exemplet med tunneln och CloudFlare presenteras som ett koncept och det Ă€r svĂ„rt att sĂ€ga om de lĂ„ngsiktiga utsikterna för den hĂ€r typen av domĂ€nfronting. För nĂ€rvarande implementeras eSNI-stöd endast av CloudFlare och i teorin hindrar ingenting dem frĂ„n att inaktivera denna typ av fronting och till exempel bryta TLS-anslutningar nĂ€r SNI och eSNI inte matchar. NĂ„, framtiden fĂ„r utvisa det. Men för tillfĂ€llet ser utsikten att arbeta under "kremlin.ru:s tĂ€ckmantel" ganska lockande ut. Är det inte rĂ€tt?

Den uppdaterade tunnelerkoden, sÄvÀl som kompilerade körbara exe-filer, placeras i en separat gren av projektet pÄ github. Det Àr bÀttre att skriva ett Àrende om alla möjliga tunnelproblem pÄ projektsidan pÄ GitHub.

KĂ€lla: will.com

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