Domain-fronting TLS 1.3 alapú. 2. rész

Bevezetés

Az első részben cikkből származnak röviden bemutattuk az encrypted SNI (eSNI) mechanizmusát. Megmutattuk, hogyan lehet e mechanizmus segítségével elkerülni a modern DPI rendszerek detektálását (például a Beeline DPI és a tiltott RKN rutracker esetében), valamint megvizsgáltuk egy új domain-fronting variánst ezen mechanizmus alapján.

A cikk második részében a RedTeam szakemberek nehéz munkájában hasznos gyakorlati dolgokra térünk át. Végül is a célunk nem a blokkolt erőforrásokhoz való hozzáférés (ilyen banális dolgokhoz ott van a régi jó VPN). Szerencsére rengeteg VPN szolgáltató létezik, ahogy mondani szokták, minden ízlésnek, színnek és költségvetésnek megfelelően.

Megpróbáljuk alkalmazni a domain-fronting mechanizmust a modern RedTeam eszközökhöz, például a Cobalt Strike-hoz, Empire-hez stb., és extra lehetőségeket biztosítani számukra a mimikrihez és a modern tartalomszűrő rendszerek elkerüléséhez.

Legutóbb az eSNI mechanizmust integráltuk az OpenSSL könyvtárba, és sikeresen használtuk azt a mindenki által ismert curl eszközben. De egyedül a curl nem elég, ahogy mondani szokták. Természetesen szeretnénk valami hasonlót megvalósítani magas szintű nyelveken is. Sajnos a weben végzett keresgélés csalódást okozott, mivel az eSNI mechanizmusa teljes mértékben csak a GOLANG-ban van megvalósítva. Így választási lehetőségünk nem túl nagy: írnunk kell vagy tiszta C-ben vagy C++-ban a javított OpenSSL könyvtár használatával, vagy használjunk a CloudFlare által készített külön GOLANG forkot, és próbáljuk meg portálni az eszközeinket oda. Van azonban még egy másik, klasszikusabb, de egyben időigényes megoldás is – ez az eSNI támogatás megvalósítása Python számára. Végül is a Python is OpenSSL-t használ a https műveletekhez. De ezt a lehetőséget másoknak hagyjuk fejlesztésre, mi a GOLANG megvalósítással fogunk megelégedni, főleg mivel a kedvenc Cobalt Strike-unk remekül tud dolgozni a külső eszközök által létrehozott kommunikációs csatornával (External C2 channel) – erről a cikk végén beszélünk.

Try Harder…

Az egyik Go nyelven megvalósított eszköz – a belső hálózatba történő pivotáláshoz készült tunneler rsockstun, aminek jelenleg a Microsoft és a Symantec eszközei nagyon káros szoftverként tekintenek, amely a globális stabilitás megzavarására irányul…

Domain-fronting TLS 1.3 alapú. 2. rész

Jó lenne a korábbi fejlesztést ebben az esetben is felhasználni. Azonban itt van egy kis probléma. Az rsockstun alapvetően a szerverrel való szinkron SSL kapcsolat használatát feltételezi. Ez azt jelenti, hogy a kapcsolat egyszer jön létre, és a tunneler működése alatt fennáll. Ahogy bizonyára tudja, a https protokoll némileg nem alkalmas az ilyen működési módra – kérés-válasz módban működik, ahol minden új http-kérés új tcp-kapcsolaton belül jön létre.

Ezen rendszer fő hátránya az, hogy a szerver nem tud adatokat küldeni az ügyfélnek, amíg az ügyfél nem küld egy új http-kérést. De szerencsére számos megoldási lehetőség létezik erre a problémára – a http protokollon keresztüli adatfolyam-küldés (végül is képesek vagyunk nézni a kedvenc sorozatainkat és hallgatni a zenét az https-t használó portálokról, és a videó- és audioátvitel nem más, mint adatfolyam-küldés). Az egyik technológia, amely lehetővé teszi egy teljes értékű tcp-kapcsolat emulálását a http protokoll felett, a web-socketek (WebSockets) technológiája, amelynek lényege, hogy teljes értékű hálózati kapcsolatot hozzon létre az ügyfél és a web-szerver között.

Szerencsére (hurrah-hurrah!!!) ez a technológia alapértelmezetten minden CloudFlare tarifacsomagban elérhető, és remekül működik az eSNI-vel. Ezt fogjuk használni, hogy megtanítsuk tunnelerünket doménfrontalizálásra és elrejtésre a modern DPI elől.

