3 poin oleh GN⁺ 2025-04-04 | 1 komentar | Bagikan ke WhatsApp
  • curl-impersonate adalah build curl yang dimodifikasi agar melakukan TLS dan HTTP handshake sehingga tampak seperti Chrome, Edge, Safari, atau Firefox, dan dapat digunakan sebagai tool CLI maupun library pengganti libcurl
  • Client Hello dan pengaturan HTTP/2 pada client serta library HTTP biasa sangat berbeda dari browser sungguhan, sehingga sebagian layanan web mengidentifikasi client melalui TLS/HTTP handshake dan menyajikan konten yang berbeda
  • Implementasinya terdiri dari penggunaan NSS untuk Firefox dan BoringSSL untuk keluarga Chrome, perubahan ekstensi TLS, opsi SSL, dan pengaturan HTTP/2, serta penerapan flag non-default seperti --ciphers, --curves, dan header
  • Target yang didukung adalah Chrome 99~116, Android Chrome 99, Edge 99·101, Firefox 91 ESR~117, dan Safari 15.3·15.5; setiap target menyediakan wrapper script dan target name
  • Di command line, jalankan curl_chrome116; untuk integrasi library, dapat diterapkan ke aplikasi yang sudah memakai libcurl melalui curl_easy_impersonate() atau LD_PRELOAD dan CURL_IMPERSONATE di Linux

Masalah yang diselesaikan curl-impersonate

  • curl-impersonate adalah proyek yang membangun curl secara khusus agar dapat meniru empat browser utama: Chrome, Edge, Safari, dan Firefox
  • Dapat melakukan TLS dan HTTP handshake secara identik dengan browser sungguhan
  • Ada dua cara penggunaan
    • Tool command line yang mirip curl biasa
    • Library yang dapat diintegrasikan sebagai pengganti libcurl yang sudah ada

Mengapa ini diperlukan

  • Saat HTTP client terhubung ke situs web TLS, ia terlebih dahulu melakukan TLS handshake
  • Pesan pertama dalam TLS handshake adalah Client Hello, dan Client Hello yang dibuat oleh kebanyakan HTTP client serta library sangat berbeda dari browser sungguhan
  • Jika server menggunakan HTTP/2, selain TLS handshake juga dilakukan HTTP/2 handshake, tempat berbagai pengaturan dipertukarkan
  • Pengaturan HTTP/2 pada kebanyakan HTTP client dan library juga berbeda dari browser sungguhan
  • Sebagian layanan web memanfaatkan perbedaan ini untuk mengidentifikasi client yang terhubung dan menyajikan konten berbeda untuk tiap client
    • Metode ini disebut TLS fingerprinting dan HTTP/2 fingerprinting
    • README menyatakan bahwa penggunaan luas metode ini membuat web menjadi kurang terbuka, kurang privat, dan lebih membatasi client web tertentu

Cara kerjanya

  • curl dipatch cukup banyak agar tampak seperti browser
  • Perubahan utamanya adalah sebagai berikut
    • Versi Firefox mengompilasi curl dengan NSS, library TLS yang digunakan Firefox, alih-alih OpenSSL
    • Versi Chrome dikompilasi dengan BoringSSL, library TLS milik Google
    • Mengubah cara curl mengatur berbagai ekstensi TLS dan opsi SSL
    • Menambahkan dukungan untuk ekstensi TLS baru
    • Mengubah pengaturan yang digunakan untuk koneksi HTTP/2
    • Menjalankan curl dengan flag non-default seperti --ciphers, --curves, dan beberapa header -H
  • Hasilnya, dari sudut pandang jaringan, curl terlihat identik dengan browser sungguhan
  • Penjelasan teknis lengkap ada di part a, part b

Browser yang didukung dan nama target

  • Daftar browser yang didukung juga tersedia di browsers.json
  • Target dukungan keluarga Chrome
    • Chrome 99, 100, 101, 104, 107, 110, 116 on Windows 10
    • Chrome 99 on Android 12
    • Edge 99, 101 on Windows 10
    • Safari 15.3 on MacOS Big Sur
    • Safari 15.5 on MacOS Monterey
  • Target dukungan Firefox
    • Firefox 91 ESR, 95, 98, 100, 102, 109, 117 on Windows 10
  • Setiap target yang didukung memiliki target name dan wrapper script
    • Contoh: target chrome116 dijalankan dengan wrapper script curl_chrome116
    • Contoh: target ff117 dijalankan dengan wrapper script curl_ff117

