Domain fronting TLS 1.3 alapján. 2. rész

Bevezetés

Az első részben Cikk Rövid leírást adtunk a titkosított SNI (eSNI) mechanizmusról. Bemutatták, hogy ennek alapján hogyan lehet elkerülni a modern DPI-rendszerek észlelését (a Beeline DPI és a betiltott RKN gyökérkövető példáján), valamint megvizsgálták a domain fronting ezen a mechanizmuson alapuló új verzióját is.

A cikk második részében áttérünk a gyakorlatiasabb dolgokra, amelyek a RedTeam szakemberei számára hasznosak lesznek nehéz munkájuk során. Végül is nem az a célunk, hogy hozzáférjünk a blokkolt erőforrásokhoz (ilyen triviális dolgokra a jó öreg VPN-ünk van). Szerencsére nagyon sokféle VPN-szolgáltató létezik, ahogy mondják, minden ízléshez, színhez és pénztárcához.

Megpróbáljuk alkalmazni a domain-fronting mechanizmust a modern RedTeam eszközökre, például a Cobalt Strike-re, az Empire-re stb., és további lehetőségeket biztosítunk számukra a modern tartalomszűrő rendszerek utánozásához és elkerüléséhez.

Legutóbb az eSNI mechanizmust implementáltuk az OpenSSL könyvtárba, és sikeresen alkalmaztuk az ismert curl segédprogramban. De ahogy mondják, nem leszel elégedett egyetlen csirkével. Természetesen valami hasonlót szeretnék megvalósítani magas szintű nyelveken is. Sajnos azonban az interneten végzett gyors keresés csalódást okoz nekünk, mivel az eSNI-mechanizmus támogatása teljes mértékben csak a GOLANG-ban van megvalósítva. Így nincs sok választásunk: vagy tiszta C-ben vagy C++-ban írunk a javított OpenSSL-könyvtár segítségével, vagy a CloudFlare-ből külön GOLANG forkot használunk, és megpróbáljuk oda portolni az eszközeinket. Elvileg van egy másik lehetőség, klasszikusabb, de ugyanakkor időigényes - az eSNI-támogatás megvalósítása a Python számára. Végül is a Python OpenSSL-t is használ a https kezelésére. De ezt a lehetőséget meghagyjuk valaki más fejlesztésére, és mi magunk is elégedettek leszünk a Golang-i megvalósítással, különösen azért, mert szeretett Cobalt Strike-unk tökéletesen képes együttműködni egy harmadik féltől származó eszközökkel épített kommunikációs csatornával (Külső C2 csatorna) - erről a cikk végén fogunk beszélni.

Próbáld keményebben...

A Go-ban megvalósított egyik eszközünk a hálózatba való kapcsolódást szolgáló fejlesztésünk – egy alagút rsockstun, amelyet egyébként a Microsoft és a Symantec eszközei most nagyon rosszindulatú szoftverként észlelnek, amelynek célja a globális stabilitás megzavarása...

Domain fronting TLS 1.3 alapján. 2. rész

Ebben az esetben is jó lenne az előző fejlesztést használni. De itt felmerül egy kis probléma. A helyzet az, hogy kezdetben az rsockstun egy szinkron SSL kommunikációs csatorna használatát jelenti a szerverrel. Ez azt jelenti, hogy a kapcsolat egyszer jön létre, és az alagút működésének teljes időtartama alatt fennáll. És amint érti, a https protokoll nem erre a működési módra készült - kérés-válasz módban működik, ahol minden új http kérés egy új TCP-kapcsolaton belül létezik.

Ennek a sémának a fő hátránya, hogy a szerver nem tud adatot továbbítani a kliensnek, amíg az ügyfél nem küld egy új http kérést. De szerencsére számos lehetőség kínálkozik a probléma megoldására - adatfolyamok továbbítása a http protokollon keresztül (végül is valahogy sikerül megnéznünk kedvenc tévéműsorainkat és zenét hallgatni https-en futó portálokról, de a kép és hang továbbítása nem más mint adatfolyam). A teljes értékű TCP kapcsolat HTTP protokollon keresztüli működésének emulálásának egyik technológiája a WebSockets technológia, amelynek fő lényege a teljes értékű hálózati kapcsolat megszervezése a kliens és a webszerver között.

Szerencsére (hurrá!!!) ez a technológia alapból minden CloudFlare tarifacsomagban benne van, és remekül működik az eSNI-vel kombinálva. Pontosan ez az, amit arra fogunk használni, hogy megtanítsuk alagútunknak a domain fronting használatát és a modern DPI-k elől való elrejtést.

