1 puan yazan GN⁺ 2025-03-19 | 1 yorum | WhatsApp'ta paylaş
  • Apple TV ile internet arasına pfSense tabanlı bir MITM proxy koyup HTTPS trafiğini çözdükten sonra, YouTube’un gönderdiği Protobuf yanıtlarını değiştirerek Apple cihazlarında reklam slotlarının kaydedilmemesini sağlayan bir PoC
  • Mevcut DNS engelleyiciler ve VPN yönlendirmesi, YouTube reklamlarıyla asıl videonun aynı alan adı ve altyapıyı kullanması nedeniyle DNS TTL, IP uyuşmazlığı, 403 hataları ve ASN leak gibi sınırlara takıldı
  • Squid denemesi performans ve yapılandırma sorunları nedeniyle bırakıldı; ardından FreeBSD jail içindeki mitmproxy/mitmdump ile TLS trafiği çözülerek JSON ve Protobuf yanıtlarının doğrudan değiştirildiği bir yaklaşıma geçildi
  • Web YouTube’da JSON içindeki adPlacements, playerAdParams, pagead URL’leri kaldırılabiliyordu; ancak iOS YouTube uygulamasında reklam slotları ve izleme bilgileri application/x-protobuf yanıtlarında taşındığı için Protobuf yapısının ele alınması gerekti
  • Nihai yöntem, /pagead/ dizgesinin yakınında field tag’i tersten bularak 50195462 gibi etiketleri target_field_tag - 1 değerine çeviren doğrusal tarama ve 1 baytlık değişiklik yaklaşımıydı; tam çözümleme olmadan gerçek zamanlı işleme uygun performans sağladı

Hedef ve ilk ağ tasarımı

  • Amaç, FreeBSD ve pfSense tabanlı bir yönlendirici kurarak Apple TV ve iPhone’daki pre-roll, mid-roll ve end-roll YouTube reklamlarını ağ genelinde engellemekti
  • Apple TV ile dış internet arasına bir man-in-the-middle proxy yerleştirilirse HTTPS trafiği çözülebilir ve Google’ın YouTube reklamlarını doldurmak için kullandığı Protocol Buffer verileri okunabilirdi
  • Birkaç ay boyunca YouTube reklam engellemeyi uyguladıktan sonra YouTube Premium aboneliği başlatıldığı, ayrıca “yapabilmek” ile “yapmak gerekmesi”nin farklı şeyler olduğu belirtildi
  • Reklam ve takip engelleme gerekçeleri olarak gizlilik takibi, bant genişliği israfı, clickbait ve cryptojacking gösterildi
    • Ağ trafiğinin %25 ila %40’ının reklamlar, takip script’leri, fingerprint.js, googletagmanager.js ve Hotjar gibi gerçek zamanlı analiz yükleyicilerinden oluşabileceği düşünüldü
    • CoinHive.js gibi crypto-mining JavaScript’lerinin bilgisayarı aşırı ısıtabileceği veya kötüye kullanılarak küçük miktarlarda kazanç elde edilebileceği açıklandı

pfSense donanımı ve temel ayarlar

  • Tüm SMB ağını korumak için VM, Docker imajı veya Raspberry Pi’nin performans açısından yetersiz kalacağı; bu nedenle yalnızca paket yönlendirme, çözme ve izleme işi için özel donanım gerektiği düşünüldü
  • Kullanılan yönlendirici donanımı, AES-NI komut setine sahip bir mini PC, DDR4 RAM, mSATA SSD ve pfSense flash’lamak için bir USB sürücüden oluşuyordu
    • Örnek yapılandırma J4125 mini PC, 32GiB DDR4 RAM ve 128GiB mSATA SSD idi
    • 128GB depolamanın loglar, SSD aşınmasını azaltma, paket yakalama ve NPM ile Docker edge cache için yeterli olduğu düşünüldü
  • pfSense kurulum imajı yaklaşık 360MB boyutundaydı ve USB sürücüye Etcher AppImage ile yazdırılabiliyordu
  • İlk kurulumdan sonra AES-NI “Yes (inactive)” olarak göründü ve System › Advanced › Miscellaneous altında elle etkinleştirildi
  • 32GiB RAM’den yararlanmak için /var ve /tmp için geniş RAM disk ayrıldı; 128GiB SSD’de wear-leveling beklentisiyle RAM disk yedeklerinin saatlik alınması ayarlandı
  • Dashboard’a SSD sorunlarını tespit etmek için S.M.A.R.T. widget’ı eklendi

DNS engelleme, ağ ayrımı ve pfBlockerNG

  • Daha önce Raspberry Pi üzerindeki Pi-hole DNS düzeyinde reklam engelleyici olarak kullanılıyordu; pfSense üzerinde ise reklam ve kötü amaçlı içerik engelleme ile geo-blocking denemeleri için pfBlockerNG-devel kuruldu
  • pfb_dnsbl servisi başlamıyorsa veya status sekmesinde [ Missing CRON task ] görünüyorsa boş /var/run/booting dosyasının silinmesi önerildi
  • Mini PC’nin 3 Gigabit portu kullanılarak VLAN yerine fiziksel olarak ayrılmış ağlar kuruldu ve Alexa ile Apple TV gibi “phoning-home” cihazlar ana ağdan ayrıldı
    • Güvenilmeyen cihazlar 172.31.1.0/24 özel ağına yerleştirildi
    • Güvenilir LAN 192.168/16 üzerinde tutuldu
    • IoT için ayrılan donanım LAN’ı adblocker üzerinden geçirildi ve 1.1.1.1, 9.9.9.9 gibi hard-coded DNS sorguları ele geçirilerek YouTube’un DNS engelleyiciyi atlatması önlenmek istendi
  • pfSense arkasındaki tüm istemcilerin yerel Unbound DNS sunucusunu kullanması için NAT kuralları yapılandırıldı
    • DNS sorgularını ele geçirmek için önce DNS over TLS’in engellenmesi gerektiği düşünüldü
    • iPhone, şifrelenmiş DNS trafiğinin engellenmesine dair bir Privacy Warning gösterebilse de upstream DNS isteklerinin Cloudflare’a şifreli gönderildiği belirtildi
    • Dış internetin DNS sunucusuna erişememesi için NAT reflection’ın devre dışı bırakılması gerektiği ifade edildi
  • WAN dışındaki arayüzlerdeki yerel DNS sorgularını 53 numaralı porttan localhost’a yönlendirmek için Non_WAN firewall alias’ı oluşturuldu
  • YouTube reklamları ve asıl videoyu aynı alan adından sunduğu için, pfBlockerNG veya Pi-hole gibi alan adı engelleyicilerle yalnızca reklamları filtrelemek zordu

