3 puan yazan GN⁺ 2025-04-04 | 1 yorum | WhatsApp'ta paylaş
  • curl-impersonate, Chrome, Edge, Safari ve Firefox gibi görünen TLS ve HTTP handshake’leri gerçekleştirecek şekilde değiştirilmiş bir curl derlemesidir; CLI aracı ve libcurl yerine geçebilen bir kütüphane olarak kullanılabilir
  • Genel HTTP istemcileri ve kütüphanelerinin Client Hello ve HTTP/2 ayarları gerçek tarayıcılardan büyük ölçüde farklıdır; bu yüzden bazı web servisleri istemciyi TLS/HTTP handshake üzerinden tanımlayıp farklı içerik sunar
  • Uygulama, Firefox için NSS, Chrome tabanlı tarayıcılar için BoringSSL kullanır; TLS uzantıları, SSL seçenekleri ve HTTP/2 ayarlarını değiştirir ve --ciphers, --curves, header’lar gibi varsayılan dışı bayraklar uygular
  • Desteklenen hedefler Chrome 99~116, Android Chrome 99, Edge 99·101, Firefox 91 ESR~117 ve Safari 15.3·15.5’tir; her hedef için bir wrapper script ve target name sağlanır
  • Komut satırında curl_chrome116 çalıştırılır; kütüphane entegrasyonunda ise curl_easy_impersonate() ya da Linux’ta LD_PRELOAD ve CURL_IMPERSONATE ile mevcut libcurl kullanan uygulamalara uygulanabilir

curl-impersonate’ın çözdüğü sorun

  • curl-impersonate, curl’ün Chrome, Edge, Safari ve Firefox olmak üzere dört büyük tarayıcıyı taklit edebilmesi için özel olarak derlendiği bir projedir
  • TLS ve HTTP handshake’lerini gerçek tarayıcılarla aynı şekilde gerçekleştirebilir
  • İki kullanım biçimi vardır
    • Normal curl’a benzer bir komut satırı aracı
    • Mevcut libcurl yerine entegre edilebilen bir kütüphane

Neden gerekli

  • Bir HTTP istemcisi TLS web sitesine bağlandığında önce bir TLS handshake gerçekleştirir
  • TLS handshake’in ilk mesajı Client Hello’dur ve çoğu HTTP istemcisi ile kütüphanenin oluşturduğu Client Hello gerçek tarayıcılardan ciddi biçimde farklıdır
  • Sunucu HTTP/2 kullanıyorsa TLS handshake’e ek olarak bir HTTP/2 handshake de yapılır ve burada çeşitli ayarlar değiş tokuş edilir
  • Çoğu HTTP istemcisi ve kütüphanesinin HTTP/2 ayarları da gerçek tarayıcılardan farklıdır
  • Bazı web servisleri bu farkları kullanarak bağlanan istemciyi tanımlar ve istemciye göre farklı içerik sunar
    • Bu yöntem TLS fingerprinting ve HTTP/2 fingerprinting olarak adlandırılır
    • README’ye göre bu yöntemlerin yaygın kullanımı web’i daha az açık, daha az özel ve belirli web istemcilerine daha kısıtlı hale getirmiştir

Nasıl çalışır

  • curl, tarayıcı gibi görünecek şekilde yoğun biçimde yamalanmıştır
  • Başlıca değişiklikler şunlardır
    • Firefox sürümü, OpenSSL yerine Firefox’un kullandığı TLS kütüphanesi NSS ile derlenir
    • Chrome sürümü, Google’ın TLS kütüphanesi BoringSSL ile derlenir
    • curl’ün çeşitli TLS uzantıları ve SSL seçeneklerini ayarlama biçimi değiştirilir
    • Yeni TLS uzantıları desteği eklenir
    • HTTP/2 bağlantılarında kullanılan ayarlar değiştirilir
    • curl, --ciphers, --curves ve bazı -H header’ları gibi varsayılan dışı bayraklarla çalıştırılır
  • Sonuç olarak ağ perspektifinden bakıldığında curl gerçek bir tarayıcıyla aynı görünür
  • Tam teknik açıklama part a ve part b içinde yer alır

