Pendahuluan
Pada bagian pertama
artikel, kami memberikan deskripsi singkat tentang mekanisme SNI terenkripsi (eSNI). Mereka menunjukkan bagaimana, pada dasarnya, adalah mungkin untuk menghindari deteksi oleh sistem DPI modern (menggunakan Beeline DPI dan rutracker ILV terlarang sebagai contoh), serta menjelajahi versi baru front-end domain berdasarkan mekanisme ini.
Di bagian kedua artikel ini, kita akan beralih ke hal-hal yang lebih praktis sehingga RedTeam akan berguna bagi para spesialis dalam pekerjaan sulit mereka. Pada akhirnya, tujuan kami bukan untuk mendapatkan akses ke sumber daya yang diblokir (untuk hal-hal biasa seperti itu, kami memiliki VPN lama yang baik). Untungnya, ada banyak penyedia VPN, seperti yang mereka katakan, untuk setiap selera, warna, dan anggaran.
Kami akan mencoba menerapkan mekanisme domain-fronting untuk alat RedTeam modern, misalnya, seperti Cobalt Strike, Empire, dll., Dan memberi mereka peluang tambahan untuk meniru dan menghindari sistem penyaringan konten modern.
Terakhir kali, kami menerapkan mekanisme eSNI di pustaka OpenSSL dan berhasil menggunakannya dalam utilitas curl yang umum. Tapi satu ikal, seperti kata mereka, tidak akan penuh. Tentu saja, saya ingin mengimplementasikan sesuatu yang serupa dalam bahasa tingkat tinggi. Namun, sayangnya, pencarian sepintas lalu tentang luasnya jaringan mengecewakan kami, karena dukungan untuk mekanisme eSNI sepenuhnya dilaksanakan hanya di GOLANG. Jadi, pilihan kita tidak terlalu besar: kita menulis dalam C murni atau C ++ menggunakan pustaka OpenSSL yang ditambal, atau kita menggunakan garpu GOLANG terpisah dari CloudFlare dan mencoba untuk mem-porting alat-alat kita di sana. Pada prinsipnya, ada opsi lain, lebih klasik, tetapi juga memakan waktu - adalah untuk mengimplementasikan dukungan eSNI untuk python. Bagaimanapun, Python juga menggunakan OpenSSL untuk bekerja dengan https. Tetapi kami akan menyerahkan opsi ini untuk pengembangan kepada orang lain, dan kami akan puas dengan implementasi pada Golang, terutama karena Cobalt Strike yang kami cintai dapat bekerja dengan baik dengan saluran komunikasi yang dibangun oleh alat pihak ketiga (saluran C2 Eksternal) - kami akan membicarakan hal ini di akhir artikel.
Coba Lebih Keras ...
Salah satu alat yang diimplementasikan pada Go adalah pengembangan kami untuk berputar di dalam jaringan -
tuner rsockstun, yang, kebetulan, sekarang terdeteksi oleh Microsoft dan alat-alat Symantec sebagai perangkat lunak yang sangat berbahaya yang bertujuan melanggar stabilitas dunia ...

