Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

pengenalan

Di bagian pertama Artikel Kami telah memberikan gambaran singkat tentang mekanisme SNI terenkripsi (eSNI). Mereka menunjukkan bagaimana, berdasarkan itu, dimungkinkan untuk menghindari deteksi oleh sistem DPI modern (menggunakan contoh Beeline DPI dan pelacak akar RKN yang dilarang), dan juga mengeksplorasi versi baru dari domain fronting berdasarkan mekanisme ini.

Di bagian kedua artikel, kita akan beralih ke hal-hal yang lebih praktis yang akan berguna bagi spesialis RedTeam dalam pekerjaan sulit mereka. Pada akhirnya, tujuan kami bukanlah untuk mendapatkan akses ke sumber daya yang diblokir (untuk hal-hal sepele seperti itu kami memiliki VPN lama yang bagus). Untungnya, ada banyak sekali penyedia VPN, seperti yang mereka katakan, untuk setiap selera, warna, dan anggaran.

Kami akan mencoba menerapkan mekanisme domain-fronting ke alat RedTeam modern, misalnya Cobalt Strike, Empire, dll., dan memberi mereka kemampuan tambahan untuk meniru dan menghindari sistem pemfilteran konten modern.

Terakhir kali kami mengimplementasikan mekanisme eSNI ke dalam pustaka OpenSSL dan berhasil menggunakannya di utilitas curl yang sudah dikenal. Tapi, seperti kata pepatah, Anda tidak akan puas hanya dengan satu ayam. Tentu saja, saya ingin menerapkan hal serupa dalam bahasa tingkat tinggi. Namun sayangnya, pencarian cepat di Internet mengecewakan kami, karena dukungan terhadap mekanisme eSNI hanya diterapkan sepenuhnya di GOLANG. Oleh karena itu, kami tidak punya banyak pilihan: kami menulis dalam C murni atau C++ menggunakan pustaka OpenSSL yang telah dipatch, atau kami menggunakan fork GOLANG terpisah dari CloudFlare dan mencoba mem-porting alat kami ke sana. Pada prinsipnya, ada opsi lain, yang lebih klasik, tetapi pada saat yang sama memakan waktu - untuk mengimplementasikan dukungan eSNI untuk Python. Lagipula, Python juga menggunakan OpenSSL untuk menangani https. Namun kami akan menyerahkan opsi ini untuk pengembangan oleh orang lain, dan kami sendiri akan puas dengan penerapannya di Golang, terutama karena Cobalt Strike kesayangan kami mampu bekerja dengan sempurna dengan saluran komunikasi yang dibangun oleh alat pihak ketiga (saluran C2 Eksternal) - kita akan membicarakan ini di akhir artikel.

Berusaha lebih keras...

Salah satu alat yang diterapkan di Go adalah pengembangan kami untuk melakukan pivot ke dalam jaringan - sebuah terowongan rsockstun, yang sekarang terdeteksi oleh alat dari Microsoft dan Symantec sebagai perangkat lunak yang sangat berbahaya yang bertujuan mengganggu stabilitas global...

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Akan sangat bagus jika menggunakan perkembangan sebelumnya dalam kasus ini juga. Namun di sini muncul masalah kecil. Faktanya adalah awalnya rsockstun menyiratkan penggunaan saluran komunikasi SSL yang sinkron dengan server. Ini berarti bahwa koneksi dibuat satu kali dan berlangsung sepanjang durasi pengoperasian terowongan. Dan, seperti yang Anda pahami, protokol https tidak dimaksudkan untuk mode operasi ini - protokol ini bekerja dalam mode permintaan-respons, di mana setiap permintaan http baru ada dalam koneksi tcp baru.

Kerugian utama dari skema ini adalah server tidak dapat mentransfer data ke klien sampai klien mengirimkan permintaan http baru. Namun, untungnya, ada banyak opsi untuk mengatasi masalah ini - streaming data melalui protokol http (bagaimanapun juga, kami entah bagaimana berhasil menonton acara TV favorit kami dan mendengarkan musik dari portal yang berjalan di https, tetapi transmisi video dan audio tidak lain adalah daripada streaming data). Salah satu teknologi untuk meniru pengoperasian koneksi TCP lengkap melalui protokol HTTP adalah teknologi WebSockets, yang esensi utamanya adalah mengatur koneksi jaringan penuh antara klien dan server Web.