Röviden a WebSocketekről

Elsősorban röviden és egyszerű szavakkal fogunk beszélni a web-socketekről, hogy mindenki képet kapjon arról, mivel fogunk dolgozni.

A web-socketek technológia lehetővé teszi, hogy ideiglenesen átváltsunk az http-kapcsolatról a normál adatfolyam-ra a hálózati socketen anélkül, hogy megszakítanánk a kialakított tcp-kapcsolatot. Amikor az ügyfél a web-socketre akar váltani, a http-kérésében néhány http-fejlécként megadja. Két kötelező fejléc – Connection: Upgrade és Upgrade: websocket. Ezen kívül kényszerítheti a web-socket protokoll verzióját is (Sec-Websocket-Version: 13) és egyfajta base64 webSocket azonosító (Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==). A szerver 101 Switching Protocols HTTP-kóddal válaszol, és beállítja a fejlécet Connection, Upgrade és Sec-WebSocket-Accept. A váltási folyamatot az alábbi képen láthatjuk:

Domain-fronting TLS 1.3 alapú. 2. rész

Ezután a WebSocket kapcsolat létrehozását befejezettnek tekinthetjük. Bármilyen adat, legyen az az ügyféltől vagy a szervertől, ezután nem http, hanem WebSocket fejlécet kap (ezek 0x82 bájttal kezdődnek). Most a szervernek nem kell várnia az ügyfél kérésére, hogy adatokat továbbítson, mivel a tcp kapcsolat nem szakad meg.

A Golangban a webSokettel való munka során több könyvtár is elérhető. A legnépszerűbbek közé tartozik a Gorilla WebSocket és a standard WebSocket. Az utóbbit választjuk, mivel egyszerűbb, kevesebb és, mint mondják, egy kicsit gyorsabb.

A rsockstun kliens kódjában szükséges, hogy a net.dial vagy tls.dial hívásokat a megfelelő WebSocket hívásokra cseréljük:

Domain-fronting TLS 1.3 alapú. 2. rész

Domain-fronting TLS 1.3 alapú. 2. rész

Azt szeretnénk, hogy a tunneler kliens része univerzális legyen és képes legyen működni közvetlen ssl kapcsolaton keresztül, valamint WebSocket protokollon keresztül. Ehhez létrehozunk egy külön funkciót func connectForWsSocks(address string, proxy string) error {…} hasonlóan a connectForSocks() funkcióhoz, és ezt fogjuk használni a webSocket-ek kezelésére, abban az esetben, ha a kliens indításakor megadott szerver címe ws: vagy wss: -t (a Secure WebSocket esetében) kezdődik.

A tunneler szerveroldalához külön funkciót is létrehozunk a webSoketek kezelésére. Ebben egy http osztály példányát hozunk létre, és beállítjuk a http kapcsolat kezelőjét (wsHandler funkció):

Domain-fronting TLS 1.3 alapú. 2. rész

Az összes kapcsolatkezelési logikát (ügyfél hitelesítése jelszóval, yamux session létrehozása és befejezése) az WebSocket kapcsolatkezelőbe helyezzük:

Domain-fronting TLS 1.3 alapú. 2. rész

A projektet lefordítjuk, indítjuk a szerveroldali részt:

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

Majd indítjuk a kliens oldalt:

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

És ellenőrizzük a működést a helyi hoszton:

Domain-fronting TLS 1.3 alapú. 2. rész

Domain-fronting TLS 1.3 alapú. 2. rész

Áttérünk a domain-frontra

Úgy tűnik, hogy a webSoketek terén már tisztában vagyunk. Most térjünk át az eSNI-re és a domain-frontra. Ahogy már említettük, a DoH és az eSNI használatához egy speciális golang ágat kell használnunk a cégtől CDN. Szükségünk van egy eSNI támogatással rendelkező ágra (pwu/esni).

Letöltjük magunkhoz lokálisan, vagy letöltjük és kibővítjük a megfelelő zip fájlt:

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

Ezután másolnunk kell a GOROOT mappát, lecserélni a megfelelő fájlokat a klónozott ágból, és alapértelmezetté állítani. Hogy megkönnyítsék a fejlesztők dolgát, a CloudFlare csapata készített egy speciális scriptet – _dev/go.sh. Egyszerűen futtassuk le. A script a makefile-lal mindent elintéz. Ha érdekli, belenézhet a makefile-ba a részletekért.