VPN atlatma deneyi ve başarısızlık noktaları

  • Reklam engellemek yerine YouTube reklam algoritmasını kandırıp kullanıcıyı reklamverenler için daha az cazip gösterecek bir deney de yapıldı
    • pfSense yönlendirici ile YouTube’un konum izleme trafiğini VPN üzerinden, izleyici sayısının daha az olduğu bölgelere yönlendirme amaçlandı
    • YouTube hesabında kullanıcının “70 yaşında erkek, İtalya’da yaşıyor” gibi görünmesi hedeflendi
  • pfSense üzerinde Apple TV’nin tüm trafiğini VPN’den geçirmek için OpenVPN yerine WireGuard kullanılarak bir referans deneyi yapıldı
    • FreeBSD WireGuard paketi kuruldu ve tunnel eklendikten sonra etkinleştirildi
    • NordLynx yapılandırması için Linux VM üzerinde sudo wg showconf nordlynx ile private key görüntülenip pfSense’e taşındı
  • Test sonucunda dizüstü bilgisayardaki Google arayüzü İtalyanca görünmeye başladı ve Apple TV’deki YouTube da İtalyanca oldu
    • Reklamlar hâlâ kısmen görünüyordu ancak öncesine göre azaldığı belirtildi
    • Netflix ve Amazon Prime tarafında sorunlar çıktı; CSS ya da font dosyalarının engellenmiş olabileceği veya thumbnail’lerin yüklenmediği düşünüldü
    • Apple TV’nin tüm trafiğinin VPN’den geçirilmemesi gerektiği konusunda uyarı yapıldı; Netflix ve Prime’ın VPN sağlayıcılarını ve geofencing’i iyi tespit ettiği düşünüldü
  • Sonrasında yalnızca Apple TV’nin YouTube trafiğini VPN üzerinden geçirmek için www.youtube.com, youtube.com, googlevideo.com, accounts.google.com, googleapis.com, gstatic.com gibi alanlar için firewall policy kuralları oluşturuldu
    • Sonuç olarak YouTube kullanıcıyı Milano’da, Netflix ve Prime Video ise Kanada’da görüyordu
    • Reklamların “few and far between” denecek kadar azaldığı belirtildi
  • Bir gün sonra DNS race condition ortaya çıktı
    • pfSense hostname alias’ları varsayılan olarak her 300 saniyede bir resolve ediliyordu
    • YouTube DNS TTL değeri ise 1.440 saniye, yani 24 dakika olabiliyordu
    • Alias Daemon’ın resolve ettiği IP ile istemcinin gerçekten aldığı IP farklı olduğunda policy, YouTube trafiğini tünelden geçiremeyebiliyordu
  • Bazı YouTube videoları 403 Forbidden hatasıyla oynatılamadı
    • YouTube’un her googlevideo.com isteğine kullanıcının IP’sini gömdüğü belirtildi
    • r5---sn-hpa7kn76.googlevideo.com gibi türetilmiş alan adları tünele alınmazsa istek yanlış IP’den çıkıyor ve sorun oluşuyordu
    • Gereken şey *.googlevideo.com için wildcard tünellemeydi; ancak NAT ve firewall kuralları wildcard hostname’lerle değil IP’lerle çalışıyordu

DNS sorgusu tabanlı IP izleme PoC

  • *.googlevideo.com alanını VPN üzerinden yönlendirmek için Google Video DNS query hijack yöntemini tasarladı
    • DNS sorgu günlüklerini periyodik olarak izleyip *.googlevideo.com sorgularını alias listesine ekleyen bir yöntemdi
    • Her video benzersiz ve değiştirilmiş bir domain kullanıyorsa, her videoda yenileme yapılmadıkça bu yöntemin çalışmayacağını düşündü
  • Yeni hedef, Python 3 ve pfSense REST API ile DNS sorgularını izleyip IP’yi yakalamak, yanıtı kısa süre bekletmek, ardından IP’yi VPN tunneling kuralına ekleyip DNS yanıtını serbest bırakmaktı
  • pfSense REST API’yi kurup https://pfsense/api/v1/firewall/alias adresine GET isteği göndererek VPN_domains alias’ını sorguladı
  • Unbound DNS Resolver’ın Python modülünü inceleyip DNS sorgu mesajlarını günlüklemeyi başardı
    • O sıradaki Python sürümü 3.8’di
    • Unbound Python modülü örnekleri Python 2.4 tabanlı olduğundan 2to3 veya biçimlendirme gerekebileceğini düşündü
  • PoC script’i, DNS yanıtındaki A/AAAA record IP’lerini çıkarıp pfSense alias’ına ekliyordu
    • A kaydı ipaddress.IPv4Address(d.rr_data[j][2:]).exploded ile işleniyordu
    • AAAA kaydı ipaddress.IPv6Address(d.rr_data[j][2:]).exploded ile işleniyordu
    • alias TTL değeri 1 saat, capacity ise 500 olarak ayarlandı
  • Ertesi gün Unbound DNS Resolver segfault verdi ve her IP eklemede pfSense kuralını yeniden yüklemek gerektiği için pfSense çok yavaşladı