Beruntung bagi kami (hore!!!), teknologi ini disertakan secara default di semua paket tarif CloudFlare dan berfungsi baik jika dikombinasikan dengan eSNI. Inilah yang akan kami gunakan untuk mengajari tunneler kami menggunakan domain-fronting dan bersembunyi dari DPI modern.

Sedikit tentang WebSockets

Pertama-tama, kita akan berbicara secara singkat dan sederhana tentang websockets sehingga setiap orang memiliki gambaran tentang apa yang akan kita kerjakan.

Teknologi Websocket memungkinkan Anda untuk sementara beralih dari koneksi http ke streaming soket jaringan standar tanpa memutus koneksi TCP yang sudah ada. Ketika klien ingin beralih ke websocket, ia menetapkan beberapa header http dalam permintaan http-nya. Dua header yang diperlukan - Koneksi: Tingkatkan и Peningkatan: soket web. Dia juga dapat secara paksa menentukan versi protokol websocket (Versi-Sec-Websockset: 13) dan sesuatu seperti pengidentifikasi soket web base64 (Kunci-WebSocket Detik: DAGDJSiREI3+KjDfwxm1FA==). Server meresponsnya dengan kode http 101 Switching Protocols dan juga menyetel headernya Koneksi, Tingkatkan и Detik-WebSocket-Terima. Proses peralihan ditunjukkan dengan jelas pada gambar di bawah:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Setelah ini, instalasi koneksi WebSocket dianggap selesai. Data apa pun dari klien dan server sekarang tidak akan diberikan dengan http, tetapi dengan header WebSocket (dimulai dengan byte 0x82). Kini server tidak perlu menunggu permintaan dari client untuk mentransfer data, karena Koneksi tcp tidak terputus.

Golang memiliki beberapa perpustakaan untuk bekerja dengan websockets. Yang paling populer adalah Gorila WebSocket dan standar WebSocket. Kami akan menggunakan yang terakhir, karena... ini lebih sederhana, lebih kecil dan, seperti yang mereka katakan, bekerja sedikit lebih cepat.

Dalam kode klien rsockstun, kita perlu mengganti panggilan net.dial atau tls.dial dengan panggilan WebSocket yang sesuai:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Kami ingin menjadikan klien sebagai bagian dari terowongan kami yang universal dan mampu bekerja baik melalui koneksi SSL langsung dan melalui protokol WebSockset. Untuk ini kita akan membuat fungsi terpisah func connectForWsSocks(string alamat, string proxy) kesalahan {…} dengan analogi dengan sambungkanForSocks() dan kami akan menggunakannya untuk bekerja dengan soket web jika alamat server yang ditentukan saat memulai klien dimulai dengan ws: atau wss: (dalam kasus Secure WebSocket).

Untuk terowongan sisi server, kami juga akan membuat fungsi terpisah untuk bekerja dengan soket web. Ini akan membuat instance kelas http dan mengatur pengendali koneksi http (fungsi wsHandler):

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Dan kami akan menempatkan semua logika pemrosesan koneksi (otorisasi klien menggunakan kata sandi, pengaturan dan mengakhiri sesi yamux) di pengendali koneksi WebSocket:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Kami mengkompilasi proyek dan meluncurkan bagian server:

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

Dan kemudian bagian klien:

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

Dan kami memeriksa pekerjaan di host lokal:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Mari beralih ke bagian depan domain

Kami tampaknya telah menemukan soket web. Sekarang mari kita langsung beralih ke eSNI dan domain fronting. Seperti disebutkan sebelumnya, untuk bekerja sama dengan DoH dan eSNI kita perlu mengambil cabang golang khusus dari perusahaan CloudFlare. Kami membutuhkan cabang yang mendukung eSNI (pwu/esni).

Kami mengkloningnya secara lokal atau mengunduh dan membuka kompresi zip yang sesuai:

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

Kemudian kita perlu menyalin direktori GOROOT, mengganti file terkait dari cabang kloning dan menetapkannya sebagai master. Untuk menyelamatkan pengembang dari sakit kepala ini, orang-orang dari CloudFlare telah menyiapkan skrip khusus - _dev/go.sh. Kami baru saja meluncurkannya. Script, bersama dengan makefile, akan melakukan semuanya sendiri. Hanya untuk bersenang-senang, Anda dapat melihat ke dalam makefile untuk mengetahui detailnya.