Egy kicsit a WebSocketsről

Először is röviden és egyszerű szavakkal beszélünk a websocketekről, hogy mindenkinek legyen fogalma arról, mivel fogunk dolgozni.

A Websocket technológia lehetővé teszi, hogy ideiglenesen váltson át http kapcsolatról szabványos hálózati socket adatfolyamra anélkül, hogy megszakadna a létrehozott TCP-kapcsolat. Amikor egy kliens websocketre akar váltani, több http fejlécet állít be a http kérésébe. Két kötelező fejléc - Csatlakozás: Frissítés и Frissítés: websocket. Erőteljesen megadhatja a websocket protokoll verzióját is (Sec-Websockset-Verzió: 13) és valami, mint egy base64 websocket azonosító (Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==). A szerver a http kóddal 101 Switching Protocols válaszol neki, és beállítja a fejléceket is Csatlakozás, frissítés и Sec-WebSocket-Accept. A váltási folyamat jól látható az alábbi képernyőképen:

Domain fronting TLS 1.3 alapján. 2. rész

Ezt követően a WebSocket kapcsolat telepítése befejezettnek tekinthető. A klienstől és a szervertől származó adatok mostantól nem http, hanem WebSocket fejlécekkel lesznek ellátva (0x82 bájttal kezdődnek). Mostantól a szervernek nem kell várnia a kliens adatátviteli kérésére, mert A tcp kapcsolat nem szakadt meg.

A Golang számos könyvtárral rendelkezik a websocketekkel való munkavégzéshez. Közülük a legnépszerűbbek Gorilla WebSocket és szabványos WebSocket. Ez utóbbit fogjuk használni, mert... egyszerűbb, kisebb, és ahogy mondani szokás, kicsit gyorsabban is működik.

Az rsockstun klienskódban le kell cserélnünk a net.dial vagy tls.dial hívásokat a megfelelő WebSocket hívásokra:

Domain fronting TLS 1.3 alapján. 2. rész

Domain fronting TLS 1.3 alapján. 2. rész

Szeretnénk a klienst univerzálissá tenni alagútunk részévé és képessé tenni mind közvetlen SSL-kapcsolaton, mind a WebSockset protokollon keresztüli működésre. Ehhez külön függvényt hozunk létre func connectForWsSocks(címkarakterlánc, proxykarakterlánc) hiba {…} -vel analógiával connectForSocks() és akkor használjuk a web socketekkel való munkához, ha a kliens indításakor megadott szervercím ws: vagy wss: karakterekkel kezdődik (a Secure WebSocket esetén).

Az alagút szerveroldalára külön funkciót is készítünk a web socketekkel való munkavégzéshez. Létrehoz egy példányt a http osztályból, és beállítja a http kapcsolatkezelőt (wsHandler függvény):

Domain fronting TLS 1.3 alapján. 2. rész

És az összes kapcsolatfeldolgozási logikát (kliens hitelesítés jelszóval, yamux munkamenet beállítása és befejezése) a WebSocket kapcsolatkezelőben helyezzük el:

Domain fronting TLS 1.3 alapján. 2. rész

Összeállítjuk a projektet és elindítjuk a szerver részt:

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

És akkor az ügyfél rész:

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

És ellenőrizzük a munkát a helyi gazdagépen:

Domain fronting TLS 1.3 alapján. 2. rész

Domain fronting TLS 1.3 alapján. 2. rész

Térjünk át a domain frontingre

Úgy tűnik, kitaláltuk a websocketeket. Most térjünk át közvetlenül az eSNI-re és a domain frontingre. Mint korábban említettük, a DoH-val és az eSNI-vel való együttműködéshez speciális golang-ágat kell átvennünk a cégtől CloudFlare. Szükségünk van egy fiókra eSNI támogatással (pwu/esni).

Helyben klónozzuk, vagy letöltjük és kicsomagoljuk a megfelelő zip-et:

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

Ezután át kell másolnunk a GOROOT könyvtárat, le kell cserélnünk a megfelelő fájlokat a klónozott ágból, és be kell állítanunk masternek. Hogy megmentsék a fejlesztőt ettől a fejfájástól, a CloudFlare srácai egy speciális szkriptet készítettek - _dev/go.sh. Csak elindítjuk. A forgatókönyv a makefile-lel együtt mindent megcsinál magától. A móka kedvéért belenézhet a makefile-be a részletekért.

