2 पॉइंट द्वारा GN⁺ 2023-08-28 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • Apple TV और iPhone पर YouTube विज्ञापनों को नेटवर्क स्तर पर रोकने के लिए pfSense, DNS blocking, VPN routing, Squid, MITMProxy से होते हुए Protobuf response modification तक प्रयोग किया गया
  • YouTube विज्ञापन सामान्य वीडियो वाले ही domain से serve होते हैं, इसलिए Pi-hole·pfBlockerNG जैसे DNS blocking भर से content और विज्ञापनों को भरोसेमंद तरीके से अलग करना कठिन था
  • TLS traffic को MITMProxy से decrypt करने के बाद web YouTube के JSON ad fields हटाए गए, और iOS app में application/x-protobuf response के अंदर ad structure को सीधे खोजकर modify किया गया
  • Python आधारित full Protobuf decoding में pfSense router पर लगभग 23 सेकंड लगे, लेकिन /pagead/ के आसपास linear scan करने के तरीके से 1.8MiB payload भी real-time में process करना संभव हो गया
  • इस तरीके के लिए trusted CA install करना और पर्याप्त CPU performance चाहिए; network से जुड़े Apple devices पर ad blocking संभव हुआ, लेकिन बाद में YouTube Premium subscription पर भी विचार करना पड़ा

pfSense router और network separation

  • लक्ष्य FreeBSD·pfSense आधारित router बनाकर Apple TV और iPhone के YouTube pre-roll, mid-roll, end-roll ads को पूरे network में block करना था
  • इस्तेमाल किया गया hardware AES-NI instruction set वाला J4125 mini PC, DDR4 RAM, mSATA SSD, और pfSense installation USB drive था
    • उदाहरण configuration 32GiB RAM और 128GB mSATA SSD थी
    • 128GB storage को logs, SSD wear कम करने, packet capture, और edge cache space के लिए उपयोगी माना गया
  • pfSense install करने के बाद LAN 1 को existing DHCP range से बाहर static IP 192.168.1.3 पर set किया गया और admin web portal में admin/pfsense account से access किया गया
  • pfSense dashboard में AES-NI CPU Crypto: Yes (inactive) display की पुष्टि करने के बाद System › Advanced › Miscellaneous में AES-NI को manually enable किया गया
  • 32GiB RAM का उपयोग करके /var और /tmp के लिए RAM disk उदारता से allocate की गई, और RAM-disk backup हर घंटे run होने के लिए configure किया गया

DNS blocking और physical network separation

  • मौजूदा Pi-hole की जगह pfSense package pfBlockerNG-devel install करके ads·malicious content blocking और geo-blocking configure किया गया
    • installation size में लगभग 20MiB extra जोड़ा गया
    • अगर pfb_dnsbl service start न हो या [ Missing CRON task ] दिखे, तो /var/run/booting empty file delete करने की कोशिश करने को कहा गया
  • pfSense router के 3 Gigabit ports को VLAN की जगह physical LAN separation के लिए इस्तेमाल किया गया
    • Alexa और Apple TV जैसे phoning-home devices को अलग hardware LAN में रखा गया
    • important LAN को smart devices·Wi-Fi devices से अलग करके banking, stock trading, crypto wallet इस्तेमाल करने वाले devices को protect करने की कोशिश की गई
  • smart devices के लिए network को 172.31.1.0/24 में अलग किया गया, और ज्यादा trusted LAN को 192.168/16 में रखा गया
    • माना गया कि networks के बीच route न हो तो misconfigured iptables rules का असर भी कुछ हद तक कम होता है
    • नए network devices को address मिल सके, इसके लिए physical NIC पर DHCP resolver enable करना जरूरी है
  • AC1200 Archer C5 को AP mode न होने, remote access problem, पुराने stock firmware, और Broadcom chipset के OpenWRT/DD-WRT/Tomato support की कमी के कारण हटा दिया गया
  • इसके बाद Nighthawk R7000 को Apple/Amazon/TV के लिए AP और Trusted Wireless Network के लिए AP के रूप में इस्तेमाल किया गया
    • Trusted Wireless Network में 2.4GHz बंद करके केवल 5GHz इस्तेमाल करने का फैसला किया गया
    • 5GHz walls और concrete से ज्यादा आसानी से block होता है, इसलिए medium-range snooping से बचने में फायदेमंद माना गया

सभी DNS को pfSense पर force करना

  • pfSense के पीछे सभी clients local Unbound DNS server इस्तेमाल करें, इसके लिए NAT rules add किए गए
    • उद्देश्य था कि apps और home assistants अपने DNS server या hardcoded DNS servers से bypass न कर सकें
    • pfBlockerNG को DNS requests में हस्तक्षेप करना हो तो DNS over TLS block करना जरूरी है
  • NAT rules WAN को छोड़कर हर interface पर बनाए जाते थे, बाद में Non_WAN firewall alias से simplify किया गया
    • IPv4 और IPv6 दोनों में port 53 की local DNS queries को localhost पर redirect किया गया
    • NAT reflection disabled रखना चाहिए, ताकि external internet से local DNS server access न हो सके
  • Services › DNS Resolver › Display Custom Options में server: log-queries: yes add करके intercepted DNS requests की logging की गई
  • DNS logs में Windows द्वारा Google Tag Manager access करने की कोशिश वाले requests दिखे, और उन requests को non-existent IP 10.10.10.1 पर blackhole किया गया