Setelah menjalankan skrip, saat mengkompilasi proyek, kita perlu menentukan direktori lokal yang disiapkan oleh skrip sebagai GOROOT. Dalam kasus kami, tampilannya seperti ini:

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

Selanjutnya, kita perlu mengimplementasikan fungsi meminta dan mengurai kunci eSNI publik untuk domain yang diinginkan di terowongan. Dalam kasus kami, ini akan menjadi kunci eSNI publik dari server frontend CloudFlare. Untuk melakukan ini, kita akan membuat tiga fungsi:

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

Nama-nama fungsinya, pada prinsipnya, berbicara sendiri. Kami akan mengambil konten dari file esni_query.go, yang merupakan bagian dari tls-tris. Fungsi pertama membuat paket jaringan dengan permintaan ke server DNS CloudFlare menggunakan protokol DoH (DNS-over-HTTPS), fungsi kedua mem-parsing hasil kueri dan memperoleh nilai kunci publik domain, dan fungsi ketiga adalah a wadah untuk dua yang pertama.

Selanjutnya, kita menambahkan koneksi soket web ke fungsi yang baru kita buat sambungkanForWsSocks fungsionalitas untuk meminta kunci eSNI untuk domain. Di mana bagian server beroperasi, kami menetapkan parameter TLS, dan juga menetapkan nama "domain penutup" palsu:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Perlu dicatat di sini bahwa pada awalnya, cabang tls-tris tidak dirancang untuk penggunaan domain fronting. Oleh karena itu, ia tidak memperhatikan nama server palsu (bidang serverName kosong dikirim sebagai bagian dari paket client-hello). Untuk memperbaikinya, kita harus menambahkan bidang FakeServerName yang sesuai ke struktur TlsConfig. Kami tidak dapat menggunakan bidang struktur ServerName standar, karena ini digunakan oleh mekanisme tls internal dan jika berbeda dari yang asli, jabat tangan tls akan berakhir dengan kesalahan. Deskripsi struktur TlsConfig terdapat dalam file tls/umum.pergi - kita harus memperbaikinya:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Selain itu, kita harus membuat perubahan pada file tls/handshake_client.gountuk menggunakan bidang FakeServerName kami saat membentuk jabat tangan TLS:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Itu saja! Anda dapat mengkompilasi proyek dan memeriksa pekerjaannya. Namun sebelum Anda menjalankan pemindaian, Anda perlu menyiapkan akun CloudFlare. Nah, bagaimana saya bisa mengatakan menyiapkannya - cukup buat akun di cloudflare dan tautkan domain Anda ke akun tersebut. Semua fitur yang terkait dengan DoH, WebSocket, dan ESNI disertakan dalam CloudFlare secara default. Setelah data DNS diperbarui, Anda dapat memeriksa pengoperasian domain dengan menanyakan kunci eSNI:

dig +short txt _esni.df13tester.info 

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Jika Anda melihat sesuatu yang serupa untuk domain Anda, itu berarti semuanya berfungsi untuk Anda dan Anda dapat melanjutkan ke pengujian.

Meluncurkan Ubuntu Misalnya, VPS di DigitalOcean. PS: Dalam kasus kami, alamat IP VPS yang baru saja kami terima dari penyedia kami akhirnya masuk daftar hitam Roskomnadzor. Jadi jangan heran jika hal serupa terjadi pada Anda. Saya harus menggunakan VPN untuk mengakses VPS saya.