Squid’den mitmproxy’ye geçiş

  • Yeni hedef, Squid tabanlı proxy’leri araştırıp kurmak, güvenilen sahte bir CA certificate oluşturmak ve TLS trafiğini çözümlemek yönüne kaydı
  • Squid denemelerinde, pfSense paketi olarak sunulan squid3 proxy’sinin gereksinimleri karşılayıp karşılamadığını test etti
    • Ayrı bir /squid_cache klasörü oluşturup cache boyutunu 8GiB olarak ayarladı
    • Transparent HTTPS support bekliyordu
  • Squid ve SquidGuard’ı bir gün yapılandırdıktan sonra vazgeçti
    • Hız çok düşüktü
    • ACL ayarları zahmetliydi
    • https://http/* ile ilgili bir issue vardı
    • SquidGuard URL filter list update işlemi çok uzun sürüyordu
    • Squid arayüzü yetersizdi
  • Sonrasında Python ile yazılmış mitmproxy kullanmaya karar verdi
    • Python hook genişletilebilirliği ve arayüzü nedeniyle SSLSplit yerine mitmproxy’yi seçti
    • pfSense’in FreeBSD sürümü 12.2-Stable, 64-bit build idi
  • pfSense’in varsayılan ortamında jail devre dışı olduğundan ezjaili elle kurup mitmproxy için bir jail oluşturdu
    • Jail’i ezjail-admin create mitmproxy 'lo0|127.0.1.1' komutuyla oluşturdu
    • transparent proxy mode için allow.raw_sockets=1 ayarını yaptı
    • Raw socket engellenirse Transparent mode failure veya Cannot open connection, no hostname given. gibi hatalar oluşabileceğini belirtti
  • Linux tarball binary çalıştırma denemesi FreeBSD’de başarısız oldu
    • ELF interpreter /lib64/ld-linux-x86-64.so.2 not found hatası oluştu
    • Ayrıca libdl.so.2, libz.so.1, libpthread.so.0, libc.so.6 dosyaları da bulunamadı
  • Jail içinde pkg install mitmproxy komutunu çalıştırdı; kurulum 50 paket, 206MiB ek alan ve 33MiB indirme gerektiriyordu
  • MITMProxy’ye LAN üzerinden erişilebilmesi için 127.0.1.1 sanal IP’sini localhost’a ekleyip NAT kuralıyla [Private IPs]:8080 adresini geçici olarak 127.0.1.1:8080 adresine yönlendirdi
  • MITMProxy’nin otomatik oluşturduğu CA PEM dosyası ~/.mitmproxy/mitmproxy-ca-cert.pem idi; bu CA cert’i test cihazının Trusted Root Store’una kurdu
  • mitmproxy, boşta bile yüksek CPU kullanıyordu ve istek başına TLS certificate’ın gerçek zamanlı üretilmesiyle aşırı logging’in hızı ciddi biçimde düşürdüğünü düşündü
    • mitmdump arayüzü ve aşırı logging’i atladığı için CPU yükünün daha düşük olduğunu düşündü

Web YouTube JSON reklamlarını kaldırma

  • Certificate Pinning, server veya client’ın beklenen certificate fingerprint’ini önceden bildiği ve bu yüzden MITMProxy’nin certificate sahteciliğinin işe yaramadığı bir tekniktir
  • Sorunlu host’lar --ignore-hosts seçeneğiyle proxy’yi baypas edecek şekilde ayarlanabiliyordu
    • Örnek olarak apple.com:443, icloud.com:443 ignore edildi
  • YouTube erişimi sırasında sayfa reklamları, şifrelenmemiş header’larla birlikte MITMProxy’de görünüyordu; basit regex engellemesi olasılığını değerlendirdi
  • YouTube reklam engelleme script’ini uygulamak için mitmdump komutuna --scripts "youtube.py" ekledi
  • Smoke-test filtresi, URL substring’ine göre reklam isteklerini engelliyordu
    • youtube.com: /pagead/, /log_event?, /stats/ads, /stats/qoe?, /ptracking?, /generate_204, el=adunit, adformat=, /activeview?
    • google.com, google.ca: /pagead/
    • ggpht.com: .
  • Engellenmesi amaçlanan istekler MITMProxy ve DevTools Network panelinde gerçekten engellenmiş görünüyordu, ancak reklamlar hâlâ çıkıyordu; bazen de reklamlar kendiliğinden atlanıyor veya oynatma başarısız oluyordu
  • Sonrasında JSON payload içinde reklamlarla ilgili çok sayıda URL buldu
  • YouTube arayüzünü ve HTTP iş akışını cookies ve service workers dahil analiz ettikten sonra, pre-roll, post-roll ve video ortası reklamların tümünü kaldırabildiğini belirtti
  • Bu aşamada router ile YouTube web ads’in JSON payload içinden reklamları kaldırabiliyordu

iOS YouTube ve Protobuf sorunu

  • YouTube iOS uygulaması, web sürümüyle aynı API çağrısının Protobuf sürümünde çok benzer veriler gösteriyor
  • Protobuf’ta anahtarlar sayılardan oluşuyor ve değişebiliyor; bu yüzden reklam bölümünü bulmak için JSONPath benzeri bir yaklaşım kullanılamıyor
  • YouTube, ileride gösterilecek reklamların büyük bir listesini payload olarak gönderiyor; bu liste tükenince kısa süre sonra başka bir büyük liste daha geliyor
  • Protobuf payload’unda “Telus”, “Samsung TV”, “Boxing Week”, “Buy now” gibi dizeler görünüyordu
  • iOS YouTube protokolü web trafiğinden farklıydı
    • web sürümünde URL’ye ve range query parametresine bakarak reklam videosu ile istenen videoyu bir ölçüde ayırt etmek mümkündü
    • iOS protokolü ne range query parametresini ne de Range header’ını kullanıyor; bunun yerine video chunk’larında &nr=2, &nr=3 gibi sayaçlar kullanıyor
    • iOS’ta reklam engelleme için Protobuf yanıtının reverse-engineer edilmesi gerekiyordu
  • Decode edilmiş Protobuf mesajında has_unlimited_entitlement: False, has_premium_lite_entitlement: False alanları bulundu, ancak bunları toggle etmek yerine yeniden heuristics yaklaşımına dönüldü
  • Yaklaşık 500KiB boyutundaki ham Protobuf’u Python’ın pure implementation’ıyla decode etmek çok yavaştı
    • i7-6700 masaüstü sistemde Python sonucu yaklaşık 2.06~2.11 saniyeydi
    • pfSense router’da Python sonucu yaklaşık 22.8~24.2 saniyeydi
    • C++ protoc --decode_raw, masaüstünde yaklaşık 0.017~0.022 saniye, pfSense router’da ise yaklaşık 0.12~0.14 saniyeydi

Protobuf decode etme ve şema çıkarma denemeleri

  • Python’da ham Protobuf decode desteği olmadığından, doğrudan C++ libprotobuf.so kullanmak yerine subprocess.Popen ile C++ protoc binary’siyle iletişim kurma yöntemi seçildi
  • Reklam videosu yanıtları fuzzing ile test edilerek boş 200, 404, 503, kesik response body ve reklam videosunun bir kısmını null yapma gibi denemeler yapıldı; ancak iOS uygulaması yavaşladıktan sonra crash ediyor veya reklam ekranında takılı kalıyordu
  • URL engelleme, uygulamanın karşı hamle üretmesine yol açtı ve video yanıt chunk’larının içinde session metadata da bulunuyordu
  • Burp Suite için blackboxprotobuf, ham Protobuf wire message’ını decode etmeye, içeriği enjekte ettikten sonra yeniden encode etmeye ve böylece Protobuf endpoint davranışını doğrulamaya imkân veriyordu
    • PyPI fork’u değil, özgün Burp Suite sürümünün kullanılması öneriliyor
    • bazı fork’larda deep recursion nedeniyle stack overflow veya infinite recursion sorunları bulunuyor
    • C++ bindings kullanıldığında yaklaşık 500KiB ham Protobuf birkaç saniye içinde transcode edilebiliyor
  • Üretilen şema kusursuz değildi; büyük, derin iç içe geçmiş bir yapıdaydı ve pretty-print işlemi yavaştı, ama reklam ayrıntılarını bulmak için yeterliydi
  • Android YouTube APK’sından gerçek .proto veya schema dosyalarını çıkarmak için PBTK, Apktool, dex2jar ve Java Decompiler denendi
    • PBTK’nin çıkardığı tek şey 59-byte’lık bir proto dosyasıydı
    • Java içinde Protobuf class’ları ile getter/setter’lar vardı, ancak gerçek şema dosyaları elde edilemeyince çalışma bırakıldı

Son dönüm noktası: Protobuf field tag’inde 1 byte değiştirme

  • Şifresi çözülmüş ağ trafiği ve Protobuf fuzzing sonuçlarına göre reklamların, belirli videoların slot’larına kaydedildiği bir yapı gözlemlendi
    • slot türleri arasında pre-roll, mid-roll, end-roll, tam sayfa ve ad pod’ları bulunuyor
    • reklam URL’si engellendiğinde, “var olmayan bir reklam bir slot ayırttı” benzeri bir hata oluşuyor ve UI panic yaşanıyordu
  • Özgün şema olmadan decode, düzenleme ve yeniden encode yapıldığında değiştirilmiş bir encoding ortaya çıkıyor; ZigZag kullanılıp kullanılmadığı, int32, int64, sint32/64, varint gibi sayısal türler ve object field sırasının genelde nondeterministic olması nedeniyle bunun sorun yarattığı düşünüldü
  • Protobuf’un backward compatibility özelliği ve UnknownFieldSet davranışında bir dolanma yolu bulundu
    • yeni bir field eklenmiş message’ı eski yazılım okuduğunda unknown field oluşabiliyor
    • belirli bir field key başka bir değere çevrilirse reklam ve tracking bilgisini taşıyan alt yapının tamamı unavailable hâle gelebilir
  • Örnek olarak, field key 49399797 değerini 49399796 yaparak ilgili reklam/tracking alt yapısını unknown field gibi göstermeye yönelik bir fikir sunuldu
  • field key 49399797 basit bir hex aramasıyla bulunamıyor; varint/tag encoding dikkate alınmak zorunda
    • wire type 2; yani length-delimited nested string/message anlamına geliyor
    • hedef field key 49399797 için tag byte dizisi AA FF B8 BC 01 oluyor
    • wire type’a ait 3 biti kaldırmak için 395198378 >> 3 yapıldığında özgün field key 49399797 elde ediliyor
  • Protobuf byte’ları içinde /pagead/ gibi klasik reklam URL imzaları aranarak field arama aralığı daraltıldı; ardından ilgili konumdan geriye gidilerek değiştirilecek field tag’i ve field key bulundu
  • Örnek intercept log’unda youtubei.googleapis.com:443/youtubei/v1/browse?key=... POST isteğinin 1.87MiB boyutundaki application/x-protobuf yanıtında key 49399797 pozisyon 4465’te, key 50195462 ise pozisyon 4477’de bulundu
  • O(n) smoke test’te 1.8MiB Protobuf verisi ek bellek kullanılmadan tek geçişte tarandı
    • hedef, 1.8MiB içindeki 30,593. byte’ta bulundu
    • yaklaşık 600 byte geri izleme ile denatüre edilecek field key tespit edildi
  • Bu yöntem çalışınca artık *.googleadservices.com veya /pagead/ içeren URL’leri engellemek gerekmiyordu; bu istekler en baştan hiç oluşmaz hâle geldi