Penggunaan dasar

  • Untuk tiap browser yang didukung, tersedia wrapper script yang menjalankan curl-impersonate dengan header dan flag yang diperlukan
  • Contoh eksekusi
    curl_chrome116 https://www.wikipedia.org
    
  • Jika flag command line ditambahkan, flag tersebut diteruskan ke curl
  • Sebagian flag dapat mengubah TLS signature curl sehingga dapat terdeteksi
  • Wrapper script menggunakan set HTTP header bawaan
    • Untuk mengubah header, wrapper script dapat dimodifikasi sesuai tujuan
  • Opsi lebih lanjut tersedia dalam penggunaan lanjutan libcurl-impersonate sebagai library

Instalasi dan metode distribusi

  • Karena alasan teknis, curl-impersonate memiliki dua versi
    • Versi chrome: digunakan untuk meniru Chrome, Edge, dan Safari
    • Versi firefox: digunakan untuk meniru Firefox
  • Binary pra-kompilasi untuk Linux dan macOS Intel tersedia di GitHub releases
  • Sebelum menggunakan binary pra-kompilasi, NSS dan sertifikat CA perlu dipasang
    • Ubuntu: sudo apt install libnss3 nss-plugin-pem ca-certificates
    • Red Hat/Fedora/CentOS: yum install nss nss-pem ca-certificates
    • Archlinux: pacman -S nss ca-certificates
    • macOS: brew install nss ca-certificates
  • Sistem juga memerlukan zlib
    • zlib hampir selalu tersedia, tetapi mungkin tidak ada pada beberapa sistem minimal
  • Binary Linux pra-kompilasi dibangun untuk sistem Ubuntu
    • Jika terjadi error verifikasi sertifikat di distribusi lain, lokasi sertifikat CA mungkin perlu diberitahukan ke curl
    curl_chrome116 https://www.wikipedia.org --cacert /etc/ssl/certs/ca-bundle.crt
    
  • Untuk build dari source, lihat INSTALL.md

Docker dan paket

  • Image Docker berbasis Alpine Linux dan Debian tersedia di Docker Hub
  • Image Docker menyertakan binary dan semua wrapper script
  • Contoh
    # Firefox version, Alpine Linux
    docker pull lwthiker/curl-impersonate:0.6-ff
    docker run --rm lwthiker/curl-impersonate:0.6-ff curl_ff109 https://www.wikipedia.org
    
    
    # Chrome version, Alpine Linux
    docker pull lwthiker/curl-impersonate:0.6-chrome
    docker run --rm lwthiker/curl-impersonate:0.6-chrome curl_chrome110 https://www.wikipedia.org
    
  • Pengguna Archlinux dapat menggunakan paket AUR
  • Formula Homebrew tidak resmi untuk Mac tersedia khusus Chrome
    brew tap shakacode/brew
    brew install curl-impersonate
    

Penggunaan lanjutan libcurl-impersonate

  • libcurl-impersonate.so adalah libcurl yang dikompilasi dengan perubahan yang sama seperti curl-impersonate command line
  • Ada fungsi API tambahan
    CURLcode curl_easy_impersonate(struct Curl_easy *data, const char * target,
                                   int default_headers);
    
  • Jika dipanggil dengan target name seperti chrome116, opsi dan header yang sebelumnya diatur oleh wrapper script akan diatur secara internal
  • Jika default_headers bernilai 0, daftar HTTP header bawaan tidak diatur
    • Pengguna harus menyediakan header sendiri dengan opsi libcurl biasa CURLOPT_HTTPHEADER
  • curl_easy_impersonate() mengatur beberapa opsi libcurl
    • CURLOPT_HTTP_VERSION
    • CURLOPT_SSLVERSION, CURLOPT_SSL_CIPHER_LIST, CURLOPT_SSL_EC_CURVES, CURLOPT_SSL_ENABLE_NPN, CURLOPT_SSL_ENABLE_ALPN
    • Opsi nonstandar untuk proyek, CURLOPT_HTTPBASEHEADER
    • Opsi HTTP/2 nonstandar untuk proyek, CURLOPT_HTTP2_PSEUDO_HEADERS_ORDER, CURLOPT_HTTP2_NO_SERVER_PUSH
    • Opsi TLS nonstandar untuk proyek, CURLOPT_SSL_ENABLE_ALPS, CURLOPT_SSL_SIG_HASH_ALGS, CURLOPT_SSL_CERT_COMPRESSION, CURLOPT_SSL_ENABLE_TICKET
    • Opsi TLS nonstandar untuk proyek, CURLOPT_SSL_PERMUTE_EXTENSIONS
  • Jika kemudian curl_easy_setopt() dipanggil untuk salah satu opsi di atas, nilai yang diatur oleh curl_easy_impersonate() akan ditimpa