VPN से YouTube ad targeting bypass करने की कोशिश

  • YouTube ads सामान्य video वाले ही domain से आते हैं, इसलिए pfBlockerNG या Pi-hole जैसे domain blockers से सिर्फ ads चुनकर निकालना मुश्किल था
    • googleadservices.com block करना तभी meaningful माना गया जब ad video देखने के बाद ad पर click किया जाए
    • browser में uBlock Origin JavaScript में intervene कर सकता है, लेकिन iPhone YouTube app में jailbreak के बिना ads limit करना मुश्किल माना गया
  • ads को सीधे block करने के बजाय यह प्रयोग किया गया कि YouTube ad algorithm user को कम attractive ad target समझे
    • idea था Apple TV traffic को VPN से भेजना और ऐसे region के VPN endpoint का उपयोग करना जहां YouTube viewers कम हों
    • लक्ष्य user को Italy में रहने वाले 70 साल के पुरुष जैसा दिखाना था
  • pfSense में WireGuard configure किया गया और NordLynx/WireGuard private key Linux VM से लाकर set की गई
    • कहा गया कि tunnel address डालते समय 1.0.0.0 और subnet mask 0 डालें तो UI result 0.0.0.0/0 के रूप में दिखता है
  • Apple TV का पूरा traffic VPN से भेजने पर YouTube Italian में दिखा और ads की संख्या कम हुई, लेकिन Netflix और Amazon Prime में समस्याएं आईं
    • ऐसा लगा जैसे CSS या font files block हो रही हों और thumbnails load न हो रहे हों
    • चेतावनी दी गई कि Netflix और Prime VPN providers पर geofencing अच्छी तरह करते हैं
  • बाद में केवल YouTube-related FQDN को VPN से route करने के लिए www.youtube.com, youtube.com, googlevideo.com, accounts.google.com, googleapis.com, gstatic.com आदि को candidates माना गया
    • configuration के बाद YouTube ने user को Milan में माना, और Netflix तथा Prime Video ने Canada में माना
    • ads rare हो गए, और जो ads दिखे वे भी Italian ads थे

DNS race condition और wildcard domain की समस्या

  • एक दिन बाद पता चला कि pfSense hostname alias और client DNS cache, YouTube IP के अलग-अलग set देख रहे थे—यह DNS race condition थी
    • pfSense hostname alias का default resolve interval 300 सेकंड है
    • YouTube DNS TTL 1,440 सेकंड देखा गया
  • अगर Alias Daemon द्वारा FQDN resolve करके मिला IP और Apple TV को बाद में मिला IP मेल न खाए, तो traffic VPN tunnel से छूट सकता है
    • इसका mitigation यह है कि pfSense target TTL को ignore करे और alias entry को ज्यादा देर तक cache रखे
  • googlevideo.com के variant subdomain के लिए wildcard routing की जरूरत थी, लेकिन NAT और firewall rule IP-based तरीके से काम करते हैं और wildcard hostname को सीधे handle नहीं कर पाते
  • Unbound Python module और pfSense REST API का इस्तेमाल करके DNS response IP capture करने और उन्हें VPN_wildcards alias में dynamically जोड़ने वाला PoC लिखा गया
    • VPN_wildcards TTL 1 घंटा और capacity 500 set की गई
    • A record को ipaddress.IPv4Address और AAAA record को ipaddress.IPv6Address से parse किया गया
  • सुबह check करने पर Unbound DNS Resolver segfault state में था, और हर IP जोड़ने पर pfSense rule reload की जरूरत पड़ रही थी, जिससे pfSense बहुत धीमा हो गया

Squid और MITMProxy से HTTPS decrypt करना

  • नया लक्ष्य Squid जैसा proxy install करना और device में fake-but-trusted CA certificate add करके TLS traffic decryption करना था
  • Squid को pfSense package के रूप में install किया गया और SSL Filtering smoke test तक सफल रहा, लेकिन इसे छोड़ दिया गया
    • performance बहुत धीमी थी
    • ACL configuration झंझट भरा था
    • https://http/* से जुड़ा issue था
    • SquidGuard URL filter list update में बहुत समय लगा
    • Squid UI अपर्याप्त लगा
  • इसके बाद MITMProxy चुना गया
    • इसमें Python scripting और UI है, और इसे YouTube ad blocking के हिसाब से extend किया जा सकता है
    • mitmproxy 7.0.4 Linux tarball FreeBSD पर ELF interpreter /lib64/ld-linux-x86-64.so.2 not found और library missing होने के कारण run नहीं हुआ
  • pfSense के FreeBSD jail environment में pkg install mitmproxy से install किया गया
    • install होने वाले package 50 थे, extra space 206MiB और download size 33MiB था
    • jail के अंदर mitmproxy run करने पर UI खुलता है
  • MITMProxy experiment के लिए pfSense में 127.0.1.1 virtual IP को localhost से जोड़ा गया, और NAT rule से [Private IPs]:8080 को 127.0.1.1:8080 पर forward किया गया
    • victim laptop का proxy 192.168.20.1:8080 set करने पर browser request MITMProxy UI log में दिखाई दी
  • MITMProxy CA PEM file ~/.mitmproxy/mitmproxy-ca-cert.pem है
    • Python 3 web server से cert.pem serve किया गया
    • MITMProxy mitm.it पर भी वही CA certificate provide करता है
    • साफ-सुथरे laptop और iPhone में certificate add किया गया