A szkript futtatása után a projekt összeállításakor a szkript által készített helyi könyvtárat GOROOT-ként kell megadnunk. A mi esetünkben így néz ki:

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

Ezután meg kell valósítanunk az alagútban a nyilvános eSNI-kulcsok kérésének és elemzésének funkcióját a kívánt tartományhoz. Esetünkben ezek nyilvános eSNI-kulcsok a CloudFlare frontend szervereiről. Ehhez három függvényt hozunk létre:

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

A függvények nevei elvileg magukért beszélnek. A tartalmat az esni_query.go fájlból fogjuk átvenni, amely a tls-tris része. Az első funkció a DoH (DNS-over-HTTPS) protokoll segítségével egy hálózati csomagot hoz létre a CloudFlare DNS-kiszolgálóhoz intézett kéréssel, a második elemzi a lekérdezés eredményeit és lekéri a tartomány nyilvános kulcsainak értékeit, a harmadik pedig egy konténer az első kettőnek.

Ezután websocket csatlakozást adunk az újonnan létrehozott funkciónkhoz connectForWsSocks funkcionalitás eSNI-kulcsok kéréséhez egy tartományhoz. Ahol a kiszolgáló rész működik, beállítjuk a TLS paramétereket, és beállítjuk a hamis „cover domain” nevét is:

Domain fronting TLS 1.3 alapján. 2. rész

Itt meg kell jegyezni, hogy kezdetben a tls-tris ágat nem tartományfront használatára tervezték. Ezért nem figyel a hamis szervernévre (a client-hello csomag részeként egy üres serverName mezőt küld). Ennek kijavításához hozzá kell adnunk a megfelelő FakeServerName mezőt a TlsConfig struktúrához. Nem használhatjuk a struktúra szabványos ServerName mezőjét, mert a belső tls mechanizmusok használják, és ha eltér az eredetitől, a tls kézfogás hibával végződik. A TlsConfig szerkezet leírása a fájlban található tls/common.go - javítanunk kell:

Domain fronting TLS 1.3 alapján. 2. rész

Domain fronting TLS 1.3 alapján. 2. rész

Ezenkívül módosítanunk kell a fájlt tls/handshake_client.goa FakeServerName mező használatához TLS-kézfogás létrehozásakor:

Domain fronting TLS 1.3 alapján. 2. rész

Ez minden! Összeállíthatja a projektet és ellenőrizheti a munkát. A vizsgálat futtatása előtt azonban be kell állítania egy CloudFlare-fiókot. Nos, hogy is mondjam, állítsa be – csak hozzon létre egy fiókot a cloudflare-en, és kapcsolja össze a domainjét. A DoH-hoz, a WebSockethez és az ESNI-hez kapcsolódó összes szolgáltatás alapértelmezés szerint benne van a CloudFlare-ben. A DNS rekordok frissítése után az eSNI kulcsok lekérdezésével ellenőrizheti a tartomány működését:

dig +short txt _esni.df13tester.info 

Domain fronting TLS 1.3 alapján. 2. rész

Ha valami hasonlót lát a domainjében, az azt jelenti, hogy minden működik az Ön számára, és folytathatja a tesztelést.

Dob Ubuntu Egy VPS, például a DigitalOcean-en. Ui.: A mi esetünkben a szolgáltatónktól kapott VPS IP-cím felkerült a Roskomnadzor feketelistájára. Szóval ne lepődj meg, ha veled is valami hasonló történik. Nekem VPN-t kellett használnom a VPS-em eléréséhez.

A már lefordított rsockstunt átmásoljuk a VPS-re (ez egyébként a Golang másik szépsége - a projektet önállóan is lefordíthatja, és bármilyen Linuxon futtathatja, csak a rendszer bitkapacitását figyelve), és elindítjuk a szerver részt:

Domain fronting TLS 1.3 alapján. 2. rész

És akkor az ügyfél rész:

Domain fronting TLS 1.3 alapján. 2. rész

Amint látjuk, a kliens sikeresen csatlakozott a szerverhez a CloudFlare frontend szerveren keresztül egy websocket segítségével. Ha ellenőrizni szeretné, hogy az alagút pontosan úgy működik-e, mint egy alagút, akkor a kiszolgálón megnyitott helyi socks5-en keresztül hajtogatási kérelmet küldhet:

Domain fronting TLS 1.3 alapján. 2. rész

Lássuk, mit lát a DPI a kommunikációs csatornában:

Domain fronting TLS 1.3 alapján. 2. rész