Menerapkannya ke aplikasi libcurl yang sudah ada

  • Jika aplikasi sudah menggunakan libcurl, di Linux library yang ada dapat diganti saat runtime dengan LD_PRELOAD
  • Terapkan peniruan otomatis dengan mengatur environment variable CURL_IMPERSONATE
    LD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 my_app
    
  • CURL_IMPERSONATE memiliki dua efek
    • Saat curl handle baru dibuat dengan curl_easy_init(), curl_easy_impersonate() otomatis dipanggil
    • Setelah curl_easy_reset(), curl_easy_impersonate() juga otomatis dipanggil
  • Jika perlu mengontrol HTTP header secara presisi, nonaktifkan daftar header bawaan dengan CURL_IMPERSONATE_HEADERS=no dan atur sendiri
    LD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 CURL_IMPERSONATE_HEADERS=no my_app
    
  • Metode LD_PRELOAD tidak bekerja pada curl itu sendiri
    • Karena tool curl menimpa pengaturan TLS
    • Untuk curl, gunakan wrapper script

Struktur repositori dan kontribusi

  • Repositori memiliki dua folder utama
    • chrome: script dan patch untuk build curl-impersonate versi Chrome
    • firefox: script dan patch untuk build curl-impersonate versi Firefox
  • Contoh direktori Firefox mencakup file berikut
    • Dockerfile: digunakan untuk membangun curl-impersonate beserta semua dependensi
    • curl_ff91esr, curl_ff95, curl_ff98: wrapper script untuk menjalankan dengan flag yang benar
    • curl-impersonate.patch: patch utama yang membuat curl menggunakan ekstensi TLS seperti Firefox, sekaligus membuatnya dikompilasi statis dengan libnghttp2 dan libnss
  • tests/signatures adalah database YAML untuk signature browser yang diketahui dapat ditiru
  • Patch curl sebenarnya dipertahankan di repositori terpisah yang di-fork dari upstream curl