A script futtatása után a projekt fordításakor meg kell adnunk GOROOT-ként a script által előkészített helyi mappát. Ez így néz ki:

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

Ezután a tunneling funkcióban meg kell valósítanunk a kívánt domain nyilvános eSNI kulcsainak lekérdezését és feldolgozását. Az esetünkben ezek a CloudFlare frontend szerverek nyilvános eSNI kulcsai lesznek. Ehhez három funkciót fogunk létrehozni:

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

A funkciók nevei, lényegében, magukért beszélnek. Az adatokat az esni_query.go fájlból fogjuk venni, amely része a tls-tris-nek. Az első funkció egy hálózati csomagot hoz létre a CloudFlare DNS szerverének lekérdezéséhez, DoH (DNS-over-HTTPS) protokoll használatával, a második feldolgozza a lekérdezés eredményeit, és megkapja a domain nyilvános kulcsainak értékeit, a harmadik pedig a két előző funkció tárolója.

Ezután bejegyzünk a frissen létrehozott webszerver csatlakozási funkciónkba. connectForWsSocks az eSNI kulcsok lekérdezési funkcióját a domain számára. Ahol a szerveroldal működik, beállítjuk a TLS paramétereket, valamint megadjuk a hamis "fedődomain" nevét:

Domain-fronting TLS 1.3 alapú. 2. rész

Itt érdemes megjegyezni, hogy az eredeti tls-tris ág nem készült domain-frontalizálásra. Ezért a hamis szervernévnek nem szenteltek figyelmet (a client-hello csomagban üres serverName mező kerül átadásra). Hogy ezt javítsuk, hozzá kell adnunk a TlsConfig struktúrához a megfelelő FakeServerName mezőt. A struktúra ServerName mezőjét nem használhatjuk, mert azt a tls belső mechanizmusai használják, és ha ez eltér az alapértelmezettől, a tls handshake hibaüzenettel végződik. A TlsConfig struktúra leírása a fájlban található. tls/common.go – ezt nekünk kell javítanunk:

Domain-fronting TLS 1.3 alapú. 2. rész

Domain-fronting TLS 1.3 alapú. 2. rész

Emellett változtatásokat kell eszközölnünk a fájlban. tls/handshake_client.go, hogy használni tudjuk a FakeServerName mezőnket a TLS kézfogó létrehozásakor:

Domain-fronting TLS 1.3 alapú. 2. rész

Ennyi! Most már lehet fordítani a projektet és ellenőrizni a működését. De mielőtt futtatnánk a tesztet, be kell állítani a CloudFlare fiókot. Vagyis, hogy úgy mondjam, egyszerűen létre kell hozni egy fiókot a CloudFlare-en, és össze kell kapcsolni a saját domainünket vele. Minden, a DoH-val, WebSocket-tel és ESNI-vel kapcsolatos funkció alapértelmezés szerint be van kapcsolva a CloudFlare-nél. Miután a DNS rekordok frissülnek, ellenőrizni lehet a domain működését az eSNI kulcsok lekérdezésével:

dig +short txt _esni.df13tester.info 

Domain-fronting TLS 1.3 alapú. 2. rész

Ha valami hasonlót látsz a domaineden, akkor minden rendben működik, és áttérhetsz a tesztelésre.

Indítunk egy Ubuntu VPS-t, például a DigitalOcean-en. P.S. A mi esetünkben az újonnan kiadott VPS provider IP-címe a RKN feketelistáin szerepelt. Szóval ne lepődj meg, ha veled is hasonló történik. Használni kellett a VPN-t, hogy hozzáférjünk a VPS-hez.

Átmásoljuk a VPS-re a már lefordított rsockstun-t (amúgy ez a Go nyelv egyik előnye – a projektet a saját gépeden le tudod fordítani, és bármely Linuxon elindítani, csupán a rendszer architektúráját kell figyelembe venni) és elindítjuk a szerveroldali részt:

Domain-fronting TLS 1.3 alapú. 2. rész

Aztán elindítjuk a kliensoldali részt:

Domain-fronting TLS 1.3 alapú. 2. rész

Ahogy látjuk, a kliens sikeresen csatlakozott a szerverhez a CloudFlare frontend szerverén keresztül WebSocket használatával. Annak ellenőrzésére, hogy a tunneling valóban tunnelingként működik, curl lekérdezést végezhetünk a szerveren nyitott helyi socks5-ön keresztül:

Domain-fronting TLS 1.3 alapú. 2. rész