Először az alagút a DoH-mechanizmus segítségével felveszi a kapcsolatot a Cloudflare DNS-kiszolgálóval a céltartomány eSNI-kulcsaiért (1-19. számú csomag), majd felveszi a kapcsolatot a frontend szerverrel, és a tartomány mögé bújva TLS-kapcsolatot hoz létre. www.google.com (ez az alapértelmezett érték, ha a kliens indításakor nincs megadva hamis tartomány). A hamis domain megadásához a -fronfDomain paramétert kell használnia:

Domain fronting TLS 1.3 alapján. 2. rész

Domain fronting TLS 1.3 alapján. 2. rész

Most még egy dolog. Alapértelmezés szerint a CloudFalre-fiók beállításai Rugalmas SSL-re vannak állítva. Ez azt jelenti, hogy az ügyfelektől a Cloudflare frontend szervereihez intézett https-kérelmek titkosítatlanul (http) kerülnek továbbításra szerverünkre. Ezért indítottuk el az alagút szerver részét nem ssl módban ( -listen ws:0.0.0.0), és nem ( -listen wss:0.0.0.0).

Domain fronting TLS 1.3 alapján. 2. rész

A teljes titkosítási módra váltáshoz ki kell választania TeleVagy Teljes (szigorú) ha valódi tanúsítvány van a szerveren. Az üzemmód váltása után a https protokoll használatával fogadhatunk majd kapcsolatokat a CloudFlare-től. Ne felejtsen el létrehozni egy önaláírt tanúsítványt az alagút szerveroldalához.

Domain fronting TLS 1.3 alapján. 2. rész

A kíváncsi olvasó megkérdezheti: „Mi a helyzet az ügyféllel?” Windows„Végül is egy tunneler fő felhasználási módja valószínűleg a vállalati gépek és szerverek közötti háttérkapcsolat létrehozása, és ezek általában mindig Windows gépek. Hogyan fordíthatok le egy tunnelert Windowsra, különösen egy adott TLS-veremmel?” Most bemutatunk egy másik funkciót, amely bemutatja, mennyire kényelmes a Golang. Windowsra közvetlenül Kali-ból fordítunk, egyszerűen a GOOS=windows paraméter hozzáadásával:

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

Vagy a 32 bites verzió:

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

Minden! És nincs szükség több gondra. Ez tényleg működik!

Domain fronting TLS 1.3 alapján. 2. rész

A –w és –s fordítójelzők azért szükségesek, hogy eltávolítsuk a felesleges szemetet a futtatható fájlból, ami néhány megabájttal kisebb lesz. Ezenkívül UPX használatával csomagolható a méret további csökkentése érdekében.

Ahelyett, hogy egy következtetés

A cikkben egy Golang nyelven írt alagút példáján egyértelműen bemutattuk az új domain-fronting technológia használatát, amelyet a TLS 1.3 protokoll egy igen érdekes tulajdonságán valósítottak meg. Hasonló módon adaptálhatja a Golang nyelven írt meglévő eszközöket, hogy például CloudFlare szervereken keresztül működjenek Kis sólyom - híres C2, vagy kényszerítse a CobaltStrike Beacont az eSNI domain fronting használatára, amikor a Teamserverrel dolgozik Külső C2 csatorna, amelyet Golang nyelven, vagy szabványos C++-ban az OpenSSL javított verzióját használva, amelyről a cikk utolsó részében beszéltünk. Általában véve a képzeletnek nincs határa.

Az tunnelerrel és a CloudFlare-rel kapcsolatos példa koncepció formájában kerül bemutatásra, és még mindig nehéz megmondani az ilyen típusú tartományfrontok hosszú távú kilátásait. Jelenleg csak a CloudFlare támogatja az eSNI-t, és elméletileg semmi sem akadályozza meg őket abban, hogy letiltsák ezt a fajta frontálást, és például megszakítsák a tls kapcsolatokat, ha az SNI és az eSNI nem egyezik. Általában a jövő fogja megmondani. Egyelőre azonban elég csábítónak tűnik a „kreml.ru” fedő alatti munkavégzés lehetősége. Nem?

A frissített tunneler kód, valamint a lefordított futtatható exe fájlok a projekt külön ágában találhatók GitHub. Jobb, ha minden lehetséges alagútproblémáról írunk egy kérdést a GitHubon található projektoldalon.

Forrás: will.com

Vásároljon megbízható tárhelyet DDoS védelemmel, VPS VDS szerverekkel rendelkező webhelyekhez 🔥 Vásároljon megbízható weboldal tárhelyet DDoS védelemmel, VPS VDS szerverekkel | ProHoster