MITMProxy operation और certificate pinning से निपटना

  • router पर mitmproxy idle state में भी काफी CPU use कर रहा था; इसकी वजह हर request पर TLS certificate on-the-fly generate करना और UI की excessive logging मानी गई
  • mitmdump में UI और extreme logging नहीं होती, इसलिए CPU load कम माना गया
    • run करते समय --anticomp, --mode regular, --listen-port 8080, --listen-host 127.0.1.1 आदि use किए गए
  • Certificate Pinning वह technique है जिसमें server या client को expected certificate fingerprint पहले से पता होता है, इसलिए MITMProxy certificate forgery काम नहीं करती
    • workaround के रूप में --ignore-hosts use करके apple.com:443, icloud.com:443 जैसे hosts को proxy bypass करने दिया गया
  • Transparent Proxy Mode में --allowed-hosts को SNI के आधार पर बेहतर काम कराने के लिए MITMProxy 7.0.4 के next_layer.py को patch किया गया
    • पहले माना गया कि कई cases में matching के लिए सिर्फ server IP use होता था
    • patch ने server.address[0] के साथ-साथ server.sni को भी hostname candidate में add किया
  • patch के बाद कुछ hosts को reliably intercept और बाकी को pass through किया जा सका

Web YouTube का JSON ad हटाना

  • MITMProxy smoke test में YouTube ad/tracking URLs को एक छोटी script से block किया गया
    • youtube.com पर /pagead/, /log_event?, /stats/ads, /stats/qoe?, /ptracking?, /generate_204, el=adunit, adformat=, /activeview? आदि block किए गए
    • google.com और google.ca पर /pagead/ block किया गया
  • शुरुआती test में blocked requests DevTools Network panel में भी सच में blocked दिखीं
    • (failed) entries script से generate हुईं
    • 502 failure को pfBlockerNG द्वारा request को black-hole करने का result माना गया
    • HTTP/2 disable किया गया ताकि same channel की subsequent requests आगे न जा सकें
  • सिर्फ URL blocking से ads पूरी तरह गायब नहीं हुए, और YouTube HTML/JavaScript व uBlock Origin filters देखते हुए यह संभावना track की गई कि ad information JSON response body में हो सकती है
  • MITMProxy द्वारा capture किए गए JSON response में playerAds और playbackTracking structure में ad/tracking information confirm हुई
    • playerAds में playerLegacyDesktopWatchAdsRenderer, playerAdParams, gutParams.tag, showCompanion, showInstream, useGut आदि शामिल थे
    • playbackTracking में videostatsPlaybackUrl, ptrackingUrl, qoeUrl, atrUrl आदि शामिल थे
    • youtubeRemarketingUrl का format www.youtube.com/pagead/viewthroughconversion/... था
  • Web YouTube में JSON payload से ad information हटाकर router के जरिए web ads हटाए जा सके

iOS YouTube और Protobuf विश्लेषण

  • iOS YouTube ऐप, web version जैसी API calls में JSON के बजाय Protocol Buffer(Protobuf) format का data इस्तेमाल करता है
    • Protobuf में keys numeric होती हैं और बदल सकती हैं, इसलिए JSONPath तरीके से ad section ढूंढना मुश्किल होता है
    • payload में “Telus”, “Samsung TV”, “Boxing Week”, “Buy now” जैसी ad strings दिखीं
  • iOS YouTube network traffic, web traffic से अलग था
    • web version में video chunk के range या clen parameters से ad candidates का कुछ हद तक अनुमान लगाया जा सकता है
    • iOS protocol range query parameter या Range header का इस्तेमाल नहीं करता, बल्कि &nr=2, &nr=3 जैसे counters इस्तेमाल करता है
  • Protobuf response को decode करके offline analysis करते समय has_unlimited_entitlement: False, has_premium_lite_entitlement: False जैसे items मिले
    • इन values को बदलने का तरीका “cheating” जैसा लगा, इसलिए फिर heuristic approach पर लौटे
  • ad URL blocking experiment से iOS ऐप में infinite loop, UI errors और crashes हुए
    • empty body वाले 200, 404, 503, truncated response body, ad video के कुछ हिस्सों को null करने से ऐप slow हो गया या broken state में crash हो गया
    • /error_204/ error-reporting endpoint “dev assertion failed” दिखाता है और block करता है
  • ad किसी खास video के अंदर slot में registered लगते हैं
    • slot types में pre-roll, mid-roll, end-roll, full-page, ad pod शामिल हैं
    • सिर्फ ad URL block करने पर “मौजूद न होने वाला ad slot reserve कर चुका है” जैसे errors आते हैं और UI panic state में चला जाता है

Protobuf performance समस्या और blackboxprotobuf

  • सिर्फ Python से लगभग 500KiB raw Protobuf को human-readable text में decode करना बहुत slow था
    • i7-6700 CPU desktop पर लगभग 2.06~2.11 seconds लगा
    • pfSense router पर लगभग 22.8~24.2 seconds लगा
  • C++ protoc --decode_raw काफी तेज था
    • i7-6700 CPU desktop पर लगभग 0.017~0.022 seconds लगा
    • pfSense router पर लगभग 0.12~0.14 seconds के आसपास था
  • Python में raw decoding support नहीं होने के कारण C++ protoc binary और subprocess.Popen से सीधे communicate करने का तरीका चुना गया
  • Burp Suite के लिए blackboxprotobuf raw Protobuf wire message को decode कर सकता है, values inject करने के बाद re-encode कर सकता है
    • PyPI fork के बजाय original Burp Suite version इस्तेमाल करने की सलाह दी गई
    • कुछ forks deep recursion के कारण stack overflow करा सकते हैं
    • protobuf import करने से पहले os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "cpp" set करने पर, संभव हो तो C++ libprotobuf.so implementation इस्तेमाल होता है
  • blackboxprotobuf का protobuf_to_json(data) best-guess .proto schema बना सकता है, लेकिन result बहुत बड़ा, गहराई से nested और पूरी तरह perfect नहीं होता
    • Python schema dump लगभग 250,000 characters से ज्यादा था
    • इसे ad details निकालने के लिए पर्याप्त माना गया

1-byte बदलाव से ad section को निष्क्रिय करना

  • Protobuf Wire Format को original schema के बिना decode/edit/re-encode करने पर encoding बदल सकती है
    • कारणों में ZigZag encoding का इस्तेमाल हुआ है या नहीं, numeric type की पहचान न हो पाना, और object field order की non-determinism बताई गई
  • solution Protobuf की backward compatibility का इस्तेमाल करके ad section को unknown field जैसा बनाना था
    • old software जब नया field पढ़ता है, तो unknown field को ignore करने वाले behavior का उपयोग किया गया
    • critical spot पर 1 byte बदलकर deeply nested section को future schema version का हिस्सा जैसा बना दें, तो Protobuf इसे ignore कर देता है
  • target field key 49399797 को simple string search से नहीं, बल्कि varint tag scanning से ढूंढना पड़ा
    • wire type 2 है, जिसका मतलब length-delimited nested string/message है
    • target tag की गणना AA FF B8 BC 01 के रूप में हुई
    • wire type के 3 bits shift out करने पर field key 49399797 restore होता है
  • actual search में raw Protobuf bytes में पहले /pagead/ जैसी ad URL signature ढूंढी जाती है, फिर उसके आसपास पीछे जाकर target field tag और field key खोजे जाते हैं
    • example intercept target POST youtubei.googleapis.com:443/youtubei/v1/browse?key=... है
    • response 200, application/x-protobuf, 1.87m था
    • example log में 49399797 position 4465 पर और 50195462 position 4477 पर मिला
  • O(n) smoke test में 1.8MiB Protobuf data को extra memory के बिना एक बार scan करके ad removal काम करता दिखा
    • target 30,593वें byte पर मिला
    • लगभग 600 byte backtracking से mutate करने वाला field key मिला
    • अब *.googleadservices.com या /pagead/ वाले URLs को block करने की जरूरत नहीं रहती, और ऐसा request शुरुआत से ही बनता नहीं है

MITMProxy ऐडऑन की संरचना

  • PoC स्क्रिप्ट को youtube.py के रूप में सेव किया जाता है और mitmdump --listen-port 8080 --listen-host 127.0.0.1 -s "youtube.py" से चलाया जाता है
    • FreeBSD prerequisite के तौर पर pkg install protobuf, pkg install py38-pip, pip install jsonpath-ng बताए गए हैं
  • स्क्रिप्ट Logger, trunc, KilledError, JSONPathReplacement, ProtobufDebugParser, YouTubeAdBlocker classes से बनी है
  • YouTubeAdBlocker का intercept target host regex \.youtube\.com|google\.(com|ca)|googleapis\.com|googleadservices\.com|googlevideo\.com है
    • Protobuf विज्ञापन URL search string b"/pagead/" है
    • search limit 80_000 है
    • target field tag 50195462 है
  • request blocking rule host के हिसाब से partial URL strings चेक करके flow को kill करता है
    • youtube.com target में pagead/, log_event?, stats/ads, stats/qoe?, ptracking?, generate_204, error_204, adformat=, activeview?, _ad_, ai?, sw.js आदि शामिल हैं
    • sw.js में service workers को reject करने की टिप्पणी है
  • JSON response में कई JSONPath replacements लागू किए जाते हैं
    • $.responseContext.serviceTrackingParams[*].params[?(@.key == 'yt_ad')].value को "0" में बदला जाता है
    • $..adPlacements को [] में बदला जाता है
    • $..adPlacementRenderer, $..adPlacementConfig, $..playerAdParams, $..gutParams को {} में बदला जाता है
    • $..adVideoId को खाली string में बदला जाता है
    • $..showCompanion, $..showInstream, $..useGut को False में बदला जाता है
  • Protobuf response में, जब content type में protobuf हो, body को bytearray बनाया जाता है और शुरुआती 80,000 bytes के भीतर /pagead/ खोजा जाता है
    • TagBytes(self.target_field_tag, WIRETYPE_LENGTH_DELIMITED) से target tag bytes बनाए जाते हैं और target_field_tag - 1 के नए bytes बनाए जाते हैं
    • /pagead/ की position से ठीक पहले तक उलटी दिशा में search करके target tag bytes खोजे जाते हैं
    • अगर मिल जाएं, तो उन bytes को नए bytes से overwrite किया जाता है और flow.response.set_content(bytes(body)) से response body replace की जाती है
  • टिप्पणी में लिखा है कि यह PoC 90% विज्ञापन block करता है
    • दूसरे sections में भी अलग field key हैं, और ऐसे कई ad sections हो सकते हैं जिन्हें corrupt करना पड़े

लागू दायरा और सीमाएं

  • इस technique को Apple-device YouTube विज्ञापनों या Instagram, WhatsApp, Facebook जैसे tracker traffic को block करने के लिए highly specialized technique के रूप में बताया गया है
  • HTTPS traffic को decrypt/re-encrypt करने की CPU requirement Raspberry Pi की क्षमता से काफी ज्यादा मानी गई है
  • Apple TV jailbreak करने के बाद pfSense root certificate जोड़ने पर pfSense gateway Apple TV traffic को decrypt कर सकता है और request header में विज्ञापन hostname की जांच करके block कर सकता है, ऐसा माना गया है
    • हालांकि यह अब भी iPhone विज्ञापनों पर लागू नहीं होता, और iPhone jailbreak ज्यादा मुश्किल है तथा banking app इसे detect करके काम करना बंद कर सकते हैं
    • jailbreak अपने आप में बहुत extreme माना गया है
  • fake trusted CA संभव हो तो TLS packet को plaintext में decrypt करके URL blocking लागू की जा सकती है
    • example block URL के तौर पर YouTube के /pagead/viewthroughconversion/... और /pagead/conversion/... paths दिए गए हैं
  • अंत में hardware router को शुरुआत से configure किया गया, LAN को trusted zone और untrusted zone में बांटा गया, DNS ad blocking और transparent MITM proxy जोड़ी गई, और फिर network से जुड़े Apple devices पर YouTube विज्ञापनों को अच्छी performance के साथ block किया गया

YouTube Premium और creators को support

  • कई महीनों तक YouTube विज्ञापन block करने के बाद content creators को support करना चाहा और YouTube Premium का payment शुरू किया
    • यह caveat जोड़ा गया कि “सिर्फ इसलिए कि आप कर सकते हैं, इसका मतलब यह नहीं कि आपको करना चाहिए”
  • YouTube Premium की कीमत CAD $9.99/mo से $11.99/mo, tax सहित लगभग $13.43/mo बताई गई है
  • विज्ञापन देखने के experiment में, एक clean laptop और private browsing के साथ एक दिन तक YouTube को रुक-रुककर देखा गया
    • record के अनुसार 10 videos देखे गए
    • 8 विज्ञापन दिखे, जिनमें से केवल 2 skippable थे
  • CPV को USD $0.15 मानने पर एक दिन की विज्ञापन लागत $1.20 और महीने का extrapolation लगभग USD $36/mo होता है
  • Statista numbers का उपयोग करते हुए दूसरी calculation में, 2019 में अमेरिकी advertisers ने YouTube पर $15.1 billion खर्च किए और US residents ने 916 billion videos देखे, जिससे average per view USD $0.0165 आया
    • यह calculation लागू करने पर एक दिन की cost लगभग USD $0.13 और महीने का extrapolation लगभग USD $3.96 है
    • इसे Premium के USD $10 के आसपास नहीं माना गया
  • DMCA claim लगने पर ad revenue creator के बजाय Sony या Viacom जैसे claimants को जा सकता है
    • इस वजह से आप अनजाने में अपने पसंदीदा channel को कुछ भी नहीं दे पा रहे हो सकते हैं
    • कई creators का Patreon पर जाना आश्चर्यजनक नहीं माना गया

2 टिप्पणियां

 
xguru 2023-08-29

मूल लेख बहुत लंबा है। प्रक्रिया दिलचस्प है, लेकिन असली बात यह है कि लेखक ने आखिर में बस YouTube Premium का भुगतान करके उसे इस्तेमाल करना शुरू कर दिया।

 
GN⁺ 2023-08-28
Hacker News की राय
  • कुल मिलाकर यह शानदार hacking है, लेकिन Protobuf के बारे में कुछ expressions अजीब लगते हैं
    Protobuf में किसी field के tag को जानबूझकर खराब किया गया है; अनपहचाने tag number को ignore करना “defect” नहीं, बल्कि extensibility के लिए core design है
    1.87MiB भी कोई बहुत बड़ा size नहीं है, और शायद ऐसे messages लगातार stream भी नहीं हो रहे होंगे, इसलिए इसे performance barrier बताना भी बहुत convincing नहीं लगता
    Protobuf encoding decoding cost को महंगा बनाने के लिए design नहीं की गई थी; उल्टा, इसे efficient decoding के लिए design किया गया है, और original .proto schema न होने पर भी UnknownFieldSet से सीधे decode किया जा सकता है
    शायद बेहतर तरीका यह होता कि जिस एक field को हटाना है, केवल उसे शामिल करने वाला fake .proto schema इस्तेमाल किया जाता। string scan वाला तरीका ज्यादा error-prone है, क्योंकि वही byte sequence संयोग से दूसरे data में भी आ सकता है
    field order बदलने पर re-encoding का resulting byte अलग हो सकता है, लेकिन receiver को इसे वही message मानकर process करना चाहिए, और YouTube app के field order में बदलाव detect करने की संभावना कम लगती है
    पहले Protobuf पर काम कर चुके व्यक्ति के तौर पर देखें तो लगता है author ने इस हिस्से को गलत समझा है

    • analysis अच्छी है, लेकिन 1.87MB को छोटा कहना थोड़ा मानना मुश्किल है
      मैंने अपनी ज़िंदगी का ज्यादातर हिस्सा rural areas में बिताया है, और अगर यह मेरा Wi-Fi न हो तो इतना भी असल में बड़ा download है। mobile पर शायद workarounds हों, लेकिन rural Wi-Fi अभी भी Web 2.0 architecture से जूझता है और आम तौर पर 2~4G speeds पर इस्तेमाल होता है
      urban areas जैसी जगहों पर, जहां infrastructure को support करने के लिए population है, 1.87MB आम तौर पर छोटी file बन चुकी होगी, लेकिन शाम करीब 6 बजे, जब cable line पर जुड़े लोग सब streaming कर रहे होते हैं, exception हो सकता है
    • without the C++ source proto files के बारे में थोड़ा plug करूं तो, मैंने protodump नाम का project बनाया है जो binary से source .proto files generate करता है
      यह messages और field definitions को original names सहित recreate कर देता है, और Apple TV box से सिर्फ binary निकाल लाना काफी है
      https://github.com/arkadiyt/protodump
    • “पहले Protobuf पर काम किया था” बहुत ही understated expression है। जिन्हें नहीं पता, उनके लिए बता दूं कि Kenton वही व्यक्ति हैं जिन्होंने Protobuf को आज के रूप में बनाया
      Protobuf वह technology थी जिसने मुझे पहली बार IDL से परिचित कराया, और उस समय यह किसी magical idea जैसा लगा था। खुद एक कमजोर IDL बनाने के बाद Protobuf खोजा, तो और भी ज्यादा हैरानी हुई
    • यह article पढ़ते हुए मुझे भी इसी तरह confusion हुआ। Protobuf design principles कोई secret नहीं हैं, और सब clearly documented हैं
    • schema के बिना Protobuf decode करते समय सबसे tricky हिस्सा यह है कि embedded messages और strings एक ही tag type इस्तेमाल करते हैं, फिर भी इसे काफी आसानी से handle किया जा सकता है
      अगर पूरी protoc dependency नहीं लानी है, तो कुछ सौ lines का simple Protobuf decoder खुद लिखा जा सकता है: https://github.com/kubernetes/test-infra/blob/master/guberna... https://github.com/kubernetes/test-infra/blob/master/guberna...
  • 20 साल से भी ज्यादा पहले The Proxomitron मिलने के बाद से, ads हटाने और user CSS जैसी चीजों से pages को rewrite करने के लिए traffic को man-in-the-middle proxy से process करता आया हूं
    CloudFlare जैसी जगहें मुझे “bot” के तौर पर classify करने की tendency रखती हैं, लेकिन उसे भी, भले आसान न हो, bypass करने के तरीके हैं। ऐसे examples यह भी दिखाते हैं कि remote attestation user freedom के लिए क्यों खतरनाक है

    • The Proxomitron के बारे में देखा तो लगता है development 2004 में खत्म हो गई थी; अगर current landscape पर कोई अच्छी summary हो तो दिलचस्प होगा
      लगता है कई “successor” projects हैं, और यह भी जानना चाहूंगा कि क्या यह Windows-only है। मैं remote content में local links insert कर सकने वाली simple proxy को हल्के-फुल्के तौर पर खोज रहा था
    • Privoxy या pi-hole जैसे network-level ad blocking में inline ads handle न कर पाने जैसी बहुत ज्यादा कमियां हैं
      अभी तो Pi 4 पर चल रहा pi-hole भी निकालकर अलग रख दिया है। कई services के साथ इसे ठीक से काम कराने में कई घंटे लगाए, लेकिन अंत में हार मान ली, और home network पर लगाने लायक time value नहीं लगा
      असल में जो अच्छी तरह काम करता है, वे browser-based ad blockers और ReVanced जैसे app patchers हैं। savings बढ़ने के साथ, YouTube Premium, Hulu, Netflix, Max जैसे cases में जहां इन दोनों से काम नहीं चलता, मैं बस ad-free service के लिए pay करने की तरफ ज्यादा झुकने लगा हूं
    • Cloudflare के employees यहां छिपकर देखते हैं, ऐसा पता है, इसलिए curious हूं। इस तरह bot के रूप में classify होना क्या false positive माना जाता है, या intended behavior?
    • Proxomitron के बारे में लगभग 20 साल से सोचा भी नहीं था, curious हूं कि क्या कोई अब भी इसे use कर रहा है
      यहां बताए गए use case के लिए इसे कभी इस्तेमाल नहीं किया, लेकिन company firewall के पीछे proxy के तौर पर यह शानदार था। पहले firewall external connections के लिए login info मांगते थे, इसलिए कई programs internet access नहीं कर पाते थे
    • शायद इसमें device पर नया CA certificate install करना पड़ता होगा, सही है?
  • Docker में पैकेज किया गया Privaxy याद आया। यह UBlock Origin ब्लॉकलिस्ट के साथ compatible एक man-in-the-middle proxy है
    स्मार्ट products, खासकर TV पर ads और tracking scripts कितनी ज्यादा होती हैं, यह देखकर हैरानी होती है। अब तक किए गए tests में गैर-ज़रूरी traffic 40% से ज़्यादा था, और smart TV apps से ads हटाने का प्रयोग काफी मज़ेदार रहा
    https://github.com/deetungsten/webui-privaxy https://github.com/Barre/privaxy का Dockerized fork है

    • TV को self-signed certificate पर trust कैसे करवाएँ?
    • इसे यहाँ भी देखकर अच्छा लगा। filter list ping issue उठाने के लिए अच्छा लगा
      Docker container को सच में isolate कर सकें, इसके लिए frontend में hardcoded 0.0.0.0 address इस्तेमाल न हो, ऐसा fork में बदलाव करना चाहता था, लेकिन ज़िंदगी बीच में आ गई। Apple TV पर आज़माया है?
    • Adguard भी कुछ ऐसा ही काम कर रहा है
      https://github.com/AdguardTeam/urlfilter
    • “Dockerized fork” का मतलब GUI को web GUI में बदल दिया गया है यह समझने में मुझे बहुत देर लग गई
  • यह लेख अक्सर पूछे जाने वाले “hacker बनने के लिए कैसे सीखना चाहिए?” सवाल का शानदार जवाब है
    किसी भी exploit में शामिल सोचने की प्रक्रिया और लगातार मेहनत को यह अच्छी तरह दिखाता है

  • “WireGuard इस्तेमाल करें — Intel AES-NI encryption instruction set है” वाला हिस्सा है, लेकिन मेरी जानकारी में WireGuard AES इस्तेमाल नहीं करता
    कुल मिलाकर लेखक TLS encryption की CPU requirements को कुछ ज़्यादा आँकता है, या modern single-board computers की performance को कम आँकता लगता है
    Raspberry Pi पर HTTPS traffic decrypt और re-encrypt करने के लिए CPU requirements बहुत ज़्यादा पार हो जाती हैं, यह स्पष्टीकरण भी अजीब लगा। अगर RPi 4 पर TLS man-in-the-middle processing सच में practical नहीं है, तो मुझे काफी हैरानी होगी, और pure software RSA इस्तेमाल करने पर भी यही बात है
    अभी इस्तेमाल हो रहे कुछ Android phones में RPi 4 से कमजोर CPU भी होते हैं, और वे भी TLS इस्तेमाल करते हैं

    • लगता है आप CPU requirements को कम आँक रहे हैं
      कोई कमजोर Android phone TLS traffic सिर्फ 50Mb/s तक ही process कर पाए, तब भी real-world use में बड़ी समस्या नहीं हो सकती। क्योंकि धीमे phones आम तौर पर धीमे networks से जुड़े होते हैं
      दूसरी ओर, अगर घर में gigabit internet है और सभी computers व internet के बीच रखे किसी कमजोर device की वजह से 50Mb/s का bottleneck बन जाए, तो यह बड़ी समस्या होगी
      TLS की CPU requirements target bandwidth पर बहुत ज्यादा निर्भर करती हैं। higher bandwidth पर accelerators को offload करना practically ज़रूरी भी हो सकता है। handshake cost भी नज़रअंदाज़ करना मुश्किल है और प्रति सेकंड connections की संख्या सीमित कर सकता है। एक single device में यह शायद ही कभी समस्या बनता है, लेकिन पूरे device network में बड़ा हो सकता है
  • शानदार लेख। मैं उम्मीद कर रहा था कि custom CA install करने की अनुमति न देने वाले devices को man-in-the-middle करने का तरीका मिलेगा
    मेरे पास एक IoT device है जो local API expose नहीं करता और सिर्फ cloud के ज़रिए data दिखाता है, और मैं device और cloud के बीच का traffic capture करना चाहता हूँ
    आखिर में flash memory dump करके CA बदलने और फिर वापस flash करने के अलावा कोई तरीका नहीं होगा क्या?

    • अगर certificate “hardcoded” है, तो उसे certificate pinning कहते हैं। ऐसे में traffic decrypt करने के लिए आपको certificate को replace या remove करना होगा, और वही certificate man-in-the-middle proxy में ले जाना होगा
      hardware या firmware work के बिना IoT device को intercept करने के तरीके आज़माने के लिए एक अच्छा लेख है:
      https://robertheaton.com/2019/11/21/how-to-man-in-the-middle...
    • custom CA install करने की अनुमति न देने वाले device को man-in-the-middle करने का तरीका ढूँढना, आखिरकार TLS के उद्देश्य के खिलाफ जाना है
      अगर यह संभव है, तो वह implementation flaw पर निर्भर होगा
      सच कहूँ तो, जिन कुछ devices पर अभी अपना trusted certificate install किया जा सकता है, मुझे लगता है कि उनके भी ऐसे दिन अब ज़्यादा नहीं बचे हैं
  • YouTube या किसी भी platform पर ads block करने के नए तरीके हमेशा आते रहते हैं, लेकिन कुछ महीनों बाद platform बदल जाता है और वे बेकार हो जाते हैं
    इसके बजाय advertisers पर हमला करना कैसा रहेगा? YouTube/Google “clicks” ही track करता दिखता है, लेकिन क्या actual purchases तक track करता है?
    सिद्धांततः, अगर पर्याप्त fake bots और real users ads पर click करें लेकिन कुछ भी न खरीदें, तो ad budget जला सकते हैं। समय के साथ marketing department देखेगा कि किसी platform पर clicks record high हैं, लेकिन clicks या impressions की तुलना में conversion rate बहुत कम है, और आखिरकार वे उस platform से हट सकते हैं

    • Nauseum को Chrome Store से block किया गया था, यह देखते हुए लगता है कि यह काफी असरदार है
  • कमाल का लेख। mitm patch वाला step दिखते ही लगा कि यह कुछ खास होगा, और सच में ऐसा ही था

  • table of contents में “नया लक्ष्य: YouTube को यह यकीन दिलाना कि मैं Italy में रहने वाला 70 साल का पुरुष हूँ” प्रभावशाली लगा
    पहले किसी तरह ad targeting को यह यकीन हो गया था कि मैं अपनी partner के लिए 500 डॉलर की washable silk pajamas खरीदना चाहता हूँ
    ads खुद तो बेहतरीन थे, लेकिन सोचता हूँ प्रति impression कितना भुगतान कर रहे होंगे
    Apple TV पर switch करने के बाद आम तौर पर region targeting गलत होने वाले local ads आते हैं। औसतन शायद वही बेहतर लगता है

  • यह Protobuf की “खामी” नहीं है। bytes को बदलने पर उनका किसी दूसरी जगह के field के रूप में decode होना बिल्कुल intended behavior है
    Protobuf शुरू से ही field number और length-prefix आधारित protocol है, और यह उचित मानता है कि transmission के दौरान bytes नहीं बदलेंगे; integrity की जिम्मेदारी पढ़ने वाले पक्ष पर छोड़ता है
    मान भी लें कि यह कोई खामी है, तो वह Protobuf की नहीं बल्कि iOS के लिए YouTube app की खामी होगी, और असल में यह खामी भी नहीं है, इसलिए इसे “exploit” कहना भी मुश्किल है। हाँ, अगर बात यह है कि YouTube iOS app के Protobuf exchange में लौटे हुए payload hash की जाँच नहीं की जाती, तो अलग बात है
    इस लेख के बाद शायद वे जाँच करने लगेंगे

    • लेखक की wording थोड़ी अजीब है। “खामी” सिर्फ शीर्षक में आता है, और body बस यह समझाती है कि format कैसे काम करता है
      यह खामी नहीं, design के हिसाब से काम करना है
      “Google C++ source proto file के बिना decoding, modification, re-encoding को computationally महंगा बना देता है” वाला हिस्सा भी अजीब है। Unoptimized Python code से करेंगे तो महंगा होगा, लेकिन C या किसी दूसरी compiled language में लिखें तो proto source file हो या न हो, 1.8MB Protobuf scan करना मामूली काम है
      मुझे नहीं लगता कि Protobuf file को source के बिना decode करना मुश्किल बनाना कोई design goal रहा होगा। अगर यही लक्ष्य था, तो यह काफी खराब तरीके से किया गया है
    • मुझे नहीं पता कि Protobuf में required fields कैसे काम करते हैं, लेकिन attack को mitigate करने के लिए Google का YouTube client उस field को required field की तरह treat कर सकता है, और field न हो या default value हो तो service deny कर सकता है
    • लेख की तारीख जनवरी 2022 है। अगर blog post के बाद वे protocol को मजबूत करना चाहते, तो संभव है कि वे यह पहले ही कर चुके हों