Kami menyalin rsockstun yang sudah dikompilasi ke VPS (omong-omong, ini adalah keindahan lain dari Golang - Anda dapat mengkompilasi proyek Anda sendiri dan menjalankannya di Linux apa pun, hanya mengamati kapasitas bit sistem) dan meluncurkan bagian server:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Dan kemudian bagian klien:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Seperti yang bisa kita lihat, klien berhasil terhubung ke server melalui server frontend CloudFlare menggunakan websocket. Untuk memeriksa apakah terowongan berfungsi persis seperti terowongan, Anda dapat membuat permintaan curl melalui kaus kaki5 lokal, yang dibuka di server:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Sekarang mari kita lihat apa yang dilihat DPI di saluran komunikasi:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Pertama, tunneler, menggunakan mekanisme DoH, menghubungi server DNS Cloudflare untuk mendapatkan kunci eSNI untuk domain tujuan (paket No. 1-19), lalu menghubungi server frontend dan membuat koneksi TLS, bersembunyi di balik domain www.google.com (ini adalah nilai default ketika tidak ada domain palsu yang ditentukan saat klien memulai). Untuk menentukan domain palsu Anda, Anda harus menggunakan parameter -fronfDomain:

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Sekarang satu hal lagi. Secara default, pengaturan akun CloudFalre diatur ke SSL Fleksibel. Artinya permintaan https ke server frontend Cloudflare dari klien akan diteruskan tanpa terenkripsi (http) ke server kami. Itu sebabnya kami meluncurkan bagian server terowongan dalam mode non-ssl ( -listen ws:0.0.0.0), dan bukan ( -listen wss:0.0.0.0).

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Untuk beralih ke mode enkripsi penuh, Anda harus memilih PenuhAtau Penuh (ketat) jika ada sertifikat asli di server. Setelah berpindah mode, kita akan dapat menerima koneksi dari CloudFlare menggunakan protokol https. Jangan lupa untuk membuat sertifikat yang ditandatangani sendiri untuk sisi server terowongan.

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Pembaca yang ingin tahu akan bertanya: “Bagaimana dengan klien di bawah Windows"Lagipula, kegunaan utama tunneler mungkin adalah untuk membangun koneksi back-end dari mesin dan server perusahaan, dan biasanya selalu Windows. Bagaimana cara mengkompilasi tunneler untuk Windows, terutama dengan tumpukan TLS tertentu?" Sekarang kita akan memperkenalkan fitur lain yang menunjukkan betapa mudahnya Golang. Kita mengkompilasi untuk Windows langsung dari Kali hanya dengan menambahkan parameter GOOS=windows:

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

Atau versi 32-bit:

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

Semua! Dan tidak diperlukan lagi kerepotan. Ini benar-benar berhasil!

Tampilan depan domain berdasarkan TLS 1.3. Bagian 2

Flag kompiler –w dan –s diperlukan untuk membuang sampah yang tidak perlu dari file yang dapat dieksekusi, membuatnya lebih kecil beberapa megabyte. Selain itu, dapat dikemas menggunakan UPX untuk memperkecil ukurannya.

Alih-alih sebuah kesimpulan

Dalam artikel tersebut, dengan menggunakan contoh terowongan yang ditulis dalam Golang, kami dengan jelas mendemonstrasikan penggunaan teknologi domain-fronting baru, yang diimplementasikan pada fitur yang cukup menarik dari protokol TLS 1.3. Dengan cara serupa, Anda dapat mengadaptasi alat yang ada yang ditulis dalam Golang untuk bekerja melalui server CloudFlare, misalnya Merlin - C2 yang terkenal, atau memaksa CobaltStrike Beacon untuk menggunakan domain-fronting eSNI saat bekerja dengan Teamserver melalui Saluran C2 Eksternal, diimplementasikan di Golang, atau dalam C++ standar menggunakan versi OpenSSL yang dipatch, yang telah kita bahas di bagian terakhir artikel. Secara umum, tidak ada batasan untuk imajinasi.

Contoh terowongan dan CloudFlare disajikan dalam bentuk konsep dan masih sulit untuk mengatakan prospek jangka panjang dari jenis domain fronting ini. Saat ini, hanya CloudFlare yang mendukung eSNI dan, secara teori, tidak ada yang menghalangi mereka untuk menonaktifkan fronting semacam ini dan, misalnya, memutus koneksi tls jika SNI dan eSNI tidak cocok. Secara umum, masa depan akan membuktikannya. Namun untuk saat ini, prospek bekerja di bawah “kedok kremlin.ru” terlihat cukup menggiurkan. Bukankah begitu?

Kode terowongan yang diperbarui, serta file exe yang dapat dieksekusi yang dikompilasi, terletak di cabang terpisah dari proyek di github. Lebih baik menulis masalah tentang semua kemungkinan masalah terowongan di halaman proyek di GitHub.

Sumber: www.habr.com

Beli hosting yang andal untuk situs dengan perlindungan DDoS, server VPS VDS 🔥 Beli hosting website andal dengan perlindungan DDoS, server VPS VDS | ProHoster