Most nézzük meg, mit lát a DPI a kommunikációs csatornában:

Domain-fronting TLS 1.3 alapú. 2. rész

Elsőként a tunneler a DoH mechanizmus segítségével a Cloudflare DNS szerveréhez fordul az eSNI kulcsokért a cél domainhez (1-19. csomagok), majd a frontend szerver felé fordul és TLS kapcsolatot létesít, miközben elfedi magát a domain alatt www.google.com (ez az alapértelmezett érték, amikor a kliens elindítása során nem adunk meg hamis domaint). A saját hamis domain megadásához a -fronfDomain paramétert kell használni:

Domain-fronting TLS 1.3 alapú. 2. rész

Domain-fronting TLS 1.3 alapú. 2. rész

Most egy másik dolog. Alapértelmezés szerint a CloudFlare fiók beállításánál a Flexible SSL üzemmód van beállítva. Ez azt jelenti, hogy a Cloudflare frontend szervereihez érkező HTTPS lekérdezéseket a kliens nem titkosított (HTTP) formában irányítják a szerverünkhöz. Ezért indítottuk a tunneler szerveroldali részét non-ssl módban (-listen ws:0.0.0.0) és nem (-listen wss:0.0.0.0) módban.

Domain-fronting TLS 1.3 alapú. 2. rész

A teljes titkosítási módra való átálláshoz ki kell választani Teljes, vagy Full (strict) ha a szerveren érvényes tanúsítvány van. A módváltás után képesek leszünk HTTPS protokollon keresztül fogadni a csatlakozásokat a CloudFlare-től. Ne felejtsd el generálni a self-signed tanúsítványt a tunneler szerveroldalához.

Domain-fronting TLS 1.3 alapú. 2. rész

A szorgalmas olvasó megkérdezheti: „Mi van a Windows klienssel? Bizonyára a tunneler fő alkalmazása a vállalati gépek és szerverek hátsó bekötésének felállítása, ahol általában mindig Windows van. Hogyan tudom lefordítani a tunnelt Windows-ra, ráadásul egy specifikus TLS veremmel?” Most bemutatunk egy újabb funkciót, amely megmutatja, mennyire kényelmes a Go. Közvetlenül Kali-ból lefordítjuk Windows-ra, csak annyit kell hozzátennünk, hogy a GOOS=windows:

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

Vagy a 32 bites változat:

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

Kész! És többé nincs szükség egyéb bonyodalmakra. Ez valóban működik!

Domain-fronting TLS 1.3 alapú. 2. rész

A fordítóflag-ek –w és –s arra valók, hogy eltávolítsák a felesleges hulladékot a végrehajtható fájlból, ezzel pár megabájttal csökkentve annak méretét. További csomagolásra UPX-t is használhatunk, hogy még inkább csökkentsük a méretet.

Összegzésként

A cikkünkben a Go nyelven írt tunneler példáján keresztül szemléltettük az új domain fronting technológia alkalmazását, amely a TLS 1.3 protokoll egy érdekes sajátosságán alapszik. Hasonló módon alkalmazhatjuk a meglévő Go eszközkészletet a CloudFlare szervereken való munkára is, például. Merlin — egy jól ismert C2, vagy kényszeríthetjük a CobaltStrike Beacont az eSNI domain fronting használatára a Teamserver-rel való munkavégzés során Külső C2 csatorna, megvalósítva a Go nyelvén, vagy akár a szabványos C++-ban, a korábban említett, módosított OpenSSL verzióval, amelyről a cikkünk előző részében írtunk. Szóval, a fantázia határtalan.

A tunneler és a CloudFlare példa konceptuálisan van bemutatva, és egyelőre nehéz megmondani, milyen távoli perspektívái vannak ennek a domain fronting típusnak. Jelenleg az eSNI támogatása csak a CloudFlare-nél valósult meg, és elvileg semmi nem akadályozza meg őket abban, hogy leállítsák ezt a fajta frontingot, és például megszakítsák a TLS kapcsolatoktól, ha az SNI és az eSNI nem egyezik. Összességében a jövő majd megmutatja. De egyelőre a „kremlin.ru álcája mögött” való munka lehetősége elég csábítóan fest. Nem igaz?

A frissített alagútkód és a lefordított végrehajtható exe fájlok egy külön ágon találhatóak a projektban a következő címen: githubMinden lehetséges alagútkapcsolati problémával kapcsolatban a legtisztább, ha az issue részlegbe írunk a GitHub projektoldalon.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster