Úvod
V prvej časti Uviedli sme stručný popis šifrovaného mechanizmu SNI (eSNI). Ukázali, ako sa na jeho základe dá vyhnúť detekcii modernými DPI systémami (na príklade Beeline DPI a zakázaného root trackera RKN), a tiež preskúmali novú verziu doménového frontingu založenú na tomto mechanizme.
V druhej časti článku prejdeme k praktickejším veciam, ktoré sa budú špecialistom RedTeamu hodiť pri ich neľahkej práci. Naším cieľom nakoniec nie je získať prístup k blokovaným zdrojom (na takéto triviálne veci máme starú dobrú VPN). Našťastie existuje veľké množstvo poskytovateľov VPN, ako sa hovorí, pre každý vkus, farbu a rozpočet.
Pokúsime sa použiť mechanizmus frontovania domény na moderné nástroje RedTeamu, napríklad ako Cobalt Strike, Empire atď., a poskytnúť im ďalšie možnosti na napodobňovanie a vyhýbanie sa moderným systémom filtrovania obsahu.
Naposledy sme do knižnice OpenSSL implementovali mechanizmus eSNI a úspešne sme ho použili v známej utilite curl. Ale ako sa hovorí, neuspokojíte sa len s jedným kuracím mäsom. Samozrejme, rád by som niečo podobné implementoval do jazykov na vysokej úrovni. Rýchle vyhľadávanie na internete nás však bohužiaľ sklame, pretože podpora mechanizmu eSNI je plne implementovaná iba v GOLANG. Nemáme teda veľmi na výber: buď píšeme v čistom C alebo C++ pomocou opravenej knižnice OpenSSL, alebo použijeme samostatnú vidlicu GOLANG od CloudFlare a pokúsime sa tam preniesť naše nástroje. V zásade je tu ešte jedna možnosť, klasickejšia, no zároveň časovo náročná – implementovať podporu eSNI pre Python. Koniec koncov, Python tiež používa OpenSSL na spracovanie https. Túto možnosť však necháme na vývoj niekomu inému a my sami si vystačíme s implementáciou v Golangu, najmä preto, že náš milovaný Cobalt Strike dokonale dokáže pracovať s komunikačným kanálom vytvoreným nástrojmi tretích strán (Externý kanál C2) - o tom si povieme na konci článku.
Snaž sa viac...
Jedným z nástrojov implementovaných v Go je náš vývoj pre pivotovanie do siete – tunelovač , ktorý, mimochodom, teraz detegujú nástroje od Microsoftu a Symantecu ako veľmi škodlivý softvér zameraný na narušenie globálnej stability...

Aj v tomto prípade by bolo skvelé využiť predchádzajúci vývoj. Tu však nastáva malý problém. Faktom je, že pôvodne rsockstun znamená použitie synchrónneho komunikačného kanála SSL so serverom. To znamená, že spojenie je vytvorené raz a existuje počas celej doby prevádzky tunela. A ako ste pochopili, protokol https nie je určený pre tento režim prevádzky - funguje v režime požiadavka-odpoveď, kde každá nová požiadavka http existuje v rámci nového pripojenia tcp.
Hlavnou nevýhodou tejto schémy je, že server nemôže preniesť dáta klientovi, kým klient nepošle novú http požiadavku. Ale, našťastie, existuje veľa možností, ako tento problém vyriešiť - streamovanie dát cez protokol http (napokon sa nám nejako darí pozerať obľúbené TV programy a počúvať hudbu z portálov bežiacich na https, ale prenos videa a zvuku nie je nič iné než streamovanie údajov). Jednou z technológií na emuláciu prevádzky plnohodnotného pripojenia TCP cez protokol HTTP je technológia WebSockets, ktorej hlavnou podstatou je zorganizovať plnohodnotné sieťové pripojenie medzi klientom a webovým serverom.
Našťastie pre nás (hurá!!!) je táto technológia štandardne zahrnutá vo všetkých tarifných plánoch CloudFlare a funguje skvele v kombinácii s eSNI. To je presne to, čo použijeme na to, aby sme naučili nášho tunelára používať doménový fronting a skrývať sa pred modernými DPI.
Trochu o WebSockets
Najprv si stručne a jednoduchými slovami povieme o websocketoch, aby mal každý predstavu, s čím budeme pracovať.
Technológia Websocket vám umožňuje dočasne prepnúť z http pripojenia na štandardný sieťový socket streaming bez prerušenia vytvoreného TCP spojenia. Keď chce klient prejsť na websocket, nastaví vo svojej http požiadavke niekoľko hlavičiek http. Dve povinné hlavičky - Pripojenie: Upgrade и Upgrade: websocket. Môže tiež násilne špecifikovať verziu protokolu websocket (Sec-Websockset-Verzia: 13) a niečo ako identifikátor websocket base64 (Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==). Server mu odpovie http kódom 101 Switching Protocols a nastaví aj hlavičky Pripojenie, upgrade и Sec-WebSocket-Accept. Proces prepínania je jasne znázornený na obrázku nižšie:

Potom môže byť inštalácia pripojenia WebSocket považovaná za dokončenú. Všetky údaje z klienta aj zo servera teraz nebudú dodávané s http, ale s hlavičkami WebSocket (začínajú bajtom 0x82). Teraz server nemusí čakať na žiadosť klienta o prenos údajov, pretože Spojenie tcp nie je prerušené.
Golang má niekoľko knižníc na prácu s websockets. Najpopulárnejšie z nich sú a štandardné . Použijeme to druhé, pretože... je jednoduchší, menší a ako sa hovorí, funguje o niečo rýchlejšie.
V kóde klienta rsockstun musíme nahradiť volania net.dial alebo tls.dial zodpovedajúcimi volaniami WebSocket:


Chceme, aby klientská časť nášho tunela bola univerzálna a schopná pracovať ako cez priame SSL pripojenie, tak aj cez protokol WebSockset. Na to vytvoríme samostatnú funkciu func connectForWsSocks (reťazec adresy, reťazec proxy) chyba {…} analogicky s connectForSocks() a použijeme ho na prácu s webovými soketmi, ak adresa servera zadaná pri spustení klienta začína ws: alebo wss: (v prípade Secure WebSocket).
Pre serverovú stranu tunela urobíme aj samostatnú funkciu pre prácu s web soketmi. Vytvorí inštanciu triedy http a nastaví obsluhu pripojenia http (funkcia wsHandler):

A celú logiku spracovania pripojenia (autorizáciu klienta pomocou hesla, nastavenie a ukončenie relácie yamux) umiestnime do obsluhy pripojenia WebSocket:

Kompilujeme projekt a spúšťame serverovú časť:
./rsockstun –listen ws:127.0.0.1:8080 –pass P@ssw0rdA potom klientska časť:
./rsockstun -connect ws:127.0.0.1:8080 –pass P@ssw0rdA skontrolujeme prácu na miestnom hostiteľovi:


Prejdime na fronting domény
Zdá sa, že sme prišli na webové zásuvky. Teraz prejdime priamo k eSNI a doménovému frontingu. Ako už bolo spomenuté, na prácu s DoH a eSNI musíme zo spoločnosti vziať špeciálnu pobočku golang . Potrebujeme pobočku s podporou eSNI (pwu/esni).
Naklonujeme ho lokálne alebo stiahneme a rozbalíme príslušný zip:
git clone -b pwu/esni https://github.com/cloudflare/tls-tris.gitPotom musíme skopírovať adresár GOROOT, nahradiť zodpovedajúce súbory z klonovanej vetvy a nastaviť ho ako hlavný. Aby vývojári tejto bolesti hlavy ušetrili, chalani z CloudFlare pripravili špeciálny skript – _dev/go.sh. Len to spustíme. Skript spolu s makefile urobia všetko sami. Len pre zábavu sa môžete pozrieť do súboru Makefile, kde nájdete podrobnosti.
Po spustení skriptu pri kompilácii projektu budeme musieť zadať lokálny adresár pripravený skriptom ako GOROOT. V našom prípade to vyzerá takto:
GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" go build ….Ďalej musíme v tuneli implementovať funkcionalitu vyžiadania a analýzy verejných eSNI kľúčov pre požadovanú doménu. V našom prípade to budú verejné eSNI kľúče z frontend serverov CloudFlare. Na tento účel vytvoríme tri funkcie:
func makeDoTQuery(dnsName string) ([]byte, error)
func parseTXTResponse(buf []byte, wantName string) (string, error)
func QueryESNIKeysForHost(hostname string) ([]byte, error)Názvy funkcií v zásade hovoria samy za seba. Obsah preberieme zo súboru esni_query.go, ktorý je súčasťou tls-tris. Prvá funkcia vytvorí sieťový paket s požiadavkou na server CloudFlare DNS pomocou protokolu DoH (DNS-over-HTTPS), druhá analyzuje výsledky dotazu a získa hodnoty verejných kľúčov domény a tretia je kontajner pre prvé dva.
Ďalej do našej novovytvorenej funkcie pridáme pripojenie na webovú zásuvku connectForWsSocks funkcia na vyžiadanie eSNI kľúčov pre doménu. Tam, kde funguje serverová časť, nastavujeme parametre TLS a tiež nastavujeme názov falošnej „krycej domény“:

Tu je potrebné poznamenať, že pôvodne vetva tls-tris nebola navrhnutá na použitie frontingu domény. Preto nevenuje pozornosť falošnému názvu servera (prázdne pole serverName sa odošle ako súčasť paketu klient-ahoj). Aby sme to vyriešili, budeme musieť pridať zodpovedajúce pole FakeServerName do štruktúry TlsConfig. Nemôžeme použiť štandardné pole ServerName štruktúry, pretože používajú ho interné tls mechanizmy a ak sa líši od pôvodného, tls handshake sa skončí chybou. Opis štruktúry TlsConfig je obsiahnutý v súbore tls/common.go - musíme to opraviť:


Okrem toho budeme musieť vykonať zmeny v súbore tls/handshake_client.gona použitie nášho poľa FakeServerName pri vytváraní handshake TLS:

To je všetko! Môžete zostaviť projekt a skontrolovať prácu. Pred spustením skenovania si však musíte nastaviť účet CloudFlare. No, ako to môžem povedať nastaviť - stačí si vytvoriť účet na cloudflare a prepojiť s ním svoju doménu. Všetky funkcie súvisiace s DoH, WebSocket a ESNI sú štandardne zahrnuté v CloudFlare. Po aktualizácii záznamov DNS môžete skontrolovať fungovanie domény zadaním kľúčov eSNI:
dig +short txt _esni.df13tester.info 
Ak vidíte niečo podobné pre svoju doménu, znamená to, že všetko pre vás funguje a môžete pokračovať v testovaní.
Spustiť Ubuntu Napríklad VPS na DigitalOcean. PS: V našom prípade sa IP adresa VPS, ktorú sme práve dostali od nášho poskytovateľa, dostala na čiernu listinu Roskomnadzoru. Takže sa nečudujte, ak sa vám stane niečo podobné. Na prístup k svojmu VPS som musel použiť VPN.
Skopírujeme už skompilovaný rsockstun do VPS (to je mimochodom ďalšia krása Golangu - projekt si môžete skompilovať sami a spustiť ho na akomkoľvek Linuxe, pričom dodržíte iba bitovú kapacitu systému) a spustíme serverovú časť:

A potom klientska časť:

Ako vidíme, klient sa úspešne pripojil k serveru cez frontend server CloudFlare pomocou websocketu. Ak chcete skontrolovať, či tunel funguje presne ako tunel, môžete požiadať o zvlnenie prostredníctvom lokálnych ponožiek5 otvorených na serveri:

Teraz sa pozrime, čo vidí DPI v komunikačnom kanáli:

Najprv tunelár pomocou mechanizmu DoH kontaktuje server DNS Cloudflare pre kľúče eSNI pre cieľovú doménu (pakety č. 1-19) a potom kontaktuje frontend server a vytvorí pripojenie TLS, ktoré sa skrýva za doménou. (toto je predvolená hodnota, keď pri spustení klienta nie je zadaná žiadna falošná doména). Ak chcete zadať svoju falošnú doménu, musíte použiť parameter -fronfDomain:
![]()

Teraz ešte jedna vec. V predvolenom nastavení sú nastavenia účtu CloudFalre nastavené na flexibilné SSL. To znamená, že požiadavky https na frontend servery Cloudflare od klientov budú preposlané nezašifrované (http) na náš server. Preto sme serverovú časť tunela spustili v režime bez protokolu SSL ( -listen ws:0.0.0.0), a nie ( -listen wss:0.0.0.0).

Ak chcete prepnúť do režimu úplného šifrovania, musíte vybrať plneAlebo Úplné (prísne) ak je na serveri skutočný certifikát. Po prepnutí režimu budeme môcť prijímať pripojenia z CloudFlare pomocou protokolu https. Nezabudnite vygenerovať certifikát s vlastným podpisom pre serverovú stranu tunela.

Zvedavý čitateľ sa opýta: „A čo klient pod Windows„Napokon, hlavným použitím tunelovacieho nástroja je pravdepodobne nadviazanie back-endového pripojenia z firemných počítačov a serverov, a tie sú zvyčajne vždy Windows. Ako skompilujem tunelovací nástroj pre Windows, najmä so špecifickým TLS stackom?“ Teraz si predstavíme ďalšiu funkciu, ktorá demonštruje, aký pohodlný je Golang. Pre Windows kompilujeme priamo z Kali jednoduchým pridaním parametra GOOS=windows:
GOARCH=amd64 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"Alebo 32-bitová verzia:
GOARCH=386 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"Všetky! A nie sú potrebné žiadne ďalšie problémy. Naozaj to funguje!

Príznaky kompilátora –w a –s sú potrebné na odstránenie zbytočného odpadu zo spustiteľného súboru, čím sa zmenšia o niekoľko megabajtov. Okrem toho môže byť zabalený pomocou UPX, aby sa ďalej zmenšila veľkosť.
namiesto záveru
V článku sme na príklade tunela napísaného v Golangu názorne demonštrovali využitie novej technológie domain-fronting, implementovanej na pomerne zaujímavej funkcii protokolu TLS 1.3. Podobným spôsobom môžete prispôsobiť existujúce nástroje napísané v Golang, aby fungovali napríklad prostredníctvom serverov CloudFlare - slávny C2 alebo prinútiť CobaltStrike Beacon používať eSNI doménové fronty pri práci s Teamserver cez , implementovaný v Golang, alebo v štandardnom C++ pomocou opravenej verzie OpenSSL, o ktorej sme hovorili v minulej časti článku. Vo všeobecnosti sa fantázii medze nekladú.
Príklad s tunelárom a CloudFlare je prezentovaný vo forme konceptu a zatiaľ je ťažké povedať o dlhodobej perspektíve tohto typu frontingu domény. Momentálne podporuje eSNI iba CloudFlare a teoreticky im nič nebráni v tom, aby deaktivovali tento druh frontingu a napríklad prerušili spojenia tls, ak sa SNI a eSNI nezhodujú. Vo všeobecnosti to ukáže budúcnosť. Ale zatiaľ vyzerá perspektíva pracovať pod „krytom kremlin.ru“ celkom lákavo. Nieje to?
Aktualizovaný kód tunelového nástroja, ako aj skompilované spustiteľné exe súbory sa nachádzajú v samostatnej vetve projektu na . Je lepšie napísať problém o všetkých možných problémoch tunela na stránke projektu na GitHub.
Zdroj: hab.com