Akan sangat bagus untuk menggunakan pengembangan sebelumnya dalam kasus ini. Tapi di sini muncul masalah kecil. Faktanya adalah bahwa rsockstun awalnya menyiratkan penggunaan saluran komunikasi SSL yang sinkron dengan server. Ini berarti bahwa koneksi dibuat sekali dan ada untuk seluruh durasi operasi terowongan. Dan, seperti yang Anda pahami, protokol https tidak dirancang untuk mode operasi ini - protokol ini berfungsi dalam mode respons-respons, di mana setiap permintaan http baru ada dalam kerangka koneksi tcp baru.
Kerugian utama dari skema ini adalah bahwa server tidak dapat mentransfer data ke klien sampai klien mengirim permintaan http baru. Tapi, untungnya, ada banyak pilihan untuk menyelesaikan masalah ini - streaming data melalui protokol http (pada akhirnya, kami berhasil menonton acara TV favorit kami dan mendengarkan musik dari portal yang berjalan di https, dan transmisi video dan audio tidak selain streaming data). Salah satu teknologi untuk meniru operasi koneksi tcp penuh melalui protokol http adalah teknologi WebSockets, yang intinya adalah untuk mengatur koneksi jaringan penuh antara klien dan server web.
Untuk keberuntungan kami (hore hore !!!), teknologi ini disertakan secara default dalam semua paket tarif CloudFlare dan berfungsi sangat baik jika dikombinasikan dengan eSNI. Inilah yang akan kami gunakan untuk mengajarkan terowongan kami menggunakan front-domain dan bersembunyi dari DPI modern.
Sedikit tentang WebSockets
Pertama-tama, kami akan secara singkat dan dengan kata sederhana memberitahu tentang soket web sehingga setiap orang memiliki gagasan tentang apa yang akan kami kerjakan.
Teknologi soket web memungkinkan Anda untuk sementara waktu beralih dari koneksi http ke data streaming standar melalui soket jaringan tanpa memutus koneksi tcp yang telah dibuat. Ketika klien ingin beralih ke soket web, ia menetapkan beberapa header http dalam permintaan http-nya. Dua header yang diperlukan adalah
Koneksi: Peningkatan dan
Peningkatan: websocket . Itu juga dapat memaksa versi protokol websocket (
Sec-Websockset-Version: 13 ) dan sesuatu seperti pengidentifikasi soket web base64 (
Sec-WebSocket-Key: DAGDJSiREI3 + KjDfwxm1FA == ). Server merespons dengan http-code 101 Switching Protocols dan juga mengatur header
Connection, Upgrade, dan
Sec-WebSocket-Accept . Proses switching diilustrasikan dalam tangkapan layar di bawah ini:

Setelah itu, koneksi WebSocket dapat dianggap selesai. Setiap data dari klien dan server sekarang akan diberikan tidak dengan http, tetapi dengan header WebSocket (mereka mulai dengan byte 0x82). Sekarang server tidak perlu menunggu permintaan dari klien untuk mentransfer data, seperti koneksi tcp tidak rusak.
Ada beberapa perpustakaan di geng soket soket web. Yang paling populer adalah
Gorilla WebSocket dan
WebSocket standar. Kami akan menggunakan yang terakhir, karena itu lebih sederhana, lebih kecil dan berfungsi, seperti yang mereka katakan, sedikit lebih cepat.
Dalam kode klien rsockstun, kita perlu mengganti panggilan net.dial atau tls.dial dengan panggilan WebSocket yang sesuai:


Kami ingin menjadikan klien bagian dari terowongan kami universal dan dapat bekerja baik melalui koneksi ssl langsung dan melalui protokol WebSockset. Untuk melakukan ini, kita akan membuat fungsi fungsi
func connectForWsSocks (string alamat, string proxy) terpisah {...} dengan analogi dengan
connectForSocks () dan kita akan menggunakannya untuk bekerja dengan soket web jika alamat server yang ditentukan ketika klien mulai akan mulai dengan ws: or wss: (dalam kasus Secure WebSocket).
Untuk sisi server dari terowongan, kami juga akan membuat fungsi terpisah untuk bekerja dengan soket web. Sebuah instance dari kelas http akan dibuat di dalamnya dan handler koneksi http (fungsi wsHandler) akan ditetapkan:

Dan kami akan menempatkan semua logika untuk memproses koneksi (mengesahkan klien dengan kata sandi, menginstal dan mengakhiri sesi yamux) di penangan koneksi WebSocket:

Kami mengkompilasi proyek, memulai 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 pada host lokal:


Kami beralih ke domain-fronting
Kami sepertinya telah memilah-milah soket web. Sekarang mari kita langsung menuju eSNI dan domain-front. Seperti yang disebutkan sebelumnya, untuk bekerja dengan DoH dan eSNI, kita perlu mengambil cabang khusus golang dari
CloudFlare . Kami membutuhkan cabang dengan dukungan eSNI (pwu / esni).
Kami mengkloningnya ke diri kami sendiri secara lokal atau mengunduh dan memperluas zip yang sesuai:
git clone -b pwu/esni https://github.com/cloudflare/tls-tris.git
Maka kita perlu menyalin direktori GOROOT, mengganti file yang sesuai dari cabang kloning dan mengaturnya sebagai yang utama. Untuk menyelamatkan pengembang dari sakit kepala ini, orang-orang dari CloudFlare menyiapkan skrip khusus - _dev / go.sh. Jalankan saja. Script bersama dengan makefile akan melakukan semuanya sendiri. Untuk bersenang-senang - Anda bisa melihat ke dalam makefile untuk detailnya.
Setelah mengerjakan skrip, saat menyusun proyek, kita perlu menunjukkan sebagai GOROOT direktori lokal yang disiapkan oleh skrip. Dalam kasus kami, tampilannya seperti ini:
GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" go build β¦.
Selanjutnya, kita perlu mengimplementasikan fungsi meminta dan mem-parsing kunci eSNI publik untuk domain yang diinginkan. Dalam kasus kami, ini akan menjadi kunci eSNI publik dari server front-end CloudFlare. Untuk melakukan ini, kami 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 fungsi, pada prinsipnya, berbicara sendiri. Kami akan mengambil isian 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), yang kedua mem-parsing hasil kueri dan menerima nilai-nilai kunci domain publik, dan yang ketiga adalah wadah untuk dua yang pertama.
Selanjutnya, kami
memperkenalkan fungsi meminta kunci eSNI untuk domain ke fungsi koneksi kami yang baru dibuat untuk soket web
connectForWsSocks . Di mana bagian server berfungsi, setel parameter TLS, dan juga setel nama "domain penutup" palsu:

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


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

Itu saja! Anda dapat mengkompilasi proyek dan memeriksa pekerjaan. Tetapi sebelum Anda menjalankan tes, Anda harus mengonfigurasi akun CloudFlare Anda. Nah, bagaimana Anda mengatakan untuk mengatur - cukup buat akun cloudflare dan ikat domain Anda ke sana. Semua chip yang terkait dengan DoH, WebSocket dan ESNI termasuk dalam CloudFlare secara default. Setelah catatan DNS diperbarui - Anda dapat memeriksa domain dengan menjalankan permintaan kunci eSNI:
dig +short txt _esni.df13tester.info

Jika Anda melihat sesuatu yang mirip dengan domain Anda, maka semuanya berfungsi untuk Anda dan Anda dapat melanjutkan ke pengujian.
Luncurkan VPS Ubuntu, misalnya, di DigitalOcean. PS Dalam kasus kami, alamat IP VPS yang baru saja dikeluarkan oleh penyedia berada dalam daftar hitam ILV. Jadi jangan heran jika hal serupa terjadi pada Anda. Saya harus menggunakan VPN untuk sampai ke VPS saya.
Kami menyalin rsockstun yang telah dikompilasi ke VPS (ini, omong-omong, adalah pesona lain dari golang - Anda dapat mengkompilasi proyek sendiri dan menjalankannya di Linux apa pun, hanya mengamati kapasitas bit sistem) dan memulai bagian server:

Dan kemudian bagian klien:

Seperti yang dapat kita lihat, klien berhasil terhubung ke server melalui server front-end CloudFlare menggunakan soket web. Untuk memverifikasi bahwa terowongan berfungsi seperti terowongan, Anda dapat membuat permintaan ikal melalui socks5 lokal yang terbuka di server:

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

Pertama, tuner terowongan, menggunakan mekanisme DoH, mengakses server Cloudflare DNS untuk kunci eSNI untuk domain tujuan (paket No. 1-19), dan kemudian mengakses server front-end dan membuat koneksi TLS, bersembunyi di bawah domain
www.google.com (nilai ini secara default, ketika domain palsu tidak disetel saat startup klien). Untuk menentukan domain palsu Anda, Anda harus menggunakan parameter -fronfDomain:


Sekarang satu hal lagi. Secara default, pengaturan akun CloudFalre diatur ke SSL Fleksibel. Ini berarti bahwa https permintaan ke server front-end Cloudflare dari klien akan dialihkan dalam bentuk tidak terenkripsi (http) ke server kami. Itulah sebabnya kami meluncurkan bagian server dari terowongan dalam mode non-ssl (-listen ws: 0.0.0.0), dan bukan (-listen wss: 0.0.0.0).

Untuk beralih ke mode enkripsi penuh, Anda harus memilih
Penuh , atau
Penuh (ketat) jika ada sertifikat ini di server. Setelah beralih mode, kita akan dapat menerima koneksi dari CloudFlare melalui protokol https. Ingatlah untuk membuat sertifikat yang ditandatangani sendiri untuk sisi server terowongan.

Pembaca yang menjengkelkan akan bertanya: "Bagaimana dengan akun klien di Windows? Memang, yang pasti, aplikasi utama terowongan adalah untuk meningkatkan koneksi kembali dari mesin dan server perusahaan, dan di sana, sebagai aturan, selalu Windows. Bagaimana saya bisa mengkompilasi sebuah terowongan untuk Windows, dan bahkan dengan tumpukan TLS tertentu? Kami mengkompilasi untuk windows langsung dari Kali, cukup dengan menambahkan parameter GOOS = windows:
GOARCH=amd64 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"
Atau opsi 32-bit:
GOARCH=386 GOROOT="/opt/tls-tris/_dev/GOROOT/linux_amd64" GOOS=windows go build -ldflags="-s -w"
Itu saja! Dan tidak ada lagi masalah yang dibutuhkan. Ini benar-benar berfungsi!

Flag compiler βw dan βs diperlukan untuk menghapus kelebihan sampah dari file yang dapat dieksekusi, membuatnya lebih sedikit beberapa megabyte. Selain itu, kemudian dapat dikemas menggunakan UPX untuk mengurangi ukuran lebih lanjut.
Alih-alih sebuah kesimpulan
Dalam artikel kami, menggunakan contoh tuner yang ditulis pada golang, dengan jelas menunjukkan penggunaan teknologi baru domain-fronting, diimplementasikan pada fitur yang agak menarik dari protokol TLS 1.3. Demikian pula, Anda dapat mengadaptasi toolkit yang ada yang ditulis pada golang untuk bekerja melalui server CloudFlare, misalnya
Merlin , C2 yang terkenal, atau memaksa CobaltStrike Beacon untuk menggunakan domain-depan eSNI saat bekerja dengan Teamserver melalui
Kanal C2 Eksternal , diterapkan pada golang, atau pada standar C ++ menggunakan versi OpenSSL yang ditambal, yang kita bicarakan di bagian akhir artikel. Secara umum, fantasi tidak memiliki batas.
Contoh terowongan dan CloudFlare disajikan dalam bentuk konsep dan masih sulit untuk mengatakan tentang prospek yang jauh dari jenis domain yang menghadap ke depan. Saat ini, dukungan eSNI hanya tersedia di CloudFlare dan, pada prinsipnya, tidak ada yang mencegah mereka menonaktifkan front-end seperti ini dan, misalnya, memutuskan koneksi ketika SNI dan eSNI tidak cocok. Secara umum, masa depan akan ditampilkan. Tetapi untuk saat ini, prospek bekerja di bawah kedok kremlin.ru tampaknya cukup menarik. Benar?
Kode terowongan yang diperbarui, serta file exe yang dapat dieksekusi yang dikompilasi, terletak di cabang proyek terpisah di
github . Lebih baik menulis masalah tentang semua masalah terowongan yang mungkin terjadi pada halaman proyek di GitHub.