Desteklenen tarayıcılar ve hedef adları

  • Desteklenen tarayıcı listesi browsers.json içinde de sunulur
  • Chrome tabanlı desteklenen hedefler
    • Windows 10 üzerinde Chrome 99, 100, 101, 104, 107, 110, 116
    • Android 12 üzerinde Chrome 99
    • Windows 10 üzerinde Edge 99, 101
    • MacOS Big Sur üzerinde Safari 15.3
    • MacOS Monterey üzerinde Safari 15.5
  • Firefox desteklenen hedefleri
    • Windows 10 üzerinde Firefox 91 ESR, 95, 98, 100, 102, 109, 117
  • Her desteklenen hedef için bir target name ve wrapper script vardır
    • Örn: chrome116 hedefi curl_chrome116 wrapper script’i ile çalıştırılır
    • Örn: ff117 hedefi curl_ff117 wrapper script’i ile çalıştırılır

Temel kullanım

  • Her desteklenen tarayıcı için gerekli header ve bayrakları içeren bir wrapper script ile curl-impersonate çalıştırılır
  • Çalıştırma örneği
    curl_chrome116 https://www.wikipedia.org
    
  • Ek komut satırı bayrakları verilirse curl’e aktarılır
  • Bazı bayraklar curl’ün TLS signature’ını değiştirerek tespit edilmesine neden olabilir
  • Wrapper script varsayılan bir HTTP header seti kullanır
    • Header’ları değiştirmek istenirse wrapper script amaca göre düzenlenebilir
  • Daha fazla seçenek, libcurl-impersonate’ın kütüphane olarak kullanıldığı gelişmiş kullanım bölümünde yer alır

Kurulum ve dağıtım biçimi

  • Teknik nedenlerle curl-impersonate iki sürümden oluşur
    • chrome sürümü: Chrome, Edge ve Safari taklidi için kullanılır
    • firefox sürümü: Firefox taklidi için kullanılır
  • Linux ve macOS Intel için önceden derlenmiş binary’ler GitHub releases üzerinden sağlanır
  • Önceden derlenmiş binary’leri kullanmadan önce NSS ve CA sertifikalarının kurulması gerekir
    • 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
  • Sistemde ayrıca zlib de gerekir
    • zlib neredeyse her zaman bulunur, ancak bazı minimal sistemlerde olmayabilir
  • Önceden derlenmiş Linux binary’leri Ubuntu sistemleri için oluşturulmuştur
    • Diğer dağıtımlarda sertifika doğrulama hatası alınırsa CA sertifikalarının konumunu curl’e belirtmek gerekebilir
    curl_chrome116 https://www.wikipedia.org --cacert /etc/ssl/certs/ca-bundle.crt
    
  • Kaynaktan derleme için INSTALL.md dosyasına bakılabilir

Docker ve paketler

  • Alpine Linux ve Debian tabanlı Docker imajları Docker Hub üzerinde sunulur
  • Docker imajları binary’leri ve tüm wrapper script’leri içerir
  • Örnek
    # 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
    
  • Archlinux kullanıcıları AUR paketlerini kullanabilir
  • Mac için gayriresmî Homebrew formula yalnızca Chrome sürümü için sunulur
    brew tap shakacode/brew
    brew install curl-impersonate
    

libcurl-impersonate gelişmiş kullanım

  • libcurl-impersonate.so, komut satırındaki curl-impersonate ile aynı değişikliklerle derlenmiş bir libcurl sürümüdür
  • Ek bir API fonksiyonu vardır
    CURLcode curl_easy_impersonate(struct Curl_easy *data, const char * target,
                                   int default_headers);
    
  • chrome116 gibi bir target name ile çağrıldığında, wrapper script’in ayarladığı seçenekleri ve header’ları içeride ayarlar
  • default_headers 0 ise yerleşik HTTP header listesi ayarlanmaz
    • Bu durumda kullanıcı header’ları normal CURLOPT_HTTPHEADER libcurl seçeneği ile kendisi sağlamalıdır
  • curl_easy_impersonate() birden çok libcurl seçeneği ayarlar
    • CURLOPT_HTTP_VERSION
    • CURLOPT_SSLVERSION, CURLOPT_SSL_CIPHER_LIST, CURLOPT_SSL_EC_CURVES, CURLOPT_SSL_ENABLE_NPN, CURLOPT_SSL_ENABLE_ALPN
    • Projeye özgü standart dışı seçenek CURLOPT_HTTPBASEHEADER
    • Projeye özgü standart dışı HTTP/2 seçenekleri CURLOPT_HTTP2_PSEUDO_HEADERS_ORDER, CURLOPT_HTTP2_NO_SERVER_PUSH
    • Projeye özgü standart dışı TLS seçenekleri CURLOPT_SSL_ENABLE_ALPS, CURLOPT_SSL_SIG_HASH_ALGS, CURLOPT_SSL_CERT_COMPRESSION, CURLOPT_SSL_ENABLE_TICKET
    • Projeye özgü standart dışı TLS seçeneği CURLOPT_SSL_PERMUTE_EXTENSIONS
  • Sonrasında bu seçeneklerden biri curl_easy_setopt() ile çağrılırsa, curl_easy_impersonate() tarafından ayarlanan değer geçersiz kılınır

Mevcut libcurl uygulamalarına uygulama

  • Uygulama hâlihazırda libcurl kullanıyorsa Linux üzerinde LD_PRELOAD ile mevcut kütüphane çalışma zamanında değiştirilebilir
  • Otomatik taklit uygulamak için CURL_IMPERSONATE ortam değişkeni ayarlanır
    LD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 my_app
    
  • CURL_IMPERSONATE iki etkiye sahiptir
    • curl_easy_init() ile yeni bir curl handle oluşturulduğunda curl_easy_impersonate() otomatik olarak çağrılır
    • curl_easy_reset() sonrasında da curl_easy_impersonate() otomatik çağrılır
  • HTTP header’ları üzerinde hassas kontrol gerekirse yerleşik header listesi CURL_IMPERSONATE_HEADERS=no ile devre dışı bırakılıp elle ayarlanabilir
    LD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 CURL_IMPERSONATE_HEADERS=no my_app
    
  • LD_PRELOAD yöntemi curl’ün kendisinde çalışmaz
    • Çünkü curl aracı TLS ayarlarını üzerine yazar
    • curl için wrapper script kullanılmalıdır

Depo yapısı ve katkı

  • Depoda iki ana klasör bulunur
    • chrome: Chrome sürümü curl-impersonate derlemesi için script’ler ve yamalar
    • firefox: Firefox sürümü curl-impersonate derlemesi için script’ler ve yamalar
  • Firefox dizini örnek olarak şu dosyaları içerir
    • Dockerfile: Tüm bağımlılıklarla birlikte curl-impersonate derlemek için kullanılır
    • curl_ff91esr, curl_ff95, curl_ff98: Doğru bayraklarla çalışan wrapper script’ler
    • curl-impersonate.patch: curl’ün Firefox ile aynı TLS uzantılarını kullanmasını sağlayan ana yamadır ve libnghttp2 ile libnss kullanacak şekilde statik derleme yapar
  • tests/signatures, taklit edilebilen bilinen tarayıcı signature’larının YAML veritabanıdır
  • Gerçek curl yamaları, upstream curl’den fork edilmiş ayrı bir depoda tutulur

1 yorum

 
GN⁺ 2025-04-04
Hacker News yorumları
  • Orijinaline göre epey fazla iyileştirme içeren ve aktif olarak bakımı yapılan bir fork var: https://github.com/lexiforest/curl-impersonate
    Python kullanıcıları için binding’ler de var: https://github.com/lexiforest/curl_cffi

    • “curl’ü tarayıcı gibi gösteren” bir programın bot tespiti atlatma hizmeti tarafından sponsorlanması bir bakıma doğal
    • Bunu Python requests kütüphanesi ile tamamen entegre eden bir modül de var: https://github.com/el1s7/curl-adapter
    • “Sertifikalı” üç büyük web tarayıcısından biri gibi görünen basit bir istek oluşturmak için, başını çevirme hızından bile hızlı değişen “ileri” teknolojileri takip etmek zorunda olmak tuhaf
      İşin ironik yanı, o istek sunucuya sertifikalı bir tarayıcıdan daha az yük bindirecek; 90’larda uyarısı yapılan distopya bu mu acaba. Kendini iyi niyetli açık kaynak/hacker topluluğu katkıcısı olarak konumlandırırken bu durumu yaratan o tek şirketin adını burada kim verebilir merak ediyorum
  • İleride Ladybird’ün güç kazanmasını umuyorum. Şu anda networking için resmi cURL’ü kullanıyor; bu yaklaşımın zorlukları olabilir
    Örneğin bildiğim kadarıyla cURL’ün hâlâ bazı kısıtları var ve h2 üzerinde WebSocket’i işleyemiyor. Öte yandan büyüyen bir tarayıcı motoru ortaya çıkarsa normal trafik de temel cURL ile aynı parmak izine sahip olur ve bu parmak izi alma yolu ortadan kalkabilir

    • Ladybird’ün cURL kullanımı, örneğin bahsedilen h2 üzerinde WebSocket gibi konularda cURL’ün kendisini geliştirmeye vesile olursa iyi olur
      Gerçek tarayıcı iş akışları temelinde cURL’de hangi özelliklerin eksik olduğunu görmek için de iyi bir test alanı
    • “Büyüyen bir tarayıcı motoru olursa bu parmak izi alma yolu ortadan kalkabilir” kısmı, CloudFlare vb. tarafında gördüklerime göre neredeyse tam tersi
      Son birkaç ayda parmak izi alma ve uygulama tanımlı davranışları “istismar etme” düzeyi ciddi biçimde arttı; muhtemelen başka tarayıcı motorlarını öldürme girişimi gibi görünüyor. Mevcut güçlü oyuncular rekabetten hiç hoşlanmıyor
      Karşı taraf bunu “yapay zeka botlarının DDoS’u” diye paketlemeye çalışıyor, ama bunun ne kadarının kendi yarattıkları bir iş olduğu şüpheli
    • Bu kişilerle konuştuğumda [0], imza oluşturan çeşitli tuhaf uygulama farklarını ele aldık; buna kullanıcı alanı uygulamalarının kontrol edemediği TCP yığını unsurları da dahildi
      Bu curl hoşuma gidiyor, ama bir bileşen “yetişmek” için kandırmaca rolünü üstlendiğinde bakımı zor bir “uyumluluk” yükünün birikmesinden endişe ediyorum
      İdeal olarak sadece “Merhaba, ben curl’üm, içeri al beni” diyebilmeliyiz
      Elbette sorun kıyafet kuralları konusunda titiz sunucularda; o sorun da kılık değiştirip içeri giren dolandırıcılar yüzünden ortaya çıkıyor, yani tavuk-yumurta gibi döngüsel
      [0] https://cybershow.uk/episodes.php?id=39
    • Bu sayede Ladybird’ün ftp URL desteği kazanması iyi olur
    • Ladybird’ün mevcut tarayıcılarla rekabet edecek kaynağı yok. Tanıtımı iyi yapıldı ama Chromium’a kıyasla avantajı ya da varlık nedeni zayıf
      Ayrıca kanıtlanabilir biçimde güvenli olmayan C++ ile yeniden tasarlanmış olması büyük bir güvenlik riski
  • Taklit etmeye çalıştığı platforma göre TTL değerini eşleştirmek için IP_TTL de ayarlanmış mı?
    Ayarlanmadıysa IP katmanında da bir ölçüde parmak izi alınabilir. IP katmanındaki TTL değeri 64’ün altındaysa, modern Windows’ta çalışmadığı ya da varsayılan TTL’i değiştirilmiş modern Windows olduğu açıktır. Çünkü modern Windows paketlerinin varsayılan TTL’i 128’den başlar, diğer platformların çoğu ise 64’ten başlar
    Diğer platformlarda da internet iletişiminde sorun olmadığı için, modern Windows’tan gelen IP paketleri uzak tarafta her zaman 64 veya üzeri, muhtemelen 64’ten biraz yüksek bir TTL ile görünür. Yine de IP katmanı parmak izi alma zor ama imkânsız değil

    • Düşük seviyeli TCP/IP yığını erişimi sunmayan PaaS/IaaS kullanırken zor. Kendi sunucunuzu işletiyorsanız her türlü TCP/IP özelliğinin parmak izini almak çok kolay
      https://en.wikipedia.org/wiki/TCP/IP_stack_fingerprinting
    • Gelen paketlerin TTL değeri ağ koşullarına göre değişmez mi? Sunucu istemcinin özgün değerini geri oluşturabilir mi?
    • TTL neden artacak şekilde değil de azalacak şekilde tasarlanmış? Genel olarak trafiği yönlendiren tarafın, yönlendirme yapılıp yapılmayacağına ve nasıl yapılacağına karar vermesi beklenmez mi?
  • Bir dakika, TLS el sıkışması farklı görünüyorsa, web tarayıcısı olduğunu iddia eden ama aslında Python/PHP betiği olan trafiği nginx seviyesinde filtreleyemez miyiz?
    Örneğin Chrome user-agent kullanan ama gerçek tarayıcı olmayan durumlar. Kötü niyetli bot trafiğinin çoğu buna giriyor olmalı; doğrudan engelleyebilsek iyi olurdu

    • Cloudflare, çeşitli TLS el sıkışması parametrelerinin hash’i olan JA3/JA4 TLS parmak izlerini kullanıyor
      Nasıl çalıştığı https://github.com/FoxIO-LLC/ja4/blob/main/technical_details... adresinde ayrıntılı anlatılıyor; bir Nginx modülü de sunuluyor: https://github.com/FoxIO-LLC/ja4-nginx-module
    • Temelde Cloudflare gibi güvenlik şirketlerinin yaptığı şey bu; buna ek olarak JavaScript yorumlayıcısını/DOM’u kontrol eden JavaScript challenge gibi daha fazla parmak izi alma yöntemi kullanıyorlar
    • Mümkün ve gerçek siteler bunu yapıyor, ama gerçekten berbat. Güvenilirliği düşük; güncel Windows üzerinde güncel Chrome kullanmayan herkesi engelleyiveriyor
      Şu anda fiilen saldırı altında değilseniz TLS parmak izi izin listesi kullanmamalısınız
    • Yazıdaki araç tam da bu tür engellemelerden kaçınmak için gibi görünüyor
  • Harika bir araç, ama istemcinin tarayıcı olup olmaması önemli olmamalı. Gerçekte böyle bir araca ihtiyaç duyulması acı verici.

    • Yaklaşık 6 ay önce Internet Explorer isteyen bir devlet ihale sitesine girmiştim. Gerçekten Internet Explorer istiyordu ve site de aktifti; ihale verileri günceldi.
      Chrome'a kullanıcı aracısı uzantısı ekleyip IE olarak değiştirerek tekrar denedim; çalıştı ve sitenin tüm işlevleri de sorunsuzdu. Bu yüzden hem buruk hem de sinir bozucuydu. Muhtemelen o devlet kurumu web sitesini 25 yıl önce yapmış ve o zamandan beri güncellememiş gibi.
    • Siteye ancak onayladığımız yazılımı kullanırsanız girebilirsiniz. Geri kalan her şeyi kötü amaçlı kabul ederiz. Evraklarınızı gösterin!
      Bu tür gatekeeping bana da acı verici geliyor. Anladığım kadarıyla, kendi yaptığınız özel tarayıcılar ya da kullanıcı aracıları; onları ikna edebilecek yeterli etki, para, kullanıcı sayısı gibi şeyler oluşana kadar Cloudflare tarzı sitelerde asla çalışmayacak.
  • Bu araç, red team çalışmalarında küçük bash betikleri ve GNU parallel ile birlikte kullanıldığında oldukça iyi.
    Kapsam olarak belirlenmiş adres aralıklarında, çeşitli nedenlerle yalnızca düzgün bir tarayıcıya yanıt veren veya SNI yapılandırması doğruysa yanıt veren HTTPS endpoint'lerini haritalarken faydalı oldu. Başlık taklidi için -H gibi normal curl seçenekleri de aynen kullanılabiliyor.

  • O zamanki Show HN gönderisi: https://news.ycombinator.com/item?id=30378562

    • O dönem, yani 2022'de yalnızca Firefox içindi.
  • Böyle şeyler burada her paylaşıldığında hep karışık duygulara kapılıyorum. Bir yandan insanlar arasında hâlâ biraz asi ruh ve bağımsızlığın yaşadığını göstermesi hoşuma gidiyor.
    Öte yandan, “özgürlük istikrarsızdır” muamelesi gören diğer projelerde olduğu gibi, istenmeyen ilgiyi üzerine çekerse buna bağımlı olan insanlar için durum daha da kötüleşebilir. Tarayıcı yazmak zor ve mevcut güçlü oyuncular bunu sürekli daha da zorlaştırıyor.

    • Tarayıcı geliştiricileri tarayıcıların parmak iziyle tanımlanabilir olmasını istiyormuş gibi gelebilir, ama bu daha çok farklı insanların farklı şekillerde uygulama yapmasıyla kendiliğinden ortaya çıkan bir durum.
      Bunu bir asi ruh meselesi olarak görmüyorum. Yazılımların parmak iziyle tanımlanabilir hâle gelmesi gizlilik korumasını ve yazılım çeşitliliğini aşındırıyor.
  • Web sitelerinin botları sorun etmiyorsa izin verdiği, istemiyorsa kullanıcı aracısını engellediği basit zamanları biraz özlüyorum.

    • O zamanlar web siteleri bugünkü kadar kaynak tüketmiyordu. Botlara yönelik olumsuz tepkinin, web deneyimine dair beklentilerin aşırı ağırlaşmasından doğan bir yan etki olduğunu düşünüyorum.
  • Sadece 3 yama ve bir shell wrapper'dan ibaretse Daniel'ın kodlamaya girişmesine değer. Şahsen bunun mutlaka mainline curl'e girmesi gerektiğini düşünüyorum.