Hyrje
Në pjesën e parë ne dhamë një përshkrim të shkurtër të mekanizmit të SNI të enkriptuar (eSNI). Të treguam se si mbi të mund të shmangim zbulimin nga sistemet moderne të DPI (me shembuj si DPI i Beeline dhe ruxhja e ndaluar RKN), si dhe kërkuam një variant të ri të domen-fronit që bazohet në këtë mekanizëm.
Në pjesën e dytë të artikullit do të kalojmë në aspekte më praktike, të cilat do të jenë të dobishme për specialistët e RedTeam në punën e tyre të ndërlikuar. Më në fund, qëllimi ynë nuk është të marrim akses në burimet e bllokuara (për këto gjëra ka VPN-in e mirë të vjetër). Ka shumë ofrues VPN, siç thuhet, për çdo shije, ngjyrë dhe buxhet.
Ne do të përpiqemi të aplikojmë mekanizmin e domen-fronting për mjetet moderne të RedTeam, siç janë Cobalt Strike, Empire etj., dhe t'u japim atyre mundësi të shtesë për mimikrim dhe shmangie nga sistemet moderne të filtrimit të përmbajtjes.
HerĂ«n e fundit implementuam mekanizmin e eSNI nĂ« bibliotekĂ«n OpenSSL dhe e pĂ«rdorĂ«m me sukses nĂ« utilitarin e njohur pĂ«r tĂ« gjithĂ« curl. Por vetĂ«m me curl, siç thonĂ«, nuk ngopesh. Sigurisht, do tĂ« dĂ«shironim tĂ« realizonim diçka tĂ« ngjashme nĂ« gjuhĂ«t e nivelit tĂ« lartĂ«. Por, fatkeqĂ«sisht, njĂ« kĂ«rkim i shpejtĂ« nĂ« hapĂ«sirĂ«n e internetit na bĂ«n tĂ« zhgĂ«njehemi, sepse mbĂ«shtetje tĂ« plote pĂ«r mekanizmin e eSNI Ă«shtĂ« realizuar vetĂ«m nĂ« GOLANG. KĂ«shtu, zgjedhja jonĂ« nuk Ă«shtĂ« shumĂ« e madhe: ose shkruajmĂ« nĂ« C tĂ« pastĂ«r ose C++ duke pĂ«rdorur bibliotekĂ«n e pĂ«rmirĂ«suar OpenSSL, ose pĂ«rdorim njĂ« fork tĂ« veçantĂ« tĂ« GOLANG nga CloudFlare dhe pĂ«rpiqemi ta portojmĂ« mjetin tonĂ« atje. NĂ« parim, ka edhe njĂ« mundĂ«si tjetĂ«r, mĂ« klasike, por njĂ«kohĂ«sisht e lodhshme â tĂ« implementojmĂ« mbĂ«shtetje pĂ«r eSNI pĂ«r Python. MĂ« nĂ« fund, Python gjithashtu pĂ«rdor OpenSSL pĂ«r tĂ« punuar me https. Por kĂ«tĂ« mundĂ«si do ta lĂ«mĂ« pĂ«r t'u zhvilluar nga dikush tjetĂ«r, ndĂ«rsa ne do tĂ« jemi tĂ« kĂ«naqur me realizimin nĂ« GOLANG, sidomos qĂ« Cobalt Strike ynĂ« i preferuar e di mirĂ« se si tĂ« punojĂ« me njĂ« kanal komunikimi tĂ« ndĂ«rtuar nga mjete tĂ« jashtme (kanali External C2) â pĂ«r kĂ«tĂ« do tĂ« flasim nĂ« fund tĂ« artikullit.
Try HarderâŠ
NjĂ« nga mjetet e realizuara nĂ« Go â zhvillimi ynĂ« pĂ«r pivoting brenda rrjetit â tuneluesi , i cili, pĂ«r t'iu referuar, aktualisht detektohet nga mjetet e kompanive Microsoft dhe Symantec si njĂ« software shumĂ« i dĂ«mshĂ«m, i orientuar drejt shkeljes sĂ« stabilitetit globalâŠ

