curl-impersonate: प्रमुख browsers की नकल कर सकने वाला खास curl build
(github.com/lwthiker)- curl-impersonate एक बदला हुआ curl build है जो Chrome, Edge, Safari, Firefox जैसा दिखने वाला TLS और HTTP handshake करता है, और इसे CLI tool तथा
libcurlreplacement library के रूप में इस्तेमाल किया जा सकता है - सामान्य HTTP clients और libraries के Client Hello तथा HTTP/2 settings असली browsers से काफी अलग होते हैं, इसलिए कुछ web services TLS/HTTP handshake से client की पहचान कर अलग content देती हैं
- Implementation में Firefox के लिए NSS, Chrome-family के लिए BoringSSL का उपयोग, TLS extensions·SSL options·HTTP/2 settings में बदलाव, और
--ciphers,--curves, headers जैसे non-default flags लागू करना शामिल है - Supported targets में Chrome 99~116, Android Chrome 99, Edge 99·101, Firefox 91 ESR~117, Safari 15.3·15.5 हैं, और हर target के लिए wrapper script और target name दिया गया है
- Command line में
curl_chrome116चलाया जाता है, और library integration मेंcurl_easy_impersonate()या Linux केLD_PRELOADऔरCURL_IMPERSONATEसे मौजूदाlibcurlइस्तेमाल करने वाले apps पर लागू किया जा सकता है
curl-impersonate जिस समस्या को हल करता है
- curl-impersonate एक project है जो curl को खास तौर पर build करके उसे Chrome, Edge, Safari, Firefox जैसे 4 प्रमुख browsers की नकल करने योग्य बनाता है
- यह TLS और HTTP handshakes को असली browser के साथ ठीक उसी तरह कर सकता है
- इस्तेमाल के दो तरीके हैं
- सामान्य curl जैसा command-line tool
- मौजूदा
libcurlकी जगह integrate की जा सकने वाली library
इसकी जरूरत क्यों है
- जब कोई HTTP client किसी TLS website से connect करता है, तो पहले TLS handshake करता है
- TLS handshake का पहला message Client Hello होता है, और अधिकतर HTTP clients और libraries द्वारा बनाया गया Client Hello असली browsers से काफी अलग होता है
- अगर server HTTP/2 इस्तेमाल करता है, तो TLS handshake के अलावा HTTP/2 handshake भी होता है, जहां कई settings exchange होती हैं
- अधिकतर HTTP clients और libraries की HTTP/2 settings भी असली browsers से अलग होती हैं
- कुछ web services इन फर्कों का उपयोग करके connecting client की पहचान करती हैं और client के हिसाब से अलग content देती हैं
- इस तरीके को TLS fingerprinting और HTTP/2 fingerprinting कहा जाता है
- README के अनुसार, इस तरह के व्यापक उपयोग ने web को कम खुला, कम निजी, और खास web clients तक ज्यादा सीमित बना दिया है
यह कैसे काम करता है
curlको browser जैसा दिखाने के लिए काफी patch किया गया है- मुख्य बदलाव ये हैं
- Firefox version में OpenSSL की जगह Firefox द्वारा इस्तेमाल की जाने वाली TLS library NSS के साथ curl compile किया जाता है
- Chrome version को Google की TLS library BoringSSL के साथ compile किया जाता है
- curl द्वारा कई TLS extensions और SSL options set करने के तरीके बदले जाते हैं
- नए TLS extensions का support जोड़ा जाता है
- HTTP/2 connection में इस्तेमाल होने वाली settings बदली जाती हैं
--ciphers,--curves, कुछ-Hheaders जैसे non-default flags के साथ curl चलाया जाता है
- नतीजतन, network के नजरिए से curl असली browser जैसा ही दिखता है
- पूरा technical explanation part a, part b में है
Supported browsers और target names
- Supported browsers की list
browsers.jsonमें भी दी गई है - Chrome-family supported targets
- 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
- Firefox supported targets
- Firefox 91 ESR, 95, 98, 100, 102, 109, 117 on Windows 10
- हर supported target के लिए target name और wrapper script है
- उदाहरण:
chrome116target कोcurl_chrome116wrapper script से चलाते हैं - उदाहरण:
ff117target कोcurl_ff117wrapper script से चलाते हैं
- उदाहरण:
Basic usage
- हर supported browser के लिए जरूरी headers और flags के साथ
curl-impersonateचलाने वाली wrapper script है - Example run
curl_chrome116 https://www.wikipedia.org - Command-line flags जोड़ने पर वे curl को pass किए जाते हैं
- कुछ flags curl की TLS signature बदल सकते हैं और detect हो सकते हैं
- wrapper script default HTTP headers set का उपयोग करती है
- Headers बदलने के लिए जरूरत के हिसाब से wrapper script edit की जा सकती है
- ज्यादा options
libcurl-impersonateको library की तरह इस्तेमाल करने वाली advanced usage में शामिल हैं
Installation और distribution method
- Technical कारणों से
curl-impersonateके दो versions हैं- chrome version: Chrome, Edge, Safari की नकल के लिए इस्तेमाल
- firefox version: Firefox की नकल के लिए इस्तेमाल
- Linux और macOS Intel के लिए precompiled binaries GitHub releases पर उपलब्ध हैं
- Precompiled binaries इस्तेमाल करने से पहले NSS और CA certificates install करना जरूरी है
- 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
- Ubuntu:
- System में zlib भी चाहिए
- zlib लगभग हमेशा होता है, लेकिन कुछ minimal systems में नहीं हो सकता
- Precompiled Linux binaries Ubuntu systems के लिए build किए गए हैं
- अगर किसी अन्य distribution पर certificate verification error आए, तो curl को CA certificate location बतानी पड़ सकती है
curl_chrome116 https://www.wikipedia.org --cacert /etc/ssl/certs/ca-bundle.crt - Source build के लिए INSTALL.md देखें
Docker और packages
- Alpine Linux और Debian-based Docker images Docker Hub पर उपलब्ध हैं
- Docker image में binaries और सभी wrapper scripts शामिल हैं
- Examples
# 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 users AUR packages इस्तेमाल कर सकते हैं
- Precompiled packages: curl-impersonate-bin, libcurl-impersonate-bin
- Source build packages: curl-impersonate-chrome, curl-impersonate-firefox
- Mac के लिए unofficial Homebrew formula सिर्फ Chrome के लिए उपलब्ध है
brew tap shakacode/brew brew install curl-impersonate
libcurl-impersonate advanced usage
libcurl-impersonate.soएक libcurl है जिसे command-linecurl-impersonateजैसी ही changes के साथ compile किया गया है- इसमें additional API function है
CURLcode curl_easy_impersonate(struct Curl_easy *data, const char * target, int default_headers); chrome116जैसे target name से call करने पर wrapper script द्वारा set किए जाने वाले options और headers internally set हो जाते हैं- अगर
default_headers0 है, तो built-in HTTP headers list set नहीं की जाती- User को सामान्य
CURLOPT_HTTPHEADERlibcurl option से खुद headers provide करने होंगे
- User को सामान्य
curl_easy_impersonate()कई libcurl options set करता हैCURLOPT_HTTP_VERSIONCURLOPT_SSLVERSION,CURLOPT_SSL_CIPHER_LIST,CURLOPT_SSL_EC_CURVES,CURLOPT_SSL_ENABLE_NPN,CURLOPT_SSL_ENABLE_ALPN- Project-specific non-standard option
CURLOPT_HTTPBASEHEADER - Project-specific non-standard HTTP/2 options
CURLOPT_HTTP2_PSEUDO_HEADERS_ORDER,CURLOPT_HTTP2_NO_SERVER_PUSH - Project-specific non-standard TLS options
CURLOPT_SSL_ENABLE_ALPS,CURLOPT_SSL_SIG_HASH_ALGS,CURLOPT_SSL_CERT_COMPRESSION,CURLOPT_SSL_ENABLE_TICKET - Project-specific non-standard TLS option
CURLOPT_SSL_PERMUTE_EXTENSIONS
- बाद में
curl_easy_setopt()से ऊपर के options में से किसी को call करने परcurl_easy_impersonate()द्वारा set value overwrite हो जाती है
मौजूदा libcurl apps पर लागू करना
- अगर application पहले से
libcurlइस्तेमाल कर रही है, तो Linux परLD_PRELOADसे runtime में existing library को replace किया जा सकता है CURL_IMPERSONATEenvironment variable set करके automatic impersonation लागू करेंLD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 my_appCURL_IMPERSONATEके दो effects हैंcurl_easy_init()से नया curl handle बनते समयcurl_easy_impersonate()automatically call होता हैcurl_easy_reset()के बाद भीcurl_easy_impersonate()automatically call होता है
- अगर HTTP headers को precise control करना हो, तो
CURL_IMPERSONATE_HEADERS=noसे built-in headers list disable करके खुद set करेंLD_PRELOAD=/path/to/libcurl-impersonate.so CURL_IMPERSONATE=chrome116 CURL_IMPERSONATE_HEADERS=no my_app LD_PRELOADmethod curl itself पर काम नहीं करता- क्योंकि curl tool TLS settings overwrite कर देता है
- curl के लिए wrapper script इस्तेमाल करनी होगी
Repository structure और contribution
- Repository में दो main folders हैं
- Firefox directory example में ये files शामिल हैं
- Dockerfile: सभी dependencies के साथ
curl-impersonatebuild करने में इस्तेमाल - curl_ff91esr, curl_ff95, curl_ff98: सही flags के साथ चलाने वाली wrapper scripts
- curl-impersonate.patch: मुख्य patch जो curl को Firefox जैसे TLS extensions इस्तेमाल करने देता है, और इसे libnghttp2 और libnss के साथ static compile कराता है
- Dockerfile: सभी dependencies के साथ
- tests/signatures imitate किए जा सकने वाले known browser signatures का YAML database है
- वास्तविक curl patches upstream curl से fork किए गए अलग repository में maintain होते हैं
- Firefox changes impersonate-firefox branch में हैं
- Chrome changes impersonate-chrome branch में हैं
1 टिप्पणियां
Hacker News की राय
मूल से काफी ज़्यादा सुधारों वाला और सक्रिय रूप से maintain किया जा रहा fork मौजूद है: https://github.com/lexiforest/curl-impersonate
Python users के लिए bindings भी हैं: https://github.com/lexiforest/curl_cffi
विडंबना यह है कि वह request certified browser की तुलना में server पर कम load डालेगी, फिर भी लगता है कि 90s में जिस dystopia की चेतावनी दी जाती थी, वह शायद यही है। अच्छी open source/hacker community contributor की तरह positioning करते हुए भी यह स्थिति बनाने वाली एक company का नाम यहां कौन ले पाएगा, यह सोचने वाली बात है
आगे चलकर Ladybird को traction मिले, ऐसी उम्मीद है। अभी networking के लिए वह official cURL इस्तेमाल कर रहा है, लेकिन इस approach में मुश्किलें हो सकती हैं
उदाहरण के लिए, मेरी जानकारी में cURL में अभी भी कुछ limitations हैं और वह h2 के ऊपर WebSocket handle नहीं कर पाता। दूसरी तरफ, अगर एक बढ़ता हुआ browser engine हो, तो legitimate traffic का fingerprint भी default cURL जैसा हो सकता है और fingerprinting का यह रास्ता गायब हो सकता है
यह देखने के लिए भी एक अच्छा testbed है कि असली browser workflows के हिसाब से cURL में कौन-सी capabilities missing हैं
पिछले कुछ महीनों में fingerprinting और implementation-defined behavior का “दुरुपयोग” करने का level काफी बढ़ गया है, और शायद यह दूसरे browser engines को खत्म करने की कोशिश लगती है। मौजूदा dominant players को competition बिल्कुल पसंद नहीं है
दूसरी side इसे “AI bots का DDoS” बताकर पेश करने की कोशिश करती है, लेकिन सवाल है कि इनमें से कितना खुद उन्होंने ही पैदा किया है
यह curl मुझे पसंद है, लेकिन चिंता है कि अगर कोई component “catch up” करने के लिए छलावे की भूमिका निभाए, तो maintain करना मुश्किल “compatibility” baggage जमा हो जाएगा
ideally तो बस “नमस्ते, मैं curl हूं, मुझे अंदर आने दो” कह पाना चाहिए
बेशक समस्या उन servers में है जिनका dress code बहुत strict है, और वह समस्या फिर उन impostors की वजह से पैदा होती है जो disguise पहनकर अंदर आते हैं, इसलिए यह chicken-and-egg जैसा circular मामला है
[0] https://cybershow.uk/episodes.php?id=39
साथ ही, यह provably unsafe C++ में फिर से design किया गया है, इसलिए बड़ा security risk भी है
जिस platform का impersonation करना है, उसके हिसाब से TTL value match करने के लिए क्या
IP_TTLभी set किया गया होगा?अगर नहीं, तो IP layer पर भी कुछ हद तक fingerprinting संभव है। IP layer की TTL value 64 से कम हो तो साफ है कि वह modern Windows पर नहीं चल रहा, या फिर modern Windows है जिसकी default TTL बदली गई है। क्योंकि modern Windows packets की default TTL 128 से शुरू होती है, और अधिकांश दूसरे platforms 64 से शुरू करते हैं
दूसरे platforms पर भी internet communication में कोई दिक्कत नहीं होती, इसलिए modern Windows से आए IP packets remote side पर हमेशा 64 या उससे अधिक, शायद 64 से थोड़ा ज़्यादा TTL के साथ दिखेंगे। हालांकि IP layer fingerprinting मुश्किल है, पर असंभव नहीं
https://en.wikipedia.org/wiki/TCP/IP_stack_fingerprinting
रुकिए, अगर TLS handshake अलग दिखता है, तो क्या nginx level पर उस traffic को filter नहीं किया जा सकता जो खुद को web browser बताता है लेकिन असल में Python/PHP script है?
जैसे Chrome user agent इस्तेमाल करता है पर actual browser नहीं है। malicious bot traffic का बड़ा हिस्सा यही होगा, इसलिए अगर इसे बस block किया जा सके तो अच्छा होगा
यह कैसे काम करता है, इसका detail https://github.com/FoxIO-LLC/ja4/blob/main/technical_details... में है, और Nginx module भी मिलता है: https://github.com/FoxIO-LLC/ja4-nginx-module
अगर आप पर अभी सचमुच attack नहीं हो रहा है, तो TLS fingerprint allowlist इस्तेमाल नहीं करनी चाहिए
शानदार टूल है, लेकिन यह मायने नहीं रखना चाहिए कि क्लाइंट ब्राउज़र है या नहीं। असल दुनिया में ऐसे टूल की ज़रूरत पड़ती है, यह बात कड़वी लगती है
Chrome में user agent extension जोड़कर उसे IE में बदलकर फिर कोशिश की, तो वह चल गई, और साइट की सारी functionality भी ठीक थी। इसलिए यह कड़वा भी लगा और झुंझलाहट भी हुई। शायद उस सरकारी agency ने 25 साल पहले website बनाई और उसके बाद update नहीं किया
ऐसी gatekeeping मुझे भी कड़वी लगती है। मेरी समझ से, खुद बनाए गए custom browser या user agent Cloudflare जैसी sites पर तब तक कभी काम नहीं करेंगे, जब तक उनके पास उन्हें मनाने लायक प्रभाव, पैसा, user base जैसी चीज़ें न हो जाएँ
यह टूल red team work में छोटे bash scripts और GNU parallel के साथ मिलाकर इस्तेमाल करने पर काफ़ी अच्छा है
scope में दिए गए address ranges के अंदर, उन HTTPS endpoints को map करने में उपयोगी रहा जो कई वजहों से केवल proper browser को ही response देते हैं या सही SNI configuration होने पर ही response देते हैं। header masquerading के लिए
-Hजैसे सामान्य curl options भी वैसे ही इस्तेमाल किए जा सकते हैंउस समय की Show HN पोस्ट: https://news.ycombinator.com/item?id=30378562
जब भी ऐसी चीज़ यहाँ आती है, हमेशा mixed feelings होती हैं। एक तरफ अच्छा लगता है कि लोगों में अभी भी थोड़ा-सा विद्रोही स्वभाव और स्वतंत्रता बची हुई है
दूसरी तरफ, जिन दूसरे projects को “freedom is instability” की तरह treat किया जाता है, उनकी तरह अगर इस पर अनचाहा attention आ गया, तो जिन लोगों की निर्भरता इस पर है, उनके लिए हालात और खराब हो सकते हैं। browser लिखना मुश्किल है, और मौजूदा बड़े players इसे लगातार और मुश्किल बना रहे हैं
मैं इसे विद्रोही स्वभाव का मुद्दा नहीं मानता। software का fingerprintable होना privacy protection और software diversity को कमज़ोर करता है
उन सरल दिनों की थोड़ी याद आती है, जब websites bots को ठीक समझतीं तो allow कर देतीं, और पसंद न होने पर user agent block कर देतीं
अगर यह बस 3 patches और shell wrapper की बात है, तो Daniel शायद coding में उतर सकते हैं। निजी तौर पर मुझे लगता है कि इसे ज़रूर mainline curl में जाना चाहिए