{"id":53317,"date":"2019-11-29T00:00:00","date_gmt":"2019-11-28T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/domen-fronting-na-baze-tls-1-3-chast-2"},"modified":"2020-02-18T14:01:12","modified_gmt":"2020-02-18T11:01:12","slug":"domen-fronting-na-baze-tls-1-3-chast-2","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/domen-fronting-na-baze-tls-1-3-chast-2","title":{"rendered":"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h3>Wprowadzenie<\/h3>\n<p>\nW pierwszej cz\u0119\u015bci <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/475372\/\">artyku\u0142u<\/a><\/noindex> przedstawili\u015bmy kr\u00f3tki opis mechanizmu encrypted SNI (eSNI). Pokazali\u015bmy, jak mo\u017cna na jego podstawie unika\u0107 wykrywania przez nowoczesne systemy DPI (na przyk\u0142ad na podstawie DPI Beeline i zablokowanego ruskiego trackeru), a tak\u017ce zbadali\u015bmy now\u0105 wersj\u0119 frontingu domeny opart\u0105 na tym mechanizmie.<\/p>\n<p>W drugiej cz\u0119\u015bci artyku\u0142u przejdziemy do bardziej praktycznych aspekt\u00f3w, kt\u00f3re b\u0119d\u0105 przydatne specjalistom RedTeam w ich trudnej pracy. W ko\u0144cu naszym celem nie jest uzyskanie dost\u0119pu do zablokowanych zasob\u00f3w (do takich bana\u0142\u00f3w mamy star\u0105 dobr\u0105 VPN). Na szcz\u0119\u015bcie dostawc\u00f3w VPN istnieje niezliczona ilo\u015b\u0107, jak m\u00f3wi\u0105, na ka\u017cdy gust, kolor i bud\u017cet.<\/p>\n<p>Postaramy si\u0119 zastosowa\u0107 mechanizm frontingu domeny do nowoczesnych narz\u0119dzi RedTeam, takich jak Cobalt Strike, Empire itp., i da\u0107 im dodatkowe mo\u017cliwo\u015bci w zakresie mimikry i unikania nowoczesnych system\u00f3w filtrowania tre\u015bci.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nOstatnim razem wdro\u017cyli\u015bmy mechanizm eSNI w bibliotece OpenSSL i skutecznie wykorzystali\u015bmy go w znanym wszystkim narz\u0119dziu curl. Ale tylko curl'em, jak m\u00f3wi przys\u0142owie, nie b\u0119dziesz syty. Oczywi\u015bcie chcieliby\u015bmy wdro\u017cy\u0107 co\u015b podobnego w j\u0119zykach wy\u017cszego poziomu. Niestety, szybkie poszukiwania w sieci rozczarowuj\u0105 nas, poniewa\u017c wsparcie dla mechanizmu eSNI jest w pe\u0142ni realizowane tylko w GOLANG. Tak wi\u0119c wyb\u00f3r nie jest zbyt du\u017cy: albo piszemy w czystym C lub C++ z u\u017cyciem zmodyfikowanej biblioteki OpenSSL, albo korzystamy z osobnego forka GOLANG od CloudFlare i pr\u00f3bujemy przenie\u015b\u0107 nasze narz\u0119dzia tam. Istnieje jeszcze jedna opcja, bardziej klasyczna, ale jednocze\u015bnie czasoch\u0142onna \u2013 wdro\u017cy\u0107 wsparcie eSNI dla Pythona. W ko\u0144cu Python r\u00f3wnie\u017c korzysta z OpenSSL do pracy z https. Ale t\u0119 opcj\u0119 zostawimy do rozwoju komu\u015b innemu, a sami zadowolimy si\u0119 realizacj\u0105 w golangu, zw\u0142aszcza \u017ce nasz ulubiony Cobalt Strike doskonale potrafi wsp\u00f3\u0142pracowa\u0107 z kana\u0142em komunikacyjnym zbudowanym za pomoc\u0105 zewn\u0119trznych \u015brodk\u00f3w (External C2 channel) \u2013 o tym opowiemy na ko\u0144cu artyku\u0142u.<\/p>\n<h3>Try Harder\u2026<\/h3>\n<p>\nJednym z narz\u0119dzi zaimplementowanych w Go jest nasze opracowanie do pivotowania wewn\u0105trz sieci \u2013 tunel <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/mis-team\/rsockstun\">rsockstun<\/a><\/noindex>, kt\u00f3ra, nawiasem m\u00f3wi\u0105c, obecnie jest wykrywana przez oprogramowanie firm Microsoft i Symantec jako bardzo z\u0142o\u015bliwe oprogramowanie, maj\u0105ce na celu naruszenie stabilno\u015bci \u015bwiatowej\u2026<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/13d2635b92051416b2f33415783a2837.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFajnie by\u0142oby wykorzysta\u0107 poprzednie opracowanie i w tym przypadku. Ale pojawia si\u0119 ma\u0142y problem. Chodzi o to, \u017ce pierwotnie rsockstun zak\u0142ada u\u017cycie synchronizowanego SSL kana\u0142u komunikacyjnego z serwerem. Oznacza to, \u017ce po\u0142\u0105czenie nawi\u0105zywane jest raz i istnieje przez ca\u0142y czas dzia\u0142ania tunelera. A jak wiadomo, protok\u00f3\u0142 https nie do ko\u0144ca jest przystosowany do takiego trybu pracy \u2013 dzia\u0142a w trybie \u017c\u0105danie-odpowied\u017a, gdzie ka\u017cde nowe \u017c\u0105danie http istnieje w ramach nowego po\u0142\u0105czenia tcp.<\/p>\n<p>G\u0142\u00f3wn\u0105 wad\u0105 takiego schematu jest to, \u017ce serwer nie mo\u017ce przesy\u0142a\u0107 danych do klienta, dop\u00f3ki klient nie wy\u015ble nowego \u017c\u0105dania http. Ale na szcz\u0119\u015bcie istnieje wiele opcji rozwi\u0105zania tego problemu \u2013 przesy\u0142ania danych strumieniowo przez protok\u00f3\u0142 http (w ko\u0144cu jako\u015b udaje nam si\u0119 ogl\u0105da\u0107 nasze ulubione seriale i s\u0142ucha\u0107 muzyki z portali dzia\u0142aj\u0105cych na https, a przesy\u0142anie wideo i audio to nic innego jak przesy\u0142anie danych strumieniowo). Jedn\u0105 z technologii do emulacji dzia\u0142ania pe\u0142noprawnego po\u0142\u0105czenia tcp nad protoko\u0142em http s\u0105 technologie WebSockets, kt\u00f3rych g\u0142\u00f3wn\u0105 ide\u0105 jest organizacja pe\u0142noprawnego po\u0142\u0105czenia sieciowego mi\u0119dzy klientem a serwerem www.<\/p>\n<p>Na nasze szcz\u0119\u015bcie (hurra!!!), ta technologia jest w\u0142\u0105czona domy\u015blnie we wszystkich planach taryfowych CloudFlare i \u015bwietnie wsp\u00f3\u0142pracuje z eSNI. W\u0142a\u015bnie j\u0105 zamierzamy wykorzysta\u0107, aby nauczy\u0107 nasz tunelowa\u0107 technologi\u0119 domain fronting i ukrywa\u0107 si\u0119 przed nowoczesnym DPI. <\/p>\n<h3>Kilka s\u0142\u00f3w o WebSockets<\/h3>\n<p>\nPrzede wszystkim w skr\u00f3cie i prostymi s\u0142owami opowiemy o WebSockets, aby wszyscy mieli poj\u0119cie o tym, z czym b\u0119dziemy pracowa\u0107. <\/p>\n<p>Technologia WebSockets pozwala tymczasowo prze\u0142\u0105czy\u0107 si\u0119 z po\u0142\u0105czenia http na standardowe przesy\u0142anie strumieniowe danych przez gniazdo sieciowe, nie zrywaj\u0105c przy tym ustanowionego po\u0142\u0105czenia tcp. Gdy klient chce prze\u0142\u0105czy\u0107 si\u0119 na WebSocket, w swoim \u017c\u0105daniu http wysy\u0142a kilka nag\u0142\u00f3wk\u00f3w http. Dwie obowi\u0105zkowe nag\u0142\u00f3wki to: <i><b>Connection: Upgrade<\/b><\/i> i <i><b>Upgrade: websocket<\/b><\/i>. Mo\u017ce on r\u00f3wnie\u017c wymusi\u0107 wersj\u0119 protoko\u0142u websocket (<i><b>Sec-Websocket-Version: 13<\/b><\/i>) oraz co\u015b w rodzaju identyfikatora base64 dla websocketu (<i><b>Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==<\/b><\/i>). Serwer odpowiada kodem http 101 Switching Protocols i r\u00f3wnie\u017c ustawia nag\u0142\u00f3wki <i><b>Connection, Upgrade<\/b><\/i> i <i><b>Sec-WebSocket-Accept<\/b><\/i>. Proces prze\u0142\u0105czania jest zobrazowany na zrzucie ekranu poni\u017cej:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/1ee9af28074e5e190daea9b4b4a4a524.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPo tym mo\u017cna uzna\u0107, \u017ce nawi\u0105zanie po\u0142\u0105czenia WebSocket zosta\u0142o zako\u0144czone. Wszystkie dane zar\u00f3wno od klienta, jak i od serwera b\u0119d\u0105 teraz u\u017cywa\u0107 nag\u0142\u00f3wk\u00f3w WebSocket (zaczynaj\u0105 si\u0119 od bajtu 0x82). Teraz serwer nie musi czeka\u0107 na zapytanie od klienta, aby przes\u0142a\u0107 dane, poniewa\u017c po\u0142\u0105czenie tcp nie jest zrywane.<\/p>\n<p>W Go do pracy z websocketami istnieje kilka bibliotek. Najbardziej popularne to <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/websocket\">Gorilla WebSocket<\/a><\/noindex> oraz standardowa <noindex><a rel=\"nofollow\" href=\"https:\/\/godoc.org\/golang.org\/x\/net\/websocket\">WebSocket.<\/a><\/noindex>. Skorzystamy z tej drugiej, poniewa\u017c jest prostsza, mniejsza i, jak m\u00f3wi\u0105, dzia\u0142a nieco szybciej.<\/p>\n<p>W kodzie klienta rsockstun musimy zast\u0105pi\u0107 wywo\u0142ania net.dial lub tls.dial odpowiednimi wywo\u0142aniami WebSocket:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/e7ffc8aadeed32b8c456ef03cff4cdf8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/035b3190717482f6aaac22b06cd25bc9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nChcemy, aby cz\u0119\u015b\u0107 kliencka naszego tunelowania by\u0142a uniwersalna i mog\u0142a dzia\u0142a\u0107 zar\u00f3wno przez bezpo\u015brednie po\u0142\u0105czenie ssl, jak i przez protok\u00f3\u0142 WebSocket. W tym celu stworzymy osobn\u0105 funkcj\u0119 <i><b>func connectForWsSocks(address string, proxy string) error {\u2026}<\/b><\/i> na podobie\u0144stwo <i><b>connectForSocks()<\/b><\/i> i b\u0119dziemy j\u0105 u\u017cywa\u0107 do pracy z websocketami, je\u015bli adres serwera podany przy uruchomieniu klienta zacznie si\u0119 od ws: lub wss: (w przypadku Secure WebSocket).<\/p>\n<p>Dla serwerowej cz\u0119\u015bci tunelowania r\u00f3wnie\u017c stworzymy osobn\u0105 funkcj\u0119 do pracy z websocketami. W niej b\u0119dzie tworzony egzemplarz klasy http i ustawiany handler http (funkcja wsHandler): <\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/ad904b629aa40bf45d42c095d4285658.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA ca\u0142\u0105 logik\u0119 obs\u0142ugi po\u0142\u0105czenia (autoryzacja klienta wed\u0142ug has\u0142a, nawi\u0105zanie i zako\u0144czenie sesji yamux) umie\u015bcimy w handlerze po\u0142\u0105czenia WebSocket:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/a624dca4819cee4b9d46f1325aafc544.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKompilujemy projekt, uruchamiamy cz\u0119\u015b\u0107 serwerow\u0105:<\/p>\n<pre><code class=\"go\">.\\\/rsockstun \u2013listen ws:127.0.0.1:8080 \u2013pass P@ssw0rd<\/code><\/pre>\n<p>\nA nast\u0119pnie cz\u0119\u015b\u0107 klienck\u0105:<\/p>\n<pre><code class=\"go\">.\\\/rsockstun -connect ws:127.0.0.1:8080 \u2013pass P@ssw0rd<\/code><\/pre>\n<p>\nI sprawdzamy dzia\u0142anie na lokalnym ho\u015bcie:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/34bb12087eb7dd72cf1f35d7addf2c72.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/83fc82e962961ba8491164d26f27be95.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Przechodzimy do domeny fronting<\/h3>\n<p>\nZ websocketami chyba si\u0119 uporali\u015bmy. Teraz przejd\u017amy bezpo\u015brednio do eSNI i domeny fronting. Jak ju\u017c wcze\u015bniej wspomniano, do pracy z DoH i eSNI musimy wzi\u0105\u0107 specjaln\u0105 ga\u0142\u0105\u017a golanga od firmy <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/cloudflare\/tls-tris\">CloudFlare<\/a><\/noindex>. Potrzebujemy ga\u0142\u0119zi z obs\u0142ug\u0105 eSNI (pwu\/esni).<\/p>\n<p>Klonujemy j\u0105 lokalnie lub pobieramy i rozpakowujemy odpowiedni zip:<\/p>\n<pre><code class=\"plaintext\">git clone -b pwu\/esni https:\/\/github.com\/cloudflare\/tls-tris.git<\/code><\/pre>\n<p>\nNast\u0119pnie musimy skopiowa\u0107 katalog GOROOT, zamieni\u0107 odpowiednie pliki z klonowanej ga\u0142\u0119zi i ustawi\u0107 go jako g\u0142\u00f3wny. Aby uwolni\u0107 programist\u00f3w od tej uci\u0105\u017cliwo\u015bci, ch\u0142opaki z CloudFlare przygotowali specjalny skrypt \u2013 _dev\/go.sh. Po prostu go uruchamiamy. Skrypt wraz z makefile zrobi wszystko sam. Dla ciekawo\u015bci \u2013 mo\u017cecie zajrze\u0107 do makefile po szczeg\u00f3\u0142y.<\/p>\n<p>Po wykonaniu skryptu, przy kompilacji projektu, b\u0119dziemy musieli wskaza\u0107 jako GOROOT lokalny katalog przygotowany przez skrypt. W naszym przypadku wygl\u0105da to tak:<\/p>\n<pre><code class=\"plaintext\">GOROOT=\"\/opt\/tls-tris\/_dev\/GOROOT\/linux_amd64\" go build \u2026.<\/code><\/pre>\n<p>\nNast\u0119pnie musimy zaimplementowa\u0107 w tunelu funkcjonalno\u015b\u0107 do zapytania i parsowania publicznych kluczy eSNI dla odpowiedniej domeny. W naszym przypadku b\u0119d\u0105 to publiczne klucze eSNI z serwer\u00f3w frontowych CloudFlare. W tym celu stworzymy trzy funkcje:<\/p>\n<pre><code class=\"plaintext\">func makeDoTQuery(dnsName string) ([]byte, error)\nfunc parseTXTResponse(buf []byte, wantName string) (string, error)\nfunc QueryESNIKeysForHost(hostname string) ([]byte, error)<\/code><\/pre>\n<p>\nNazwy funkcji w zasadzie m\u00f3wi\u0105 same za siebie. Wype\u0142nienie we\u017amiemy z pliku esni_query.go, kt\u00f3ry jest cz\u0119\u015bci\u0105 tls-tris. Pierwsza funkcja tworzy pakiet sieciowy z zapytaniem do serwera DNS CloudFlare, u\u017cywaj\u0105c protoko\u0142u DoH (DNS-over-HTTPS), druga \u2013 parsuje wyniki zapytania i pobiera warto\u015bci publicznych kluczy domeny, a trzecia jest kontenerem dla pierwszych dw\u00f3ch.<\/p>\n<p>Nast\u0119pnie wprowadzamy nasz\u0105 nowo stworzon\u0105 funkcj\u0119 do\u0142\u0105czenia do WebSocket. <i><b>connectForWsSocks<\/b><\/i> funkcjonalno\u015b\u0107 zapytania kluczy eSNI dla domeny. Tam, gdzie dzia\u0142a cz\u0119\u015b\u0107 serwerowa, ustawiamy parametry TLS oraz definiujemy nazw\u0119 fa\u0142szywego \u201edomeny przykrywaj\u0105cej\u201d:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/63abc51177058223e0f0941a78d182fa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNale\u017cy zauwa\u017cy\u0107, \u017ce pocz\u0105tkowo ga\u0142\u0105\u017a tls-tris nie by\u0142a przystosowana do zastosowania domain fronting. W zwi\u0105zku z tym nie po\u015bwi\u0119cono uwagi fa\u0142szywej nazwie serwera (w pakiecie client-hello przekazywane jest puste pole serverName). Aby to naprawi\u0107, b\u0119dziemy musieli doda\u0107 odpowiednie pole FakeServerName do struktury TlsConfig. Standardowego pola ServerName w tej strukturze nie mo\u017cemy u\u017cywa\u0107, poniewa\u017c wykorzystuj\u0105 je wewn\u0119trzne mechanizmy tls i je\u015bli b\u0119dzie r\u00f3\u017cni\u0107 si\u0119 od oryginalnego, to tls-handshake zako\u0144czy si\u0119 b\u0142\u0119dem. Opis struktury TlsConfig znajduje si\u0119 w pliku <b>tls\/common.go<\/b> \u2013 kt\u00f3ry musimy poprawi\u0107:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/04f35bb49a5f6a28625de28b23d686f0.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/0caf5cfccb2ffffeae703ecfe3eb6652.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDodatkowo musimy wprowadzi\u0107 zmiany w pliku <b>tls\/handshake_client.go<\/b>, aby u\u017cy\u0107 naszego pola FakeServerName podczas formowania negocjacji TLS:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/ac68f37f426603b2fcec467c6ee886ca.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo wszystko! Mo\u017cna kompilowa\u0107 projekt i sprawdza\u0107 dzia\u0142anie. Ale zanim uruchomisz test, musisz skonfigurowa\u0107 konto CloudFlare. Jak to powiedzie\u0107, skonfigurowa\u0107 - po prostu utworzy\u0107 konto na CloudFlare i powi\u0105za\u0107 swoj\u0105 domen\u0119. Wszystkie funkcje zwi\u0105zane z DoH, WebSocket i ESNI s\u0105 domy\u015blnie w\u0142\u0105czone w CloudFlare. Po zaktualizowaniu rekord\u00f3w DNS - mo\u017cna sprawdzi\u0107 dzia\u0142anie domeny, wykonuj\u0105c zapytanie o klucze eSNI:<\/p>\n<pre><code class=\"plaintext\">dig +short txt _esni.df13tester.info <\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/09d07d1f49defc3551c3720d9b67569e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe\u015bli widzisz co\u015b podobnego dla swojej domeny - to znaczy, \u017ce wszystko dzia\u0142a i mo\u017cesz przej\u015b\u0107 do testowania.<\/p>\n<p>Uruchamiamy VPS Ubuntu, na przyk\u0142ad na DigitalOcean. P.S. W naszym przypadku w\u0142a\u015bnie przyznany przez dostawc\u0119 adres IP VPS znalaz\u0142 si\u0119 na czarnej li\u015bcie RKN. Wi\u0119c nie zdziw si\u0119, je\u015bli zdarzy si\u0119 co\u015b podobnego. Musia\u0142em skorzysta\u0107 z VPN, aby dosta\u0107 si\u0119 na sw\u00f3j VPS.<\/p>\n<p>Kopiujemy na VPS ju\u017c skompilowany rsockstun (w tym, swoj\u0105 drog\u0105, jeszcze jedna zaleta Golanga - mo\u017cna skompilowa\u0107 projekt na swoim sprz\u0119cie i uruchomi\u0107 go na dowolnym Linuksie, przestrzegaj\u0105c tylko architektury systemu) i uruchamiamy cz\u0119\u015b\u0107 serwerow\u0105:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/f86be92203d646832205fb611fe4d056.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA nast\u0119pnie cz\u0119\u015b\u0107 klienck\u0105:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/c8852d7431e8bba7eab1494989ceb46d.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJak widzimy, klient pomy\u015blnie po\u0142\u0105czy\u0142 si\u0119 z serwerem przez serwer frontendowy CloudFlare za pomoc\u0105 WebSocket. Aby sprawdzi\u0107, czy tunel dzia\u0142a jako tunel, mo\u017cna wykona\u0107 zapytanie curl przez lokalnego socks5, otwartego na serwerze:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/87b6f42676e5e895b7f7b03da16420bb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTeraz zobaczmy, co widzi DPI w kanale komunikacyjnym:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/d546b676904d5b8ded7e0891ff5a98e6.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNajpierw tunel z wykorzystaniem mechanizmu DoH zwraca si\u0119 do serwera DNS Cloudflare po klucze eSNI dla domeny docelowej (pakiety nr 1-19), a nast\u0119pnie zwraca si\u0119 do serwera frontendowego i ustanawia po\u0142\u0105czenie TLS, ukrywaj\u0105c si\u0119 przy tym za domen\u0105 <noindex><a rel=\"nofollow\" href=\"http:\/\/www.google.com\">www.google.com<\/a><\/noindex> (to jest warto\u015b\u0107 domy\u015blna, gdy podczas uruchamiania klienta nie jest podana fa\u0142szywa domena). Aby wskaza\u0107 swoj\u0105 fa\u0142szyw\u0105 domen\u0119, nale\u017cy u\u017cy\u0107 parametru -fronfDomain:<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/3f55e03eecd7436b1e9c2312d88b46af.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/da5e219fb5a097e6ad6d75844d7a5687.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTeraz jeszcze jedna kwestia. Domy\u015blnie w ustawieniach konta na CloudFlare w\u0142\u0105czony jest tryb Flexible SSL. Oznacza to, \u017ce zapytania https do serwer\u00f3w frontendowych Cloudflare od klient\u00f3w b\u0119d\u0105 przekierowywane w niezaszyfrowanej (http) formie na nasz serwer. Dlatego uruchomili\u015bmy cz\u0119\u015b\u0107 serwerow\u0105 tunelera w trybie non-ssl (-listen ws:0.0.0.0), a nie (-listen wss:0.0.0.0).<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/17f820b973f8a3f26f78a30c10bdb493.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAby prze\u0142\u0105czy\u0107 si\u0119 w tryb pe\u0142nego szyfrowania, nale\u017cy wybra\u0107 <b>Full<\/b>, lub <b>Full (strict)<\/b> w przypadku posiadania odpowiedniego certyfikatu na serwerze. Po prze\u0142\u0105czeniu trybu b\u0119dziemy mogli akceptowa\u0107 po\u0142\u0105czenia od CloudFlare za pomoc\u0105 protoko\u0142u https. Nie zapomnij wygenerowa\u0107 certyfikatu self-signed dla serwera tunelera.<\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/c9a05134c9ba01e6008b4432cf59c74e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDociekliwy czytelnik zapyta: \u201eA co z klientem pod Windows? Przecie\u017c zapewne g\u0142\u00f3wne zastosowanie tunelera to uruchamianie back-connect z komputer\u00f3w i serwer\u00f3w korporacyjnych, a tam zazwyczaj zawsze jest Windows. Jak mog\u0119 skompilowa\u0107 tuneler pod Windows, jeszcze ze specyficznym stosem TLS?\u201d A teraz przedstawimy jeszcze jedn\u0105 funkcj\u0119, kt\u00f3ra pokazuje, jak wygodny jest Go. Kompilujemy pod Windows bezpo\u015brednio z Kali, po prostu dodaj\u0105c parametr GOOS=windows:<\/p>\n<pre><code class=\"plaintext\">GOARCH=amd64 GOROOT=\"\/opt\/tls-tris\/_dev\/GOROOT\/linux_amd64\" GOOS=windows  go build -ldflags=\"-s -w\"<\/code><\/pre>\n<p>\nLub 32-bitowa wersja:<\/p>\n<pre><code class=\"plaintext\">GOARCH=386 GOROOT=\"\/opt\/tls-tris\/_dev\/GOROOT\/linux_amd64\" GOOS=windows  go build -ldflags=\"-s -w\"<\/code><\/pre>\n<p>\nTo wszystko! I wi\u0119cej \u017cadnych problem\u00f3w. To naprawd\u0119 dzia\u0142a! <\/p>\n<p><img decoding=\"async\" alt=\"Frontering domen na bazie TLS 1.3. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2019\/11\/2c60d41c115b8df32a8b53b06a45e915.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFlagi kompilatora \u2013w i \u2013s s\u0105 potrzebne, aby usun\u0105\u0107 zb\u0119dne dane z pliku wykonywalnego, co sprawia, \u017ce jest on mniejszy o kilka megabajt\u00f3w. Dodatkowo mo\u017cna go p\u00f3\u017aniej spakowa\u0107 za pomoc\u0105 UPX, aby jeszcze bardziej zmniejszy\u0107 rozmiar.<\/p>\n<h3>Zamiast zako\u0144czenia<\/h3>\n<p>\nW artykule na przyk\u0142adzie napisanego w Go tunelera pokazali\u015bmy zastosowanie nowej technologii domain-frontingu, zrealizowanej na do\u015b\u0107 interesuj\u0105cej w\u0142a\u015bciwo\u015bci protoko\u0142u TLS 1.3. W podobny spos\u00f3b mo\u017cna dostosowa\u0107 istniej\u0105ce narz\u0119dzia napisane w Go do pracy przez serwery CloudFlare, na przyk\u0142ad <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Ne0nd0g\/merlin\">Merlin<\/a><\/noindex> \u2014 znany C2, lub zmusi\u0107 CobaltStrike Beacon do u\u017cycia eSNI domain-frontingu przy pracy z Teamserver przez <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ryhanson\/ExternalC2\">External C2 Channel<\/a><\/noindex>, zrealizowany w Go, lub te\u017c w standardowym C++ z u\u017cyciem spatchowanej wersji OpenSSL, o kt\u00f3rej m\u00f3wili\u015bmy w poprzedniej cz\u0119\u015bci artyku\u0142u. W skr\u00f3cie, wyobra\u017ani nie ma ko\u0144ca.<\/p>\n<p>Przyk\u0142ad z tunelerem i CloudFlare przedstawiony jest jako koncepcja i na razie trudno m\u00f3wi\u0107 o dalszych perspektywach tego rodzaju domain-frontingu. Na ten moment wsparcie eSNI jest zrealizowane tylko przez CloudFlare i teoretycznie nic nie stoi na przeszkodzie, aby wy\u0142\u0105czyli tego rodzaju fronting i, na przyk\u0142ad, przerywali po\u0142\u0105czenia tls przy niesp\u00f3jno\u015bci SNI i eSNI. W skr\u00f3cie, przysz\u0142o\u015b\u0107 poka\u017ce. Ale na razie perspektywa pracy pod \u201emask\u0105 kremlin.ru\u201d wydaje si\u0119 ca\u0142kiem kusz\u0105ca. Czy\u017c nie?<\/p>\n<p>Zaktualizowany kod tunelera, a tak\u017ce skompilowane pliki wykonywalne exe zosta\u0142y umieszczone w oddzielnej ga\u0142\u0119zi projektu na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/mis-team\/rsockstun\">github<\/a><\/noindex>. O wszelkich mo\u017cliwych problemach z tunelerem najlepiej pisa\u0107 issue na stronie projektu na GitHubie.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/477696\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0434\u0430\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 encrypted SNI (eSNI). \u041f\u043e\u043a\u0430\u0437\u0430\u043b\u0438 \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u043b\u043e\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0435\u0442\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 DPI-\u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 (\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0438\u043b\u0430\u0439\u043d\u043e\u0432\u0441\u043a\u043e\u0433\u043e DPI \u0438 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0420\u041a\u041d \u0440\u0443\u0442\u0440\u0435\u043a\u0435\u0440\u0430), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043e\u043c\u0435\u043d-\u0444\u0440\u043e\u043d\u0442\u0438\u043d\u0433\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430. \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0432\u0435\u0449\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-53317","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0434\u0430\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 encrypted SNI (eSNI).\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/domen-fronting-na-baze-tls-1-3-chast-2\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0414\u043e\u043c\u0435\u043d-\u0444\u0440\u043e\u043d\u0442\u0438\u043d\u0433 \u043d\u0430 \u0431\u0430\u0437\u0435 TLS 1.3. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0434\u0430\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 encrypted SNI (eSNI).\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/domen-fronting-na-baze-tls-1-3-chast-2\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-28T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:01:12+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Domain Fronting na bazie TLS 1.3. Cz\u0119\u015b\u0107 2 | ProHoster","description":"Wprowadzenie W pierwszej cz\u0119\u015bci artyku\u0142u przedstawili\u015bmy kr\u00f3tkie wprowadzenie do mechanizmu encrypted SNI (eSNI).","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/domen-fronting-na-baze-tls-1-3-chast-2","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0414\u043e\u043c\u0435\u043d-\u0444\u0440\u043e\u043d\u0442\u0438\u043d\u0433 \u043d\u0430 \u0431\u0430\u0437\u0435 TLS 1.3. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster","og:description":"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0434\u0430\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 encrypted SNI (eSNI).","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/domen-fronting-na-baze-tls-1-3-chast-2","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-28T21:00:00+00:00","article:modified_time":"2020-02-18T11:01:12+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"53317","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 06:55:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:27:38","updated":"2026-01-24 06:55:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/53317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=53317"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/53317\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=53317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=53317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=53317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}