1 komentar

 
GN⁺ 2025-04-04
Opini Hacker News
  • Ada fork yang aktif dipelihara dengan cukup banyak peningkatan dibandingkan versi asli: https://github.com/lexiforest/curl-impersonate
    Ada juga binding untuk pengguna Python: https://github.com/lexiforest/curl_cffi

    • Di satu sisi wajar saja program yang “membuat curl terlihat seperti browser” disponsori oleh layanan bypass deteksi bot
    • Ada juga modul yang mengintegrasikannya sepenuhnya dengan library requests Python: https://github.com/el1s7/curl-adapter
    • Aneh rasanya harus mengikuti teknologi “canggih” yang berubah lebih cepat daripada orang memutar leher, hanya untuk membuat satu request sederhana yang terlihat seperti salah satu dari tiga browser web “tersertifikasi”
      Ironisnya, request itu mungkin akan membebani server lebih ringan daripada browser tersertifikasi, dan saya jadi bertanya-tanya apakah ini distopia yang dulu diperingatkan pada era 90-an. Saya penasaran apakah ada yang bisa menyebutkan di sini nama satu perusahaan yang menciptakan situasi ini sambil memosisikan diri sebagai kontributor baik bagi komunitas open source/hacker
  • Semoga ke depannya Ladybird makin kuat. Saat ini untuk networking mereka memakai cURL resmi, tetapi pendekatan ini bisa menemui hambatan
    Misalnya, setahu saya cURL masih punya beberapa keterbatasan dan belum bisa menangani WebSocket di atas h2. Sebaliknya, jika ada engine browser yang berkembang, traffic normal juga akan memiliki fingerprint yang sama dengan cURL bawaan, sehingga jalur fingerprinting ini mungkin bisa hilang

    • Semoga penggunaan cURL oleh Ladybird menjadi pemicu untuk memperbaiki cURL itu sendiri, misalnya pada bagian seperti WebSocket di atas h2 yang disebutkan tadi
      Ini juga menjadi ajang uji yang bagus untuk melihat fitur apa saja yang masih kurang di cURL berdasarkan workflow browser sungguhan
    • Untuk bagian “jika ada engine browser yang berkembang, jalur fingerprinting ini mungkin bisa hilang”, dari yang saya lihat di CloudFlare dan sejenisnya, kenyataannya hampir kebalikannya
      Dalam beberapa bulan terakhir, tingkat fingerprinting dan “penyalahgunaan” perilaku yang ditentukan implementasi meningkat tajam, dan tampaknya mungkin merupakan upaya untuk mematikan engine browser lain. Pemain lama sama sekali tidak suka kompetisi
      Pihak lawan mencoba membungkusnya sebagai “DDoS oleh bot AI”, tetapi saya bertanya-tanya seberapa banyak dari itu sebenarnya ulah mereka sendiri
    • Saat berbicara dengan orang-orang ini [0], kami membahas berbagai perbedaan implementasi yang aneh yang dipakai untuk membuat signature, bahkan sampai mencakup elemen TCP stack yang tidak bisa dikendalikan aplikasi di user space
      Saya suka curl ini, tetapi khawatir ketika suatu komponen mengambil peran sebagai trik untuk “mengejar ketertinggalan”, beban “kompatibilitas” yang sulit dipelihara akan menumpuk
      Idealnya kita cukup bisa berkata, “halo, saya curl, izinkan saya masuk”
      Tentu masalahnya ada pada server yang terlalu ketat soal aturan berpakaian, dan masalah itu sendiri muncul karena para penipu masuk dengan menyamar, jadi ini berputar seperti ayam dan telur
      [0] https://cybershow.uk/episodes.php?id=39
    • Semoga berkat ini Ladybird jadi mendukung URL ftp
    • Ladybird tidak punya sumber daya untuk bersaing dengan browser yang ada sekarang. Publisitasnya memang bagus, tetapi kurang memiliki keunggulan atau alasan keberadaan dibandingkan Chromium
      Selain itu, fakta bahwa ia dirancang ulang dengan C++ yang terbukti tidak aman adalah risiko keamanan besar
  • Apakah mereka juga mengatur IP_TTL agar cocok dengan nilai TTL platform yang ingin ditiru?
    Kalau tidak, fingerprinting sampai tingkat IP juga bisa dilakukan sampai batas tertentu. Jika nilai TTL pada lapisan IP kurang dari 64, jelas itu bukan berjalan di Windows modern, atau Windows modern yang TTL bawaannya diubah. Sebab TTL default paket pada Windows modern dimulai dari 128, sementara sebagian besar platform lain dimulai dari 64
    Platform lain juga tidak bermasalah berkomunikasi di internet, jadi paket IP dari Windows modern akan selalu terlihat di sisi remote dengan TTL 64 atau lebih, mungkin sedikit di atas 64. Memang fingerprinting lapisan IP sulit, tetapi bukan tidak mungkin

    • Ini hanya sulit saat memakai PaaS/IaaS yang tidak menyediakan akses TCP/IP stack level rendah. Jika menjalankan server sendiri, fingerprinting berbagai atribut TCP/IP sangat mudah
      https://en.wikipedia.org/wiki/TCP/IP_stack_fingerprinting
    • Bukankah nilai TTL paket yang diterima berubah tergantung kondisi jaringan? Bisakah server memulihkan nilai asli dari klien?
    • Mengapa TTL dirancang untuk berkurang, bukan bertambah? Secara umum, bukankah kita mengharapkan pihak yang merutekan traffic menentukan apakah dan bagaimana routing dilakukan?
  • Tunggu, kalau TLS handshake terlihat berbeda, bukankah traffic yang mengaku sebagai browser web tetapi sebenarnya skrip Python/PHP bisa difilter di level nginx?
    Misalnya kasus yang memakai user agent Chrome tetapi bukan browser sungguhan. Sebagian besar traffic bot jahat mungkin termasuk ini, jadi bagus kalau bisa langsung diblokir

    • Cloudflare menggunakan fingerprint TLS JA3/JA4, yaitu hash dari berbagai parameter TLS handshake
      Cara kerjanya dijelaskan rinci di https://github.com/FoxIO-LLC/ja4/blob/main/technical_details..., dan ada juga modul Nginx: https://github.com/FoxIO-LLC/ja4-nginx-module
    • Pada dasarnya itulah yang dilakukan perusahaan keamanan seperti Cloudflare, ditambah lebih banyak fingerprinting seperti JavaScript challenge yang memeriksa interpreter JavaScript/DOM
    • Itu memungkinkan, dan situs-situs nyata memang melakukannya, tetapi benar-benar buruk. Keandalannya rendah, sehingga memblokir semua orang yang tidak memakai Chrome terbaru di Windows terbaru
      Jika saat ini tidak benar-benar sedang diserang, jangan gunakan allowlist fingerprint TLS
    • Tool dalam artikel tampaknya memang ditujukan untuk menghindari pemblokiran seperti itu
  • Alat yang keren, tetapi seharusnya tidak penting apakah klien itu browser atau bukan. Rasanya pahit bahwa di dunia nyata alat seperti ini diperlukan

    • Sekitar 6 bulan lalu saya pernah masuk ke situs lelang pemerintah yang mensyaratkan Internet Explorer. Itu benar-benar Internet Explorer, dan situsnya juga masih aktif sehingga data lelangnya mutakhir
      Saya menambahkan ekstensi user agent di Chrome, mengubahnya menjadi IE, lalu mencoba lagi dan berhasil; semua fungsi situsnya juga berjalan normal. Jadi rasanya pahit sekaligus menyebalkan. Mungkin instansi pemerintah itu membuat situs webnya 25 tahun lalu lalu tidak pernah memperbaruinya lagi
    • Anda hanya boleh masuk ke situs ini jika memakai software yang kami setujui. Selain itu semuanya dianggap berbahaya. Tunjukkan dokumennya!
      Gatekeeping semacam ini juga terasa pahit bagi saya. Sejauh yang saya pahami, browser atau user agent kustom buatan sendiri tidak akan pernah bekerja di situs-situs semacam Cloudflare sampai mereka punya cukup pengaruh, uang, jumlah pengguna, atau semacamnya untuk meyakinkan pihak tersebut
  • Alat ini cukup bagus dipakai dalam pekerjaan red team dengan menggabungkan skrip bash kecil dan GNU parallel
    Berguna saat memetakan endpoint HTTPS dalam rentang alamat yang sudah ditentukan, yang karena berbagai alasan hanya merespons browser sungguhan atau baru merespons jika konfigurasi SNI cocok. Opsi curl biasa seperti -H untuk menyamarkan header juga tetap bisa dipakai

  • Tulisan Show HN saat itu: https://news.ycombinator.com/item?id=30378562

    • Saat itu, pada 2022, alat ini khusus Firefox
  • Setiap kali hal seperti ini muncul di sini, perasaan saya selalu campur aduk. Di satu sisi, menyenangkan mengetahui masih ada sedikit jiwa pembangkangan dan kemandirian di antara orang-orang
    Di sisi lain, seperti proyek-proyek lain yang diperlakukan seolah “kebebasan itu tidak stabil”, jika menarik perhatian yang tidak diinginkan, situasinya bisa menjadi lebih buruk bagi orang-orang yang bergantung padanya. Menulis browser itu sulit, dan para pemain dominan yang sudah ada terus membuatnya makin sulit

    • Kedengarannya seolah para pengembang browser menginginkan browser dapat diidentifikasi melalui fingerprint, tetapi itu lebih merupakan sesuatu yang terjadi dengan sendirinya karena orang-orang yang berbeda mengimplementasikannya secara berbeda
      Saya tidak melihat ini sebagai soal jiwa pembangkangan. Software yang dapat diidentifikasi lewat fingerprint menggerogoti perlindungan privasi dan keberagaman software
  • Saya agak merindukan masa-masa sederhana ketika situs web mengizinkan bot jika mereka tidak keberatan, dan memblokir user agent jika mereka tidak suka

    • Saat itu situs web tidak seboros sumber daya seperti sekarang. Menurut saya, reaksi negatif terhadap bot lebih merupakan efek samping dari ekspektasi terhadap pengalaman web yang menjadi terlalu berat
  • Kalau hanya tiga patch dan shell wrapper, Daniel mungkin tertarik untuk ikut coding. Secara pribadi, saya rasa ini memang harus masuk ke curl mainline