MITMProxy add-on script yapısı

  • MITMProxy add-on script’i, ağa bağlı Apple cihazlarında YouTube reklamlarını engelleyen bir proof of concept olarak sunuluyor
    • Dosya adı youtube.py
    • Çalıştırma örneği: mitmdump --listen-port 8080 --listen-host 127.0.0.1 -s "youtube.py"
    • FreeBSD önkoşulları: pkg install protobuf, pkg install py38-pip, pip install jsonpath-ng
  • Script içinde, içerik üreticilerini desteklemek için reklamların %5’ine izin veren bir fairness function bulunuyor
    • in_allowed_ads_window() mevcut zaman her saatin 0. dakikası ile 2. dakikası arasındaysa reklam engellemeyi atlıyor
  • YouTubeAdBlocker, YouTube ile ilgili domain’leri intercept edip JSON veya Protobuf response’larını değiştirerek reklam bilgilerini kaldırıyor
    • Intercept hedefi host regex’i: \.youtube\.com|google\.(com|ca)|googleapis\.com|googleadservices\.com|googlevideo\.com
    • Protobuf reklam tespiti için kullanılan dize: b"/pagead/"
    • Arama sınırı: 80_000 bayt
    • Hedef field tag’i: 50195462
  • İstek aşaması engelleme listesinde YouTube host’larındaki pagead/, log_event?, stats/ads, stats/qoe?, ptracking?, generate_204, error_204, adformat=, activeview?, _ad_, ai?, sw.js ve benzerleri yer alıyor
  • Web YouTube için JSON replacement, reklamla ilgili field’ları kaldırıyor veya devre dışı bırakıyor
    • yt_ad, "0" olarak değiştiriliyor
    • adPlacements, [] olarak değiştiriliyor
    • adPlacementRenderer, adPlacementConfig, playerAdParams, gutParams, {} olarak değiştiriliyor
    • adVideoId, "" olarak değiştiriliyor
    • showCompanion, showInstream, useGut, False olarak değiştiriliyor
  • load() hook’u HTTP/2’yi devre dışı bırakıyor ve anticomp=True, mode="transparent" ayarlarını yapıyor
  • running() hook’u, intercept’in yalnızca YouTube ile ilgili domain’lere uygulanması için allow_hosts değerini güncelliyor
  • response() hook’u, content-type içinde protobuf varsa yanıt gövdesinin ilk 80.000 baytı içinde /pagead/ arıyor
    • Bulursa TagBytes(self.target_field_tag, WIRETYPE_LENGTH_DELIMITED) ile hedef tag byte’larını oluşturuyor
    • target_field_tag - 1 için tag byte’larını yeni byte’lar olarak oluşturuyor
    • /pagead/ konumunun öncesinde reverse search yaparak hedef tag’i buluyor
    • İlgili konumdaki byte’ları target_field_tag - 1e karşılık gelen byte’larla değiştiriyor
    • Değiştirilen Protobuf içeriğini flow.response.set_content(bytes(body)) ile geri yazıyor
  • Kod yorumları, bu PoC’nin zaten reklamların %90’ını engellediğini söylüyor; ayrıca başka bölümlerde de başka field key’lerin bulunduğunu ve etkisiz hale getirilmesi gereken birden fazla reklam bölümü olabileceğini ekliyor

Performans, sınırlamalar ve hedef kullanıcı

  • Nihai teknik, Protobuf’un schema change’lerde backward-compatible kalmak için unknown field’lara izin vermesi özelliğinden ve compact formatın tek baytlık düzenleme hassasiyetinden yararlanıyor
  • Kritik noktadaki 1 baytı değiştirip derin iç içe geçmiş bir bölümü gelecekteki bir schema version’a aitmiş gibi göstermek, Protobuf’un bunu ignore etmesini ve reklam bilgisinin kaldırılmasını sağlayabiliyor
  • Google, iOS uygulama düzenini de içeren büyük bir Protobuf response döndürüyor; örnek payload 1.8MiB
  • Tüm payload’u parse etmek için C++/Swift gibi native code gerekiyor; Python ile decode işleminin birkaç basamak daha yavaş olduğu ve connection timeout’a yol açtığı belirtiliyor
  • Web tabanlı JSON’da tüm payload’un parse edilmesi, düzenlenmesi ve yeniden serialize edilmesi gerekirken, Protobuf tekniği yalnızca linear scan ve hızlı bir backtrack yaptığı için microseconds düzeyinde işleniyor; bu da onu real-time adblocking için uygun hale getiriyor ve blocklist gerektirmiyor
  • Apple cihazlarındaki tüm *.googleadservices.com ve /pagead/* URL’leri Protobuf payload’dan geliyor; payload içindeki reklam verisi kaybolunca bu request’ler de otomatik olarak kayboluyor
  • YouTube uygulaması ad URL’lerini fetch etmeye çalışmadığı için daha hızlı hissediliyor ve reklamlar video slot’una kaydedilmediğinden içerik hemen oynatılıyor
  • Bu yaklaşım, Apple cihazlarındaki YouTube reklamlarını veya Instagram, WhatsApp, Facebook tracker trafiğini engellemek için geliştirilmiş son derece özelleşmiş bir teknik olarak sunuluyor
  • HTTPS trafiğini decrypt/re-encrypt etmenin CPU gereksiniminin Raspberry Pi performansını açık ara aştığı belirtiliyor
  • Apple cihaz sahibinin OS’yi compromise etmek istemediği varsayıldığından, hedef kullanıcı kitlesinin daha da dar olduğu düşünülüyor

YouTube Premium ve reklam maliyeti deneyi

  • YouTube Premium fiyatı CAD $9.99/ay veya CAD $11.99/ay olup vergi dahil yaklaşık CAD $13.43/ay olduğunda bunun makul olup olmadığı konusunda emin olunmadığı belirtiliyor
  • Temiz bir dizüstü bilgisayar ve private browsing ile, bir gün boyunca aralıklı YouTube izleme üzerinden reklam gösterimi deneyi yapılıyor
    • İzleme geçmişinde “izlendi” olarak görünen video sayısı yalnızca 10’du
    • Bu 10 videonun bazı kısımları izlenirken 8 reklama maruz kalındı
    • Atlanabilir reklam sadece 2 taneydi ve ikisi de atlandı
  • Yaklaşık CPV’nin USD $0.15 olduğu varsayılırsa, günde 8 reklam 8 x $0.15 = $1.20 reklamveren maliyeti anlamına geliyor; bu da aya vurulduğunda yaklaşık USD $36/ay ediyor
  • Statista verilerine dayanarak, ABD reklam harcamasını toplam izlenme sayısına bölme hesabı da sunuluyor
    • 2019’da ABD’li reklamverenler YouTube’da $15.1 billion harcadı
    • ABD sakinlerinin 916 billion video izlediği belirtiliyor
    • Ortalama $15.1B / 916B = USD $0.0165 per view
    • Yazar, kendi durumu için bunun günde yaklaşık USD $0.13, ayda ise yaklaşık USD $3.96 reklamveren maliyetine denk geldiğini hesaplıyor
  • Reklam deneyi sırasında donanımsal sesi kapattığı ve sık sık gözünü ekrandan ayırdığı için, kendisine gösterilen reklam bütçesinin boşa harcandığını düşünüyor
  • Buna rağmen üreticileri desteklemek istediğini ve Google’ın kendisi hakkında neyi takip ettiğini izlemeyi sürdürürken 3 aylık Premium denemesini kullanacağını söylüyor
  • Bir DMCA claim gelir gelmez tüm reklam gelirinin üreticiye değil claimant’e gidebileceğinden endişe ettiğini, bu yüzden birçok üreticinin Patreon’a yönelmesinin şaşırtıcı olmadığını ekliyor

Son özet

  • Donanım yönlendiricisi baştan yapılandırılıyor ve LAN trusted/untrusted zone’lara ayrılıyor
  • Geleneksel DNS reklam engelleme kuruluyor
  • Transparent MITM proxy ekleniyor
  • Sonuç olarak, ağa bağlı Apple cihazlarında YouTube reklamlarının yüksek performansla engellenebildiği belirtiliyor
  • Zor kısmın bittiği söylenerek YouTube Premium ödemesinin değerlendirilebileceği yazılıyor, ancak tracker’ların hâlâ güçlü şekilde engellendiği de ekleniyor

1 yorum

 
GN⁺ 2025-03-19
Hacker News yorumları
  • Bu, Protobuf biçimindeki bir kusurdan çok, yazarın alan numarasını büyük ve kullanılmayan bir numarayla değiştirmiş gibi görünüyor.
    Yöntem, Protobuf baytları içinde /pagead/ gibi reklam URL imzalarını bulup alan aralığını belirlemek, ardından geriye giderek hedef alan etiketini ve alan anahtarını bulup etkisizleştirmek; bu bir kusurdan ziyade tasarlanmış davranışa daha yakın.
    Etiketi bulacak kadar uğraşılacaksa hemen yanındaki varint uzunluğunu okuyup ilgili baytları atlamak da çok büyük bir ek iş değil. Arabelleği kopyalamak ya da baytları kaydırmak gerekebilir; ancak PoC betiği de mitmproxy API’sinin döndürdüğü bytes değişmez olduğu için zaten kopyalama yapmak zorunda.

    • Protokol düzeyinde beklenen şekilde çalışıyor, ancak reklam veri yapısında bilinmeyen bir alan çıktığında Google’ın hata vermeyip bunu reklam yokmuş gibi işlemesi açık gibi görünüyor.
      Google, mevcut uygulama sürümlerinde reklamların tamamen kaybolmasına yol açacak ölçüde protokolü değiştirmeden önce yeni uygulamayı dağıtacaktır; dolayısıyla basit sertifika sabitleme ya da reklam bilgisi çıkarma başarısız olduğunda daha az hoşgörülü decode etme gibi yöntemler bile bu engellemeyi hemen durdurabilir. YouTube ekibi bunu muhtemelen bir kusur olarak görür.
    • bytes nesnesi değişmezdir, ama bytearray nesnesi değişmez değildir.
  • Küçük bir C++/Go proxy ile aynı iş çok daha düşük ek yükle yapılabilir. Bu kadar iyi tanımlanmış bir iş, mitmproxy ile boğuşmaktan daha kararlı ve daha az zahmetli olur.
    Tüm trafiği proxy’ye yönlendirirseniz SNI yakalama kullansanız bile performans düşer. pfSense için de aynısı geçerli; basit bir Linux sunucusu ve sade iptables kurallarıyla, pfSense’in soyutlama katmanlarıyla uğraşmadan bu iş çözülebilir.
    Tersine mühendislikle çıkarılan proto alanlarından yalnızca gerekenleri .proto dosyasına yazıp kodu otomatik ürettikten sonra bayrağı değiştirmek yeterli. Python uygulamasından daha ucuz olur ve proto değişse bile güncellemesi daha kolaydır. Bilinmeyen alan etiketlerini yok saymak Protobuf’un önemli bir özelliğidir ve mevcut dağıtımları bozmadan uyumlu şema değişiklikleri yapılmasını sağlar.

    • YouTube deneyimini kasıtlı olarak yavaşlatmak ve video geçişlerini de ağırlaştırmak daha iyi bile olabilir. Özellikle Shorts bağımlılığını epey azaltacak gibi.
    • Bunu nasıl yapacağını ayrıntılı paylaşan bir blog yazısı beklerim.
    • Verimsizliğin nerede olduğunu ve daha basit yazılımla nasıl hafifletilebileceğini anlatan rehberi sizin yazmanız iyi olur.
      Yazar zaten yorumlardaki noktaların önemli bir kısmının farkındaymış gibi görünüyor ve yazı da oldukça kapsamlı. Python ve C++ ile benchmark yapmış; nihai uygulama Protobuf decode bile etmiyor. Birden fazla mitm çözümünü de denemiş; pfSense’i ise basit bir güvenlik yönlendiricisi olarak değil, VLAN ve VPN ile yalnızca Apple TV trafiğini hedeflemek için kullanıyor.
      Bu yorum fazla kolaycı ve küçümseyici duruyor. Asıl yazı öyle değil; böyle konuşulacaksa topluluk için bunu bizzat kanıtlamak gerekir.
    • macOS’ta çalışıp evdeki diğer cihazlara da hizmet verebilecek hafif bir proxy önerisi olan var mı, merak ediyorum.
  • YouTube Premium’a ödeme yapmak içerik üreticileri desteklemek anlamına geliyor mu? Öyleyse Patreon gibi doğrudan destekle karşılaştırıldığında ne seviyede olduğunu merak ediyorum.

    • Patreon’a kıyasla çok olmayacaktır, ama birden fazla YouTuber izleyen birinden hepsinin Patreon’una abone olması da beklenemez.
      Tek bir YouTube Premium aboneliğinin tekil içerik üreticilerine sağladığı gelir çok küçük olacaktır; yine de reklam engelleyici açıkken video izlemekten daha iyidir.
    • İçerik üreticilerinin YouTube Premium izlenmelerinden, normal reklam izlenen görüntülemelere kıyasla daha büyük pay aldığı biliniyor. Çünkü reklam atlanırsa gelir olmaz. Ancak Premium kullanıcı sayısı az olduğu için hâlâ sınırlı.
    • Güncel bilgi az, ama ilk kez YouTube Red olarak çıktığında izlenme başına reklam gelirinden genellikle çok daha fazlaydı.
    • Reklamdan fazla, Patreon’dan az.
      Reklam gösterimi yerine izlenme süresi baz alındığı için uzun format içerik üreten içerik üreticileri daha avantajlı.
  • Kız arkadaşımın YouTube hesabında garip şekilde, hangi cihazdan giriş yaparsa yapsın reklam çıkmıyor. Apple TV de dahil; Premium değil ve hiç Premium da olmadı.
    İçeride bir bayrak ayarlanıp reklamların kapatılmış olup olmadığını merak ediyorum.

    • Hesap kullanıcı adını ve e-postasını DM’den gönderirsen kontrol edip düzeltebilirim.
    • Kız arkadaşın fiilen reklamların kontrol grubuna alınmış gibi. Reklam gören kullanıcıların davranışlarıyla karşılaştırarak reklamların kullanıcılar üzerinde nasıl etki yarattığını anlamak için kullanılabilir.
    • Bir holdback experiment’a dahil olmuş olabilir. Reklam sunumu gibi bir özelliğin metrikleri nasıl etkilediğini görmek için bazı kullanıcıları bekletme grubunda tutmak sık yapılan bir şey; Google’da çalışırken biz de böyle deneyler yapıyorduk.
    • Eskiden Google Music aboneliği varsa YouTube reklamları kapanıyordu. Hizmet sonlandırıldıktan ya da abonelik iptal edildikten sonra bile 6 aydan uzun süre YouTube reklamları geri gelmedi.
      İnsanların neden şikâyet ettiğini ancak o zaman anladığım bir an yaşamıştım.
    • Twitch’te aynı şeyi yaşıyorum.
      Reklam engelleyici kullanmadığım halde giriş yapınca ne web sitesinde ne de mobil uygulamada reklam çıkıyor. Twitch Turbo’m yok, Amazon Prime’ım da artık yok. Diğer Turbo avantajları da olmadığı için tamamen Turbo olarak işaretlenmiş de değilim.
      Eskiden bug bounty yaparken kurcaladığım şeyler yüzünden hesap profilim tesadüfen bozuldu mu bilmiyorum; ama bu avantajı koruyacaklarsa daha ayrıntılı bilgi de verebilirim.
      Tuhaf olan, eskiden hastanede ilaçların etkisi altındayken ve ağrı içindeyken sadece TV izlemek istemiştim, ama Twitch reklamları o kadar berbattı ki neredeyse sinir krizi geçirecektim; bunu hatırlıyorum. Sonra 1-2 yıl sonra birden, yıllardır reklam görmediğimi fark ettim.
      Muhtemelen uzun süredir unutulmuş reklamsız bir A/B testi var ve temizlemeye değmediği için kalmış. Bu sayede yıllardır faydasını gördüm ve Twitch’i diğer tüm platformlardan daha çok izledim. Birleşik Krallık’ta Twitch Turbo aylık £12, yani yaklaşık $15,50; küresel ölçekte de pahalı sayılır ve ABD ile Avrupa’daki $12/€12 ile kıyaslandığında epey kötü bir fiyat.
  • Apple TV ile dış internet arasına bir ortadaki adam proxy’si koyunca HTTPS trafiğinin çözülebilmesi oldukça şaşırtıcıydı
    Normalde bunun çalışmaması gerektiğini düşünürdüm; sonra Apple TV’nin sertifika deposuna CA eklenebildiğini öğrenince ayrıca şaşırdım. Tüm yığını baştan sona inceleyen ayrıntılı bir yazıydı

    • Apple’ın sertifika eklemeyi desteklemesinin nedenini tahmin edecek olursam, kurumsal ya da eğitim ortamlarında Apple TV’yi bir AirPlay kutusu olarak kullanırken BT ve cihaz yönetimi gereksinimlerine uyum sağlamak için olma ihtimali yüksek
      Örneğin üniversitelerde bir cihazı Wi‑Fi’ye bağlamak için MAC adresini izin listesine almak ya da sertifika yüklemek gerekirdi
    • Google, YouTube uygulamasında SSL sertifikasını imzalayan CA’yı kontrol ederek bu yöntemi kolayca engelleyebilir
      Ancak bunu yaparsa birçok kurumsal ortamda YouTube bozulabilir; gerçekten yapar mı bilmiyorum. Yine de ne yazık ki engellemesi çok kolay
    • Apple TV’ye CA eklenebilmesi beklemediğim bir şeydi. Geçerli bir sertifika zinciri olmayan kaynaklara Apple TV ile hiç erişmeyi denemediğim için bilmiyor olabilirim
    • Çoğu cihaz CA eklenmesine izin verir, ancak günümüzde uygulamaların neredeyse tamamı sertifika sabitleme kullanıp sistem sertifika deposunu yok sayar. YouTube’un bunu yapmaması çok şaşırtıcı
    • İronik biçimde Android TV, en azından 7.x sürümünde, buna izin vermiyor. Güvenilmeyen bir Let’s Encrypt sertifikasını atlatmaya çalışırken bunu zor yoldan öğrendim
  • Apple TV’de birkaç kez uygulamaya çalıştım ama hiç başarılı olamadım. YouTube artık uygulamaya sertifika sabitleme eklemiş falan olabilir. Yakın zamanda bunu çalıştırabilen biri var mı merak ediyorum

    • Zaman ayırmaya niyetliyseniz Frida’yı [0] kurcalayabilirsiniz. Sabitlenmiş sertifika da sorun değil
      [0] https://frida.re/docs/home/
  • Kullanmak zorunda bırakıldığımız berbat çevrimiçi hizmetleri tüm ağ genelinde engellemeye yönelik her türlü girişimi seviyorum
    Reklam engelleme de güzel, ama YouTube Shorts veya Instagram Reels gibi saldırgan sonsuz kaydırmayı ağ genelinde daha kolay ve daha kapsamlı engellemenin yolları olsa keşke
    Instagram’da sadece takip ettiğim kişilerin gönderilerini ve hikâyelerini görmek istiyorum; dikkatimi çalmak üzere tasarlanmış aptal videolar önerilmesin istiyorum. Belki irade eksikliğimi gösteriyor olabilir ama sık sık birkaç tane izlerken buluyorum kendimi ve hayatımdan 15 dakika gidiyor

    • Zorla kullandırılmıyor. Kullanmayabilirsiniz ya da ücret ödeyebilirsiniz
      İnternet kullanıcıları genel olarak ücret ödemek istememe tarafını seçti ve bu yüzden maliyeti birileri üstleniyor. Genel olarak internet kullanıcıları reklam göstermeyen tarafları ödüllendirmiyor. İçerik istiyorlar ama çoğunlukla ücretsiz istiyorlar
    • Uygulamayı silip web sayfasını kullanın; kullanıcı betiklerine izin veren bir tarayıcı kullanın
      Instagram sayfasını neredeyse sadece görsel etiketi gibi davranacak şekilde değiştirip yalnızca fotoğrafları görmeyi sağlayan bir betik buldum: https://greasyfork.org/en/scripts/5014-un-instagram
    • Bu tür taktiklerin doğal merakımızı ve onun etrafındaki estetiği suistimal ettiğini düşünüyorum
      Bu yüzden mesele irade eksikliğinden çok, biriktirdiğimiz duyarsızlaşmaya daha yakın görünüyor ve bu oldukça kötü. Platformların bize kendini kullandırması yerine bizim platformları kullanmamızı geri getirmeye dönük çaba ve yaratıcılık saygı duyulacak şey
    • Bir ebeveyn olarak özellikle katılıyorum. Çocukların algoritmaya kapılıp gitmesini izlemek zor
      Çocuklarla düzenli olarak konuşuyorum; onlar da bunun zararlı olduğuna katılıyor ama direnmekte çok zorlanıyorlar. Ben bile bazen doomscrolling’e çekiliyorum
      Mümkün olan yerlerde Pi-hole ile reklam filtrelemeyi ayarladım ama YouTube’u tamamen engellemek istemiyorum. Yine de ailemi korumak için ileride bunu ciddi biçimde düşünmek zorunda kalabilirim
    • Instagram’ın sonsuz kaydırmasını engellemek için şu uygulama çok iyi uydu: https://www.distractionfreeapps.com/index.html
  • Mühendislik güzel, ama kendi donanımınıza ya da yazılımınıza bir ölçüde sahipmişsiniz gibi kullanabilmek için bu kadar uğraşmak zorunda olmak biraz üzücü

    • Bu durumda cihaza sahipsiniz. Ancak YouTube’a ya da içeriğine de sahip olduğunuzu iddia etmek için bir gerekçe yok gibi görünüyor
    • 30 dolarlık bir Android kutuya NewPipe APK yüklemek, neredeyse 10 yıldır mümkün olan bir şey
  • YouTube’da reklam mı var? Tarayıcım o kadar iyi engelliyor ki bilmiyordum
    Asıl sorun, Apple TV deneyiminin sıradan web tarayıcısı deneyiminden çok daha kötü olması. Apple donanımı o kadar kilitli tutuyor ki, para verip satın alan son tüketiciden çok YouTube’un reklam gelirine fayda sağlayan bir yapıya dönüşüyor

    • Linux, Windows ve Android’de hiç reklam görmüyorum. Arada iPad’de YouTube izlemeye çalışınca reklamların ne kadar sık ve sinir bozucu olduğuna şaşırıyorum
      Evdeki Pi-hole ağının dışındayken iPad ile web’e bakarken de aynı şey geçerli. İnsanların buna her gün nasıl katlandığını bilmiyorum
      iPad iş için verilen bir cihaz olduğu için kişisel amaçla sık kullanmıyorum, ama her kullandığımda ne kadar sinir bozucu olduğunu hatırlatıyor
      Tuhaf biçimde, iPad’i almadan önce yalnızca içerik tüketimi için işe yarar sanıyordum; gerçekte ise iş kaynaklarına hızlıca uzaktan erişmek için çok kullanışlı, normal web gezintisi ve streaming medya tarafında ise reklamlarla kaplı bir çoraklığa hapsolmuş bir cihazmış
  • Reklamsız YouTube gerekiyorsa https://yewtu.be ya da başka bir Invidious instance’ı https://docs.invidious.io/instances/ kullanabilirsiniz
    YouTube ile Invidious arasında bir silahlanma yarışı var ve bazen Invidious çalışmasa da ekip her zaman YouTube’u aşarak videoları reklamsız iletmenin yeni yollarını buldu

    • Başlıkta “on AppleTV” yazmasının bir nedeni var. Alternatif istemciler ya da frontend’ler orada çalışmıyor
    • Roku TV gibi yerlerde tarayıcı olmadığı için bu yöntem işe yaramıyor