Do tĂ« ishte e shkĂ«lqyer tĂ« pĂ«rdornim zhvillimin e mĂ«parshĂ«m edhe nĂ« kĂ«tĂ« rast. Por kĂ«tu lind njĂ« problem i vogĂ«l. Problemi Ă«shtĂ« se fillimisht rsockstun parashikon pĂ«rdorimin e njĂ« kanali tĂ« zakonshĂ«m SSL pĂ«r lidhjen me serverin. Kjo do tĂ« thotĂ« se lidhja krijohet njĂ« herĂ« dhe ekziston gjatĂ« gjithĂ« kohĂ«s sĂ« funksionimit tĂ« tunelit. Dhe, siç e kuptoni, protokolli https paksa nuk Ă«shtĂ« i dizajnuar pĂ«r kĂ«tĂ« mod pĂ«rdorimi â ai punon nĂ« modin kĂ«rkesĂ«- pĂ«rgjigje, ku çdo kĂ«rkesĂ« e re http ekziston brenda kuadrit tĂ« njĂ« lidhjeje tĂ« re tcp.
Defekti kryesor i kĂ«tij skeme Ă«shtĂ« se serveri nuk mund tĂ« transmetojĂ« tĂ« dhĂ«na klientit, derisa klienti tĂ« dĂ«rgojĂ« njĂ« kĂ«rkesĂ« tĂ« re http. MegjithatĂ«, pĂ«r fat tĂ« mirĂ«, ekzistojnĂ« shumĂ« opsione pĂ«r zgjidhjen e kĂ«tij problemi â transmetimi i tĂ« dhĂ«nave nĂ«pĂ«rmjet protokollit http (mjerĂ« qĂ« arrijmĂ« siç e bĂ«jmĂ« tĂ« shikojmĂ« serialet tona tĂ« preferuara dhe tĂ« dĂ«gjojmĂ« muzikĂ« nga portalet qĂ« punojnĂ« nĂ« https, dhe transmetimi i videos dhe audios â nuk Ă«shtĂ« asgjĂ« tjetĂ«r pĂ«rveç transmetimit tĂ« tĂ« dhĂ«nave). NjĂ« nga teknologjitĂ« pĂ«r tĂ« emuluar funksionimin e njĂ« lidhjeje tĂ« plotĂ« tcp mbi protokollin http Ă«shtĂ« teknologjia e web-socket-Ă«ve (WebSockets), thelbi i sĂ« cilĂ«s Ă«shtĂ« organizimi i njĂ« lidhjeje tĂ« plotĂ« nĂ« rrjet midis klientit dhe serverit web.
Për fatin tonë (hurra-hurra!!!), kjo teknologji është e përfshirë siç duhet në të gjitha planet tarifore të CloudFlare dhe funksionon shkëlqyer së bashku me eSNI. Pikërisht këtë do ta përdorim për të mësuar tuneluesin tonë të përdorë domenin e përparshëm dhe të fshihet nga DPI-të moderne.
Pak për WebSockets
Së pari, do të flasim shkurtimisht dhe me fjalë të thjeshta për web-socket-et, në mënyrë që të gjithë të kenë një ide për atë me çfarë do të punojmë.
Teknologjia e web-socket-ëve lejon kalimin përkohësisht nga lidhja http në transmetim standard të të dhënave përmes një socket-i rrjeti, pa ndarë lidhjen tcp të krijuar. Kur klienti dëshiron të kalojë në web-socket, ai në kërkesën e tij http vendos disa headers http. Dy headers të detyrueshëm janë Connection: Upgrade dhe Upgrade: websocket. Ai gjithashtu mund të tregojë me forcë versionin e protokollit websocket (Sec-Websockset-Version: 13) dhe diçka si identifikuesi base64 i web-socket (Sec-WebSocket-Key: DAGDJSiREI3+KjDfwxm1FA==). Serveri përgjigjet me kodi http 101 Switching Protocols dhe gjithashtu vendos headerët Connection, Upgrade dhe Sec-WebSocket-Accept. Procesi i kalimit është ilustruar në screenshotin më poshtë:

Pas kĂ«saj, vendosja e lidhjes WebSocket mund tĂ« konsiderohet e pĂ«rfunduar. Ădo tĂ« dhĂ«nĂ«, si nga klienti ashtu edhe nga serveri, tani do tĂ« dĂ«rgohet me headerĂ« tĂ« WebSocket (fillojnĂ« me bajtin 0x82). Tani serveri nuk ka nevojĂ« tĂ« presĂ« njĂ« kĂ«rkesĂ« nga klienti pĂ«r tĂ« dĂ«rguar tĂ« dhĂ«na, pasi lidhja tcp nuk ndĂ«rpritet.
Në Golang, ka disa biblioteka për punën me web-sockets. Më të njohurat janë dhe standardi . Ne do të përdorim të fundit, pasi është më e thjeshtë, më e vogël dhe funksionon, siç thuhet, pak më shpejt.
Në kodin e klientit rsockstun, ne duhet të zëvendësojmë thirrjet net.dial ose tls.dial me thirrjet përkatëse të WebSocket:


Ne duam tĂ« bĂ«jmĂ« pjesĂ«n klient tĂ« tunelit tonĂ« universale dhe tĂ« aftĂ« tĂ« funksionojĂ« si pĂ«rmes njĂ« lidhjeje tĂ« drejtpĂ«rdrejtĂ« ssl, ashtu edhe pĂ«rmes protokollit WebSocket. PĂ«r kĂ«tĂ«, ne do tĂ« krijojmĂ« njĂ« funksion tĂ« veçantĂ« func connectForWsSocks(address string, proxy string) error {âŠ} me analogji me connectForSocks() dhe do ta pĂ«rdorim atĂ« pĂ«r tĂ« punuar me web-sockets nĂ« rast se adresa e serverit, e cila Ă«shtĂ« caktuar gjatĂ« fillimit tĂ« klientit, fillon me ws: ose wss: (nĂ« rastin e WebSocket-it tĂ« Sigurt).
Për pjesën server të tunelit, ne gjithashtu do të krijojmë një funksion të veçantë për punën me web-sockets. Në të, do të krijohet një instancë e klasës http dhe do t'i caktohet një trajtues i lidhjes http (funksioni wsHandler):

Dhe të gjitha logjikat e trajtimit të lidhjes (autorizimi i klientit me fjalëkalim, vendosja dhe përfundimi i sesionit yamux) do t'i vendosim te trajtuesi i lidhjes WebSocket:

Kompilojmë projektin, fillojmë pjesën server:
.\/rsockstun âlisten ws:127.0.0.1:8080 âpass P@ssw0rdDhe pastaj pjesĂ«n klient:
.\/rsockstun -connect ws:127.0.0.1:8080 âpass P@ssw0rdDhe verifikojmĂ« funksionimin nĂ« hostin lokal:


Kalo në domain-fronting
Me web-sockets duket se e kemi kuptuar situatën. Tani le të kalojmë drejtpërdrejt në eSNI dhe domain-fronting. Siç u tha më parë, për të punuar me DoH dhe eSNI, na nevojitet një degë speciale golang nga kompania . Na nevojitet një degë me mbështetje eSNI (pwu/esni).
Klonojmë atë lokalisht ose e shkarkojmë dhe e çzipojmë zip-in përkatës:
git clone -b pwu/esni https://github.com/cloudflare/tls-tris.gitPastaj duhet tĂ« kopjojmĂ« katalogun GOROOT, tĂ« zĂ«vendĂ«sojmĂ« skedarĂ«t pĂ«rkatĂ«s nga dega e klonuar dhe ta vendosim atĂ« si kryesor. PĂ«r tĂ« shpĂ«tuar zhvilluesin nga kjo dhimbje koke, ekipi nĂ« CloudFlare ka pĂ«rgatitur njĂ« skenar tĂ« veçantĂ« â _dev/go.sh. Thjesht e aktivizojmĂ« atĂ«. Skripti, sĂ« bashku me makefile, do tĂ« bĂ«jĂ« gjithçka vetĂ«. PĂ«r kuriozitet, mund tĂ« shikoni brenda makefile pĂ«r detaje.
Pas përfundimit të skriptit, gjatë kompilimit të projektit, na nevojitet të specifikojmë katalogun lokal si GOROOT, i përgatitur nga skripti. Në rastin tonë, kjo duket kështu:
GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" go build ....Më pas, na nevojitet të zbatojmë në tunelimin e funksionalitetit për kërkimin dhe analizimin e çelësave publikë eSNI për domenin e nevojshëm. Në rastin tonë, këta do të jenë çelësat publikë eSNI nga serverët frontend të CloudFlare. Për këtë, do të krijojmë tre funksione:
func makeDoTQuery(dnsName string) ([]byte, error)
func parseTXTResponse(buf []byte, wantName string) (string, error)
func QueryESNIKeysForHost(hostname string) ([]byte, error)Emrat e funksioneve, nĂ« parim, e thonĂ« vetĂ«. PĂ«rmbajtja do ta marrim nga skedari esni_query.go, qĂ« Ă«shtĂ« pjesĂ« e tls-tris. Funksioni i parĂ« krijon njĂ« paketĂ« rrjeti me njĂ« kĂ«rkesĂ« pĂ«r serverin DNS tĂ« CloudFlare, duke pĂ«rdorur protokollin DoH (DNS-over-HTTPS), i dyti â analizojnĂ« rezultatet e kĂ«rkesĂ«s dhe marrin vlerat e çelĂ«save publikĂ« tĂ« domenit, ndĂ«rsa i treti Ă«shtĂ« njĂ« kontejner pĂ«r tĂ« parĂ«t dy.
Më pas, ne e shtojmë në funksionin tonë të sapo krijuar lidhjen e web-socket-it connectForWsSocks funksionalitetin për kërkimin e çelësave eSNI për domenin. Atje ku funksionon pjesa server, vendosim parametrat TLS, si dhe caktuam emrin e domenit të rremë:

KĂ«tu duhet tĂ« theksohet se fillimisht, dega tls-tris nuk Ă«shtĂ« projektuar pĂ«r pĂ«rdorimin e domenit tĂ« maskuar. Prandaj, nuk i Ă«shtĂ« kushtuar vĂ«mendje emrit tĂ« rremĂ« tĂ« serverit (nĂ« paketĂ«n client-hello, transmetohet njĂ« fushĂ« e zbrazĂ«t serverName). PĂ«r ta korrigjuar kĂ«tĂ«, na nevojitet tĂ« shtojmĂ« nĂ« strukturĂ«n TlsConfig fushĂ«n e duhur FakeServerName. Nuk mund ta pĂ«rdorim fushĂ«n standarde ServerName tĂ« strukturĂ«s, pasi e pĂ«rdorin mekanizmat e brendshĂ«m tls dhe nĂ«se ajo ndryshon nga origjinali, atĂ«herĂ« tls-handshake do tĂ« pĂ«rfundojĂ« me njĂ« gabim. PĂ«rshkrimi i strukturĂ«s TlsConfig ndodhet nĂ« skedarin tls/common.go â dhe atĂ« do ta kemi pĂ«r tĂ« korrigjuar:


Shtesë, na nevojitet të bëjmë ndryshime në skedarin tls/handshake_client.go, për të përdorur fushën tonë FakeServerName gjatë formimit të TLS handshakes:

KĂ«tu pĂ«rfundon! Tani mund tĂ« kompilohet projekti dhe tĂ« kontrollohet funksionaliteti. Por para se tĂ« filloni kontrollet, Ă«shtĂ« e nevojshme tĂ« konfiguroni llogarinĂ« CloudFlare. Si tĂ« thuash ta konfiguroni â vetĂ«m krijoni njĂ« llogari nĂ« CloudFlare dhe lidheni domenin tuaj me tĂ«. TĂ« gjitha veçoritĂ« lidhur me DoH, WebSocket dhe ESNI janĂ« tĂ« aktivizuara nĂ« CloudFlare si parazgjedhje. Pas pĂ«rditĂ«simit tĂ« rekordeve DNS â mund tĂ« kontrolloni funksionimin e domenit duke bĂ«rĂ« njĂ« kĂ«rkesĂ« pĂ«r çelĂ«sat e eSNI:
dig +short txt _esni.df13tester.info 
NĂ«se shihni diçka tĂ« ngjashme pĂ«r domenin tuaj â atĂ«herĂ« gjithçka funksionon dhe mund tĂ« kaloni nĂ« testim.
Nisim një Ubuntu VPS, për shembull, në DigitalOcean. P.S. Në rastin tonë, adresa IP e ofruar nga provider-i për VPS ishte në listat e zeza të RKN. Pra, mos u habitni nëse ndodh diçka e ngjashme me ju. Duhej të përdorim një VPN për të aksesuar VPS-në tonë.
KopjojmĂ« nĂ« VPS rsockstun tĂ« kompiliuar mĂ« parĂ« (nĂ« kĂ«tĂ«, ndonjĂ«herĂ«, Ă«shtĂ« njĂ« tjetĂ«r kĂ«naqĂ«si e Golang â mund tĂ« kompilohet projekti tuaj dhe ta ekzekutoni nĂ« çdo Linux, pĂ«r sa kohĂ« qĂ« pĂ«rmbushni vetĂ«m arkitekturĂ«n e sistemit) dhe nisim pjesĂ«n server:

Dhe pastaj pjesën klient:

Siç e shohim, klienti u lidh me sukses me serverin përmes serverit frontend të CloudFlare duke përdorur websockets. Për të kontrolluar nëse tuneli funksionon si një tunel, mund të bëni një kërkesë curl përmes socks5 lokal, të hapur në server:

Tani le të shohim se çfarë sheh DPI në kanal:

Së pari, tuneluesi, duke përdorur mekanizmin DoH, i drejtohet serverit DNS të Cloudflare për çelësat e eSNI për domenin e destinacionit (paketat #1-19), dhe pastaj i drejtohet serverit frontend dhe krijon një lidhje TLS, duke u mbuluar me domenin (kjo është vlera parazgjedhje, kur klienti niset pa përcaktuar një domen fals). Për të caktuar domenin tuaj fals, duhen përdorur parametra -fronfDomain:
![]()

Tani një pikë tjetër. Sipas parazgjedhjes, në cilësimet e llogarisë në CloudFlare është vendosur regjimi Flexible SSL. Kjo do të thotë se kërkesat https nga klientët ndaj serverëve frontend të Cloudflare do të redirektohen në mënyrë të pa enkriptuar (http) tek serveri ynë. Pikërisht për këtë shkak, ne e nisëm pjesën server të tuneluesit në modin non-ssl (-listen ws:0.0.0.0), dhe jo (-listen wss:0.0.0.0).

Për të kaluar në regjimin e enkriptimit të plotë, është e nevojshme të zgjidhni Full, ose Full (strict) në rast se ka një certifikatë të vërtetë në server. Pasi të kalojmë në modalitet tjetër, do të jemi në gjendje të pranojmë lidhje nga CloudFlare përmes protokollit https. Mos harroni të gjeneroni një certifikatë self-signed për pjesën server të tunelit.

Një lexues i kujdesshëm do të pyesë: "Si qëndron puna me klientin për Windows? Sigurisht, aplikimi kryesor i tunelit është ngushtimi i një lidhjeje mbrapa nga makinat dhe serverët korporatë, dhe aty zakonisht është gjithmonë Windows. Si ta kompiloje tunelin për Windows, duke e pasur parasysh strukturën specifike të TLS?" Tani do të paraqesim një tjetër veçori që tregon sa e lehtë është Go. Kompilohet për Windows direkt nga Kali, thjesht duke shtuar parametrin GOOS=windows:
GOARCH=amd64 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"Ose varianti 32-bit:
GOARCH=386 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"Kaq! Dhe asnjë problem tjetër nuk nevojitet. Kjo do të thotë se funksionon!

Flamujt e kompilatorit âw dhe âs janĂ« tĂ« nevojshme pĂ«r tĂ« hequr mbetje tĂ« panevojshme nga skedari ekzekutiv, duke e bĂ«rĂ« atĂ« mĂ« tĂ« vogĂ«l pĂ«r disa megabajt. SĂ« fundi, mund tĂ« paketoni gjithashtu me ndihmĂ«n e UPX pĂ«r tĂ« zvogĂ«luar akoma mĂ« shumĂ« madhĂ«sinĂ«.
Në përfundim
NĂ« kĂ«tĂ« artikull, ne, pĂ«rmes shembullit tĂ« tunelit tĂ« shkruar nĂ« Go, demonstruam aplikimin e teknologjisĂ« sĂ« re tĂ« domain-fronting, e realizuar nĂ« njĂ« veçori mjaft interesante tĂ« protokollit TLS 1.3. NĂ« mĂ«nyrĂ« tĂ« ngjashme, mund tĂ« adaptohet mjetet ekzistues tĂ« shkruara nĂ« Go pĂ«r tĂ« punuar pĂ«rmes serverĂ«ve CloudFlare, pĂ«r shembull, â njĂ« C2 i njohur, ose tĂ« detyrojĂ« CobaltStrike Beacon tĂ« pĂ«rdorĂ« domain-fronting eSNI kur punon me Teamserver pĂ«rmes , i realizuar nĂ« Go, ose nĂ« standardin C++ duke pĂ«rdorur versionin e patchuar tĂ« OpenSSL, pĂ«r tĂ« cilin folĂ«m nĂ« pjesĂ«n e kaluar tĂ« artikullit. NĂ« pĂ«rgjithĂ«si, imagjinata nuk ka limite.
Shembulli me tunelin dhe CloudFlare është i paraqitur si një koncept dhe deri tani është e vështirë të flasim për perspektivat e tilla në të ardhmen. Në këtë moment, mbështetja e eSNI është realizuar vetëm nga CloudFlare dhe, në parim, asgjë nuk i pengon ata të çaktivizojnë këtë lloj fronti dhe, për shembull, të ndërpresin lidhjet tls në rast të mos përputhjes midis SNI dhe eSNI. Në përgjithësi, e ardhmja do ta tregojë. Por për momentin, perspektiva e punës nën "mbrojtjen e kremlin.ru" duket mjaft joshëse. A nuk është kështu?
Kodi i azhurnuar i tunnelerit, si dhe skedarët ekzekutivë exe të kompiluara janë vendosur në një degë të veçantë të projektit në . Për çdo problem të mundshëm me tunnelerin, më mirë të shkruani një problem në faqen e projektit në GitHub.
Burimi: habr.com
