1 คะแนน โดย GN⁺ 2025-03-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • นี่คือ PoC ที่วาง พร็อกซี MITM บน pfSense ไว้ระหว่าง Apple TV กับอินเทอร์เน็ต ถอดรหัส HTTPS แล้วแก้ไขการตอบกลับ Protobuf ที่ YouTube ส่งมา เพื่อไม่ให้มีการลงทะเบียนช่องโฆษณาบนอุปกรณ์ Apple
  • ตัว ตัวบล็อก DNS และการทำ VPN routing แบบเดิมติดข้อจำกัด เช่น DNS TTL, IP ไม่ตรงกัน, ข้อผิดพลาด 403 และ ASN leak เพราะโฆษณา YouTube กับวิดีโอหลักใช้โดเมนและโครงสร้างพื้นฐานเดียวกัน
  • การทดลองกับ Squid ถูกยุติลงเพราะปัญหาด้านประสิทธิภาพและการตั้งค่า จากนั้นจึงเปลี่ยนไปใช้ mitmproxy/mitmdump บน FreeBSD jail เพื่อถอดรหัสทราฟฟิก TLS และแก้ไขการตอบกลับ JSON·Protobuf โดยตรง
  • YouTube บนเว็บสามารถลบ adPlacements, playerAdParams, URL pagead เป็นต้น ออกจาก JSON ได้ แต่แอป YouTube บน iOS เก็บช่องโฆษณาและข้อมูลติดตามไว้ใน response แบบ application/x-protobuf จึงต้องจัดการกับ โครงสร้าง Protobuf
  • วิธีสุดท้ายคือ การสแกนเชิงเส้นและแก้ไข 1 ไบต์ โดยไล่ย้อนหา field tag ใกล้สตริง /pagead/ แล้วเปลี่ยนแท็กอย่าง 50195462 เป็น target_field_tag - 1 ซึ่งให้ประสิทธิภาพเหมาะกับการประมวลผลแบบเรียลไทม์โดยไม่ต้องถอดรหัสทั้งหมด

เป้าหมายและการออกแบบเครือข่ายระยะแรก

  • เป้าหมายคือสร้างเราเตอร์บน FreeBSD และ pfSense เพื่อบล็อกโฆษณา YouTube แบบ pre-roll, mid-roll และ end-roll ของ Apple TV และ iPhone ทั้งเครือข่าย
  • หากวาง พร็อกซีแบบ man-in-the-middle ไว้ระหว่าง Apple TV กับอินเทอร์เน็ตภายนอก ก็จะสามารถถอดรหัสทราฟฟิก HTTPS และอ่านข้อมูล Protocol Buffer ที่ Google ใช้เติมโฆษณา YouTube ได้
  • หลังจากทำระบบบล็อกโฆษณา YouTube อยู่หลายเดือน ผู้เขียนก็เริ่มจ่าย YouTube Premium และบอกว่า “ทำได้” กับ “ควรทำ” เป็นคนละเรื่องกัน
  • เหตุผลที่บล็อกโฆษณาและตัวติดตามคือการติดตามข้อมูลส่วนตัว การเปลืองแบนด์วิดท์ clickbait และ cryptojacking
    • มองว่าทราฟฟิกเครือข่าย 25~40% อาจเป็นโฆษณา สคริปต์ติดตาม ตัวโหลดวิเคราะห์แบบเรียลไทม์อย่าง fingerprint.js, googletagmanager.js และ Hotjar
    • อธิบายว่า JavaScript ขุดคริปโตอย่าง CoinHive.js อาจทำให้คอมพิวเตอร์ร้อนเกินไปหรือถูกนำไปใช้หารายได้เล็กน้อยโดยมิชอบ

ฮาร์ดแวร์ pfSense และการตั้งค่าพื้นฐาน

  • มองว่าหากต้องการปกป้องเครือข่าย SMB ทั้งหมด VM, Docker image และ Raspberry Pi มีประสิทธิภาพไม่พอ จึงต้องใช้ ฮาร์ดแวร์เฉพาะทาง ที่รับหน้าที่แค่ routing, ถอดรหัส และ monitoring แพ็กเก็ต
  • ฮาร์ดแวร์เราเตอร์ที่ใช้คือ mini PC ที่มีชุดคำสั่ง AES-NI, RAM DDR4, SSD แบบ mSATA และ USB drive สำหรับแฟลช pfSense
    • ตัวอย่างสเปกคือ mini PC J4125, RAM DDR4 32GiB และ SSD mSATA 128GiB
    • มองว่าพื้นที่เก็บข้อมูล 128GB เพียงพอสำหรับ log, ลด SSD wear, packet capture และ edge cache ของ NPM·Docker
  • อิมเมจติดตั้ง pfSense มีขนาดราว 360MB และสามารถแฟลชลง USB drive ได้ด้วย Etcher AppImage
  • หลังตั้งค่าครั้งแรก AES-NI แสดงเป็น “Yes (inactive)” จึงเปิดใช้งานเองที่ System › Advanced › Miscellaneous
  • เพื่อใช้ประโยชน์จาก RAM 32GiB จึงจัดสรร RAM disk ให้ /var และ /tmp อย่างเพียงพอ และตั้งให้ SSD 128GiB สำรองข้อมูล RAM-disk ทุกชั่วโมงโดยคาดหวังการทำ wear-leveling
  • ใน Dashboard มีการเพิ่ม วิดเจ็ต S.M.A.R.T. เพื่อให้ตรวจจับความผิดปกติของ SSD ได้

การบล็อก DNS, การแยกเครือข่าย และ pfBlockerNG

  • เดิมใช้ Pi-hole บน Raspberry Pi เป็นตัวบล็อกโฆษณาระดับ DNS และบน pfSense ได้ติดตั้ง pfBlockerNG-devel เพื่อทดลองบล็อกโฆษณา·เนื้อหาอันตรายและ geo-blocking
  • หากบริการ pfb_dnsbl ไม่เริ่มทำงานหรือแท็บ status แสดง [ Missing CRON task ] ก็แนะนำให้ลองลบไฟล์ว่าง /var/run/booting
  • ใช้พอร์ต Gigabit 3 พอร์ตของ mini PC สร้างเครือข่ายจริงแทน VLAN และแยกอุปกรณ์ที่ “โทรกลับบ้าน” อย่าง Alexa และ Apple TV ออกจากเครือข่ายหลัก
    • อุปกรณ์ untrusted ถูกวางไว้ในเครือข่าย private 172.31.1.0/24
    • trusted LAN ยังคงใช้ 192.168/16
    • ฮาร์ดแวร์ LAN สำหรับ IoT จะผ่าน adblocker และพยายามดักจับคำขอ DNS แบบ hard-coded เช่น 1.1.1.1·9.9.9.9 เพื่อไม่ให้ YouTube เลี่ยงตัวบล็อก DNS ได้
  • มีการตั้งกฎ NAT ให้ไคลเอนต์ทั้งหมดหลัง pfSense ใช้ Unbound DNS ภายในเครื่อง
    • มองว่าต้องบล็อก DNS over TLS ก่อน จึงจะดักจับ DNS query ได้
    • iPhone อาจแสดง Privacy Warning เกี่ยวกับการบล็อกทราฟฟิก DNS ที่เข้ารหัส แต่คำขอ DNS ไปยัง upstream จะยังเข้ารหัสไปที่ Cloudflare
    • ควรปิด NAT reflection เพื่อไม่ให้อินเทอร์เน็ตภายนอกเข้าถึงเซิร์ฟเวอร์ DNS ได้
  • สร้าง firewall alias ชื่อ Non_WAN เพื่อ redirect พอร์ต 53 ของ local DNS query จากทุกอินเทอร์เฟซที่ไม่ใช่ WAN ไปยัง localhost
  • เนื่องจาก YouTube ส่งทั้งโฆษณาและวิดีโอหลักจากโดเมนเดียวกัน จึงกรองเฉพาะโฆษณาด้วย ตัวบล็อกชื่อโดเมน อย่าง pfBlockerNG หรือ Pi-hole ได้ยาก

การทดลองเลี่ยงผ่าน VPN และจุดที่ล้มเหลว

  • นอกจากการบล็อกโฆษณา ยังมีการทดลองหลอกอัลกอริทึมโฆษณา YouTube ให้มองว่าผู้ใช้มีความน่าสนใจต่อผู้ลงโฆษณาน้อยลง
    • ตั้งใจใช้เราเตอร์ pfSense route ทราฟฟิกติดตามตำแหน่งของ YouTube ผ่าน VPN ไปยังภูมิภาคที่มีผู้ชมน้อย
    • ตั้งเป้าให้บัญชี YouTube ถูกมองว่าเป็น “ผู้ชายอายุ 70 ปี อาศัยอยู่ในอิตาลี”
  • บน pfSense ใช้ WireGuard แทน OpenVPN เพื่อทำการทดลองพื้นฐานในการส่งทราฟฟิกทั้งหมดของ Apple TV ผ่าน VPN
    • ติดตั้งแพ็กเกจ WireGuard ของ FreeBSD แล้วเพิ่มและเปิดใช้งาน tunnel
    • สำหรับการตั้งค่า NordLynx ได้ตรวจสอบ private key บน Linux VM ด้วย sudo wg showconf nordlynx แล้วนำไปใส่ใน pfSense
  • ผลทดสอบพบว่า Google บนโน้ตบุ๊กแสดงเป็นภาษาอิตาลี และ YouTube บน Apple TV ก็เปลี่ยนเป็นภาษาอิตาลีเช่นกัน
    • โฆษณายังมีอยู่บ้าง แต่บอกว่าลดลงจากเดิม
    • Netflix และ Amazon Prime มีปัญหา และดูเหมือนว่าไฟล์ CSS หรือฟอนต์ถูกบล็อก หรือ thumbnail โหลดไม่ขึ้น
    • มีคำเตือนว่าอย่าส่งทราฟฟิกทั้งหมดของ Apple TV ผ่าน VPN เพราะ Netflix และ Prime ตรวจจับ VPN provider และ geofencing ได้เก่ง
  • หลังจากนั้นจึงตั้ง firewall policy rule เพื่อให้ เฉพาะทราฟฟิก YouTube ของ Apple TV วิ่งผ่าน VPN โดยกำหนดเป้าหมายเช่น www.youtube.com, youtube.com, googlevideo.com, accounts.google.com, googleapis.com, gstatic.com
    • ผลคือ YouTube มองว่าผู้ใช้อยู่ที่ Milan ขณะที่ Netflix และ Prime Video มองว่าอยู่ที่ Canada
    • โฆษณาลดลงจนอยู่ในระดับที่ “น้อยมากและห่างกันมาก”
  • หนึ่งวันต่อมาเกิด DNS race condition
    • hostname alias ของ pfSense จะ resolve ทุก 300 วินาทีตามค่าเริ่มต้น
    • DNS TTL ของ YouTube อาจเป็น 1,440 วินาที หรือ 24 นาที
    • หาก IP ที่ Alias Daemon resolve ได้ไม่ตรงกับ IP ที่ไคลเอนต์จริงได้รับ policy ก็อาจไม่สามารถ tunnel ทราฟฟิก YouTube ได้
  • วิดีโอ YouTube บางรายการเล่นไม่ได้และขึ้น 403 Forbidden
    • มีคำอธิบายว่า YouTube ฝัง IP ของผู้ใช้ไว้ในแต่ละคำขอ googlevideo.com
    • หากโดเมนที่แปลงรูปอย่าง r5---sn-hpa7kn76.googlevideo.com ไม่ถูก tunnel คำขอก็จะออกจาก IP ที่ผิดและทำให้เกิดปัญหา
    • สิ่งที่ต้องการคือการ tunnel แบบ wildcard สำหรับ *.googlevideo.com แต่ NAT และ firewall rule ทำงานกับ IP ไม่ใช่ wildcard hostname

PoC ติดตาม IP โดยอิงจาก DNS query

  • ได้วางแนวทาง Google Video DNS query hijack เพื่อทำการ route *.googlevideo.com ผ่าน VPN
    • เป็นวิธีที่คอยติดตาม DNS query log เป็นระยะ แล้วเพิ่ม query ของ *.googlevideo.com เข้าไปในรายการ alias
    • มองว่าหากวิดีโอแต่ละรายการใช้โดเมนที่ไม่ซ้ำและถูกดัดแปลง วิธีนี้จะไม่ทำงาน เว้นแต่จะรีเฟรชใหม่ทุกครั้งต่อวิดีโอ
  • เป้าหมายใหม่คือใช้ Python 3 และ pfSense REST API เพื่อตรวจจับ DNS query, จับ IP, หน่วงการตอบกลับไว้ชั่วคราว, เพิ่ม IP เข้าไปในกฎ VPN tunneling แล้วค่อยปล่อย DNS reply
  • ติดตั้ง pfSense REST API แล้วส่งคำขอ GET ไปที่ https://pfsense/api/v1/firewall/alias เพื่อดู alias VPN_domains
  • ได้สำรวจ Python module ของ Unbound DNS Resolver และล็อกข้อความ DNS-query ได้สำเร็จ
    • เวอร์ชัน Python ตอนนั้นคือ 3.8
    • ตัวอย่าง Unbound Python module อิงกับ Python 2.4 จึงมองว่าอาจต้องใช้ 2to3 หรือจัดฟอร์แมตเพิ่มเติม
  • สคริปต์ PoC จะดึง IP ของ A/AAAA record จาก DNS response แล้วเพิ่มเข้าไปใน pfSense alias
    • A record ประมวลผลด้วย ipaddress.IPv4Address(d.rr_data[j][2:]).exploded
    • AAAA record ประมวลผลด้วย ipaddress.IPv6Address(d.rr_data[j][2:]).exploded
    • ตั้งค่า alias TTL เป็น 1 ชั่วโมง และ capacity เป็น 500
  • วันถัดมา Unbound DNS Resolver เกิด segfault และทุกครั้งที่เพิ่ม IP ก็ต้อง reload กฎ pfSense ทำให้ pfSense ช้ามาก

เปลี่ยนจาก Squid ไปเป็น mitmproxy

  • เป้าหมายใหม่เปลี่ยนไปเป็นการสำรวจและติดตั้ง proxy ตระกูล Squid, สร้าง CA certificate ปลอมที่เชื่อถือได้ แล้วถอดรหัส TLS traffic
  • ในการทดลองกับ Squid ได้ทดสอบว่า squid3 proxy ที่มากับแพ็กเกจ pfSense ตอบโจทย์หรือไม่
    • สร้างโฟลเดอร์เฉพาะ /squid_cache และตั้งขนาด cache เป็น 8GiB
    • คาดหวังการรองรับ Transparent HTTPS
  • หลังตั้งค่า Squid และ SquidGuard อยู่หนึ่งวันก็ล้มเลิก
    • ความเร็วช้ามาก
    • การตั้งค่า ACL ยุ่งยาก
    • มีปัญหาที่เกี่ยวกับ https://http/*
    • การอัปเดตรายการกรอง URL ของ SquidGuard ใช้เวลานานมาก
    • UI ของ Squid ยังไม่เพียงพอ
  • หลังจากนั้นจึงตัดสินใจใช้ mitmproxy ที่เขียนด้วย Python
    • เลือก mitmproxy แทน SSLSplit เพราะความยืดหยุ่นของ Python hook และ UI
    • เวอร์ชัน FreeBSD ของ pfSense คือ 12.2-Stable, 64-bit build
  • ในสภาพแวดล้อมปกติของ pfSense นั้น jail ถูกปิดไว้ จึงติดตั้ง ezjail แบบแมนนวลและสร้าง jail สำหรับ mitmproxy
    • สร้าง jail ด้วย ezjail-admin create mitmproxy 'lo0|127.0.1.1'
    • ตั้งค่า allow.raw_sockets=1 สำหรับ transparent proxy mode
    • ระบุว่าหาก raw socket ถูกบล็อก อาจเกิดข้อผิดพลาดอย่าง Transparent mode failure หรือ Cannot open connection, no hostname given.
  • การรัน Linux tarball binary ล้มเหลวบน FreeBSD
    • เกิดข้อผิดพลาด ELF interpreter /lib64/ld-linux-x86-64.so.2 not found
    • และยังหา libdl.so.2, libz.so.1, libpthread.so.0, libc.so.6 ไม่พบด้วย
  • ภายใน jail ได้รัน pkg install mitmproxy โดยการติดตั้งต้องใช้ 50 แพ็กเกจ, พื้นที่เพิ่ม 206MiB และดาวน์โหลด 33MiB
  • เพื่อให้เข้าถึง MITMProxy ได้จาก LAN จึงผูก virtual IP 127.0.1.1 เข้ากับ localhost และตั้ง NAT rule ให้ forward [Private IPs]:8080 ไปที่ 127.0.1.1:8080 ชั่วคราว
  • ไฟล์ CA PEM ที่ MITMProxy สร้างอัตโนมัติคือ ~/.mitmproxy/mitmproxy-ca-cert.pem และได้นำ CA cert นี้ไปติดตั้งใน Trusted Root Store ของอุปกรณ์ทดสอบ
  • mitmproxy ใช้ CPU สูงแม้อยู่ในสถานะ idle และมองว่าการสร้าง TLS certificate แบบเรียลไทม์ต่อคำขอ รวมถึง logging ที่มากเกินไป ทำให้ช้าลงอย่างมาก
    • มองว่า mitmdump ใช้ CPU น้อยกว่า เพราะตัด UI และ logging ที่มากเกินไปออก

ลบโฆษณา YouTube JSON บนเว็บ

  • Certificate Pinning คือเทคนิคที่ server หรือ client รู้ fingerprint ของ certificate ที่คาดไว้ล่วงหน้า ทำให้การปลอม certificate ของ MITMProxy ใช้ไม่ได้
  • โฮสต์ที่มีปัญหาสามารถให้ข้าม proxy ได้ด้วยตัวเลือก --ignore-hosts
    • ตัวอย่างเช่น ignore apple.com:443, icloud.com:443
  • ระหว่างเข้า YouTube พบว่า page ads แสดงให้เห็นใน MITMProxy พร้อม header ที่ไม่ได้เข้ารหัส และได้พิจารณาความเป็นไปได้ในการบล็อกด้วย regex แบบง่าย
  • เพื่อใช้สคริปต์บล็อกโฆษณา YouTube ได้เพิ่ม --scripts "youtube.py" ให้กับ mitmdump
  • smoke-test filter จะบล็อกคำขอโฆษณาตาม substring ของ URL
    • youtube.com: /pagead/, /log_event?, /stats/ads, /stats/qoe?, /ptracking?, /generate_204, el=adunit, adformat=, /activeview?
    • google.com, google.ca: /pagead/
    • ggpht.com: .
  • คำขอที่ต้องการบล็อกดูเหมือนจะถูกบล็อกจริงทั้งใน MITMProxy และแผง DevTools Network แต่โฆษณายังคงแสดงอยู่ และบางครั้งโฆษณาก็ถูกข้ามเองหรือเล่นไม่สำเร็จ
  • หลังจากนั้นพบ URL ที่เกี่ยวข้องกับโฆษณาจำนวนมากภายใน JSON payload
  • หลังวิเคราะห์ YouTube UI และ HTTP workflow รวมถึง cookies และ service workers แล้ว ระบุว่าสามารถลบโฆษณา pre-roll, post-roll และ mid-video ได้ทั้งหมด
  • ในขั้นตอนนี้ สามารถลบโฆษณาออกจาก JSON payload ของโฆษณา YouTube บนเว็บ ได้ที่เราเตอร์

ปัญหา Protobuf ของ YouTube บน iOS

  • แอป YouTube บน iOS แสดงข้อมูลที่คล้ายกันมากจาก Protobuf version ของ API call เดียวกับเวอร์ชันเว็บ
  • ใน Protobuf คีย์เป็นตัวเลขและอาจเปลี่ยนได้ จึงใช้วิธีหา section โฆษณาด้วย JSONPath ไม่ได้
  • YouTube จะส่งรายการโฆษณาจำนวนมากล่วงหน้าที่จะได้เห็นมาใน payload และเมื่อใช้รายการนั้นหมด รายการใหญ่อีกรายการก็จะถูกส่งตามมาในไม่ช้า
  • ใน Protobuf payload พบสตริงอย่าง “Telus,” “Samsung TV,” “Boxing Week,” “Buy now”
  • โปรโตคอล YouTube บน iOS แตกต่างจาก web traffic
    • ในเวอร์ชันเว็บ ยังพอแยกวิดีโอโฆษณากับวิดีโอที่ต้องการได้ระดับหนึ่งจาก URL และ query parameter range
    • โปรโตคอลบน iOS ไม่ใช้ทั้ง query parameter range และ header Range แต่ใช้ตัวนับอย่าง &nr=2, &nr=3 กับ video chunk แทน
    • เพื่อบล็อกโฆษณาบน iOS จึงต้อง reverse-engineer Protobuf response
  • ใน decoded Protobuf message พบรายการ has_unlimited_entitlement: False, has_premium_lite_entitlement: False แต่แทนที่จะ toggle ค่านี้ ก็กลับไปใช้ heuristics
  • การ decode Protobuf ดิบขนาดราว 500KiB ด้วย Python pure implementation ช้ามาก
    • บนเดสก์ท็อป i7-6700 ผลลัพธ์ของ Python อยู่ที่ประมาณ 2.06~2.11 วินาที
    • บนเราเตอร์ pfSense ผลลัพธ์ของ Python อยู่ที่ประมาณ 22.8~24.2 วินาที
    • C++ protoc --decode_raw ใช้เวลาบนเดสก์ท็อปประมาณ 0.017~0.022 วินาที และบนเราเตอร์ pfSense ประมาณ 0.12~0.14 วินาที

ความพยายามถอดรหัส Protobuf และดึง schema

  • เนื่องจาก Python ไม่รองรับ raw Protobuf decoding จึงเลือกวิธีสื่อสารกับไบนารี C++ protoc ผ่าน subprocess.Popen แทนการเรียกใช้ C++ libprotobuf.so โดยตรง
  • ลอง fuzzing การตอบกลับของวิดีโอโฆษณาด้วยการทำ 200, 404, 503 ว่าง ๆ, response body ที่ถูกตัด, การทำบางส่วนของวิดีโอโฆษณาเป็น null เป็นต้น แต่แอป iOS จะค่อย ๆ ช้าลงแล้ว crash หรือค้างอยู่ที่หน้าจอโฆษณา
  • การบล็อก URL กระตุ้นให้แอปมีพฤติกรรมตอบโต้ และใน video response chunk ก็มี session metadata รวมอยู่ด้วย
  • blackboxprotobuf สำหรับ Burp Suite สามารถ decode raw Protobuf wire message, inject เนื้อหา แล้ว encode กลับเพื่อดูการทำงานของ Protobuf endpoint ได้
    • แนะนำให้ใช้เวอร์ชันต้นฉบับของ Burp Suite ไม่ใช่ PyPI fork
    • บาง fork มีปัญหา stack overflow หรือ infinite recursion เพราะ deep recursion
    • หากใช้ C++ bindings จะ transcode raw Protobuf ราว 500KiB ได้ภายในไม่กี่วินาที
  • schema ที่สร้างขึ้นไม่สมบูรณ์ มีขนาดใหญ่ ซ้อนลึก และ pretty-print ช้า แต่ก็เพียงพอสำหรับการหา detail ของโฆษณา
  • มีการลองใช้ PBTK, Apktool, dex2jar, Java Decompiler เพื่อดึง .proto หรือไฟล์ schema จริงจาก YouTube APK บน Android
    • สิ่งที่ PBTK ดึงออกมาได้มีเพียง proto file ขนาด 59 ไบต์
    • แม้ใน Java จะมี Protobuf classes และ getter/setter แต่ก็ไม่ได้ schema files ที่แท้จริง จึงหยุดการลองในทางนี้

จุดเปลี่ยนสุดท้าย: เปลี่ยน 1 ไบต์ของ Protobuf field tag

  • จาก decrypted network traffic และผลของ Protobuf fuzzing พบว่าโฆษณาอยู่ในโครงสร้างที่ถูกลงทะเบียนไว้กับ slots ของวิดีโอแต่ละรายการ
    • ประเภทของ slot มีทั้ง pre-roll, mid-roll, end-roll, full-page, ad pods
    • หากบล็อก URL โฆษณา จะเกิดข้อผิดพลาดในลักษณะ “โฆษณาที่ไม่มีอยู่จอง slot ไว้” และทำให้ UI panic
  • มองว่าการ decode, edit, แล้ว re-encode โดยไม่มี schema ต้นฉบับจะได้ encoding ที่เปลี่ยนไป และไม่รู้ว่าใช้ ZigZag หรือไม่, เป็นชนิดตัวเลขแบบ int32, int64, sint32/64, varint อะไร รวมถึงลำดับ object field ก็มัก nondeterministic จึงเป็นปัญหา
  • พบช่องทางอ้อมจาก backward compatibility ของ Protobuf และพฤติกรรมของ UnknownFieldSet
    • เมื่อซอฟต์แวร์เก่าอ่าน message ที่มี field ใหม่เพิ่มเข้ามา อาจเกิด unknown field ได้
    • หากเปลี่ยน field key บางตัวเป็นค่าอื่น อาจทำให้ sub-structure ทั้งก้อนที่มีข้อมูลโฆษณาและ tracking กลายเป็นสถานะ unavailable ได้
  • ยกตัวอย่างแนวคิดการเปลี่ยน field key 49399797 เป็น 49399796 เพื่อทำให้ ad/tracking sub-structure นั้นกลายเป็น unknown field
  • field key 49399797 หาไม่เจอด้วยการค้นหา hex แบบตรง ๆ และต้องคำนึงถึง varint/tag encoding
    • wire type คือ 2 หมายถึง nested string/message แบบ length-delimited
    • ลำดับไบต์ tag ของ target field key 49399797 คือ AA FF B8 BC 01
    • เมื่อตัด 3 บิตของ wire type ออกด้วย 395198378 >> 3 ก็จะได้ field key เดิม 49399797
  • ใช้ classic ad URL signature อย่าง /pagead/ ใน Protobuf bytes เพื่อกำหนดขอบเขตการค้นหา field แล้วไล่ย้อนกลับจากตำแหน่งนั้นเพื่อหาทั้ง field tag และ field key ที่ต้องแก้ไข
  • ในตัวอย่าง intercept log พบ key 49399797 ที่ตำแหน่ง 4465 และ key 50195462 ที่ตำแหน่ง 4477 ในการตอบกลับ application/x-protobuf ขนาด 1.87MiB ของคำขอ POST ไปยัง youtubei.googleapis.com:443/youtubei/v1/browse?key=...
  • ใน O(n) smoke test มีการสแกน Protobuf data ขนาด 1.8MiB เพียงหนึ่งรอบโดยไม่ใช้หน่วยความจำเพิ่ม
    • พบ target ที่ไบต์ลำดับที่ 30,593 จากทั้งหมด 1.8MiB
    • ย้อนกลับราว 600 ไบต์เพื่อหา field key ที่จะ denature
  • เมื่อวิธีนี้ใช้งานได้ ก็ไม่จำเป็นต้องบล็อก URL ที่มี *.googleadservices.com หรือ /pagead/ อีกต่อไป และคำขอเหล่านั้นก็จะไม่ถูกส่งออกมาตั้งแต่แรก

โครงสร้างสคริปต์ add-on ของ MITMProxy

  • สคริปต์ add-on ของ MITMProxy ถูกนำเสนอเป็น proof of concept สำหรับบล็อกโฆษณา YouTube บนอุปกรณ์ Apple ที่เชื่อมต่อเครือข่าย
    • ชื่อไฟล์คือ youtube.py
    • ตัวอย่างการรันคือ mitmdump --listen-port 8080 --listen-host 127.0.0.1 -s "youtube.py"
    • prerequisite ของ FreeBSD คือ pkg install protobuf, pkg install py38-pip, pip install jsonpath-ng
  • ในสคริปต์มี fairness function ที่ยอมให้โฆษณาแสดง 5% เพื่อสนับสนุนครีเอเตอร์
    • in_allowed_ads_window() จะข้ามการบล็อกโฆษณาหากเวลาปัจจุบันอยู่ระหว่างนาทีที่ 0 ถึง 2 ของทุกชั่วโมง
  • YouTubeAdBlocker จะ intercept โดเมนที่เกี่ยวข้องกับ YouTube และแก้ไข response แบบ JSON หรือ Protobuf เพื่อลบข้อมูลโฆษณา
    • host regex ที่เป็นเป้าหมายของการ intercept คือ \.youtube\.com|google\.(com|ca)|googleapis\.com|googleadservices\.com|googlevideo\.com
    • สตริงสำหรับตรวจจับโฆษณา Protobuf คือ b"/pagead/"
    • ขีดจำกัดการค้นหาคือ 80_000 ไบต์
    • target field tag คือ 50195462
  • รายการบล็อกในขั้นตอน request มี pagead/, log_event?, stats/ads, stats/qoe?, ptracking?, generate_204, error_204, adformat=, activeview?, _ad_, ai?, sw.js เป็นต้น บนโฮสต์ YouTube
  • JSON replacement สำหรับ YouTube เวอร์ชันเว็บจะลบหรือปิดการทำงานของฟิลด์ที่เกี่ยวข้องกับโฆษณา
    • yt_ad เปลี่ยนเป็น "0"
    • adPlacements เปลี่ยนเป็น []
    • adPlacementRenderer, adPlacementConfig, playerAdParams, gutParams เปลี่ยนเป็น {}
    • adVideoId เปลี่ยนเป็น ""
    • showCompanion, showInstream, useGut เปลี่ยนเป็น False
  • hook load() จะปิดการใช้งาน HTTP/2 และตั้งค่า anticomp=True, mode="transparent"
  • hook running() จะอัปเดต allow_hosts เพื่อให้การ intercept ใช้กับเฉพาะโดเมนที่เกี่ยวข้องกับ YouTube
  • hook response() จะค้นหา /pagead/ ภายใน 80,000 ไบต์แรกของ response body หาก content-type มี protobuf
    • หากพบ จะสร้าง target tag bytes ด้วย TagBytes(self.target_field_tag, WIRETYPE_LENGTH_DELIMITED)
    • จะสร้าง tag bytes ใหม่ของ target_field_tag - 1
    • จะค้นหาแบบย้อนกลับก่อนถึงตำแหน่ง /pagead/ เพื่อหา target tag
    • จะแทนที่ bytes ณ ตำแหน่งนั้นด้วย bytes ที่สอดคล้องกับ target_field_tag - 1
    • จากนั้นจะใส่ Protobuf content ที่แก้ไขแล้วกลับเข้าไปด้วย flow.response.set_content(bytes(body))
  • คอมเมนต์ในโค้ดระบุว่า PoC นี้บล็อกโฆษณาได้แล้ว 90% และเสริมว่าในส่วนอื่นยังมี field key อื่น ๆ และอาจมีหลายส่วนของโฆษณาที่ต้องทำให้ใช้งานไม่ได้

ประสิทธิภาพ ข้อจำกัด และผู้ใช้เป้าหมาย

  • เทคนิคสุดท้ายอาศัยความสามารถของ Protobuf ที่ยอมรับ unknown field เพื่อให้เข้ากันได้แบบ backward-compatible เมื่อ schema เปลี่ยน และอาศัย single-byte edit sensitivity ของฟอร์แมตแบบ compact
  • หากเปลี่ยน 1 ไบต์ในจุดสำคัญจนทำให้ส่วนที่ซ้อนลึกดูเหมือนเป็นของ future schema version, Protobuf จะ ignore ส่วนนั้นและลบข้อมูลโฆษณาได้
  • Google ส่งคืน response Protobuf ขนาดใหญ่ที่รวมถึง layout ของแอป iOS ด้วย โดย payload ตัวอย่างมีขนาด 1.8MiB
  • ผู้เขียนระบุว่าการ parse payload ทั้งก้อนต้องใช้ native code อย่าง C++/Swift และการ decode ด้วย Python ช้ากว่าหลายหลัก จนทำให้เกิด connection timeout
  • JSON แบบเว็บต้อง parse, edit และ re-serialize payload ทั้งหมด แต่เทคนิค Protobuf ใช้เพียง linear scan และ backtrack อย่างรวดเร็ว จึงประมวลผลได้ในระดับ microseconds เหมาะกับการบล็อกโฆษณาแบบ real-time และไม่ต้องมี blocklist
  • URL ทั้งหมดของ *.googleadservices.com และ /pagead/* บนอุปกรณ์ Apple มาจาก Protobuf payload ดังนั้นเมื่อข้อมูลโฆษณาหายไปจาก payload แล้ว request เหล่านั้นก็จะหายไปเองโดยอัตโนมัติ
  • แอป YouTube จะไม่พยายาม fetch ad URL ทำให้รู้สึกเร็วขึ้น และเนื้อหาจะเล่นได้ทันทีเพราะไม่มีการลงทะเบียนโฆษณาใน video slot
  • วิธีนี้ถูกนำเสนอเป็นเทคนิคที่ highly specialized สำหรับบล็อกโฆษณา YouTube บนอุปกรณ์ Apple หรือทราฟฟิก tracker ของ Instagram, WhatsApp และ Facebook
  • ผู้เขียนระบุว่าความต้องการ CPU สำหรับการ decrypt/re-encrypt ทราฟฟิก HTTPS สูงเกินความสามารถของ Raspberry Pi อย่างมาก
  • เนื่องจากเจาะกลุ่มเจ้าของอุปกรณ์ Apple ที่ไม่ต้องการ compromise ระบบปฏิบัติการของตัวเอง จึงมองว่ากลุ่มผู้ใช้งานยิ่งแคบลง

YouTube Premium และการทดลองต้นทุนโฆษณา

  • ผู้เขียนมองว่ายังไม่แน่ใจว่า YouTube Premium ที่ราคา CAD $9.99/mo หรือ CAD $11.99/mo และประมาณ CAD $13.43/mo เมื่อรวมภาษี จะถือว่าสมเหตุสมผลหรือไม่
  • มีการทดลองดูการแสดงโฆษณาเป็นเวลาหนึ่งวันด้วยโน้ตบุ๊กที่สะอาดและ private browsing โดยดู YouTube เป็นช่วง ๆ
    • ในประวัติการรับชมมีวิดีโอที่ “ดู” เพียง 10 รายการ
    • ระหว่างดูบางส่วนของวิดีโอ 10 รายการนั้น พบโฆษณา 8 ชิ้น
    • มีเพียง 2 ชิ้นที่กดข้ามได้ และก็ข้ามทั้งคู่
  • หากสมมติ CPV คร่าว ๆ ที่ USD $0.15 โฆษณา 8 ชิ้นต่อวันจะเท่ากับต้นทุนฝั่งผู้ลงโฆษณา 8 x $0.15 = $1.20 และเมื่อนำไปคาดการณ์ทั้งเดือนจะอยู่ที่ราว USD $36/mo
  • ยังมีการคำนวณโดยอิงข้อมูล Statista ด้วยการนำยอดใช้จ่ายโฆษณาในสหรัฐฯ หารด้วยจำนวนการดูทั้งหมด
    • ในปี 2019 ผู้ลงโฆษณาในสหรัฐฯ ใช้เงินกับ YouTube ไป $15.1 billion
    • ผู้อยู่อาศัยในสหรัฐฯ รับชมวิดีโอ 916 billion ครั้ง
    • ค่าเฉลี่ยคือ $15.1B / 916B = USD $0.0165 per view
    • สำหรับกรณีของผู้เขียน คำนวณได้ว่าเป็นต้นทุนโฆษณาประมาณ USD $0.13 ต่อวัน และราว USD $3.96 ต่อเดือน
  • ระหว่างการทดลองโฆษณา ผู้เขียนปิดเสียงด้วยฮาร์ดแวร์และละสายตาออกบ่อยครั้ง จึงมองว่าเงินโฆษณาที่ลงกับตนเองนั้นสูญเปล่า
  • ถึงอย่างนั้นก็ยังต้องการสนับสนุนครีเอเตอร์ และจะลองใช้ Premium trial 3 เดือน พร้อมกับติดตามต่อไปว่า Google ติดตามข้อมูลอะไรเกี่ยวกับตนบ้าง
  • ผู้เขียนกังวลว่าเมื่อมีการยื่น DMCA claim รายได้จากโฆษณาทั้งหมดอาจไม่ไปถึงครีเอเตอร์แต่ไปถึงผู้เรียกร้องสิทธิ์แทน และเสริมว่าไม่แปลกที่ครีเอเตอร์จำนวนมากย้ายไป Patreon

สรุปท้ายสุด

  • ตั้งค่าฮาร์ดแวร์เราเตอร์ใหม่ตั้งแต่ต้น และแยก LAN ออกเป็น trusted/untrusted zone
  • ตั้งค่าการบล็อกโฆษณาแบบ DNS ดั้งเดิม
  • เพิ่ม transparent MITM proxy
  • สุดท้ายสามารถบล็อกโฆษณา YouTube บนอุปกรณ์ Apple ที่เชื่อมต่อเครือข่ายได้อย่างมีประสิทธิภาพ
  • ผู้เขียนบอกว่าส่วนที่ยากจบแล้ว จึงจะพิจารณาจ่าย YouTube Premium แต่เสริมว่า tracker ยังคงถูกบล็อกอย่างหนักเหมือนเดิม

1 ความคิดเห็น

 
GN⁺ 2025-03-19
ความคิดเห็นบน Hacker News
  • ดูเหมือนว่าไม่ใช่ข้อบกพร่องของรูปแบบ Protobuf แต่เป็นการที่ผู้เขียนเปลี่ยนหมายเลขฟิลด์ไปเป็นหมายเลขใหญ่ ๆ ที่ยังไม่ได้ใช้
    วิธีคือค้นหาลายเซ็น URL โฆษณาอย่าง /pagead/ ในไบต์ของ Protobuf เพื่อจับช่วงของฟิลด์ แล้วไล่ย้อนกลับไปหาทั้งแท็กฟิลด์เป้าหมายและคีย์ฟิลด์เพื่อทำให้ใช้งานไม่ได้ แต่นี่ใกล้เคียงกับ พฤติกรรมที่ตั้งใจไว้ มากกว่าจะเป็นข้อบกพร่อง
    ถ้าจะลงแรงพอที่จะหาแท็กได้อยู่แล้ว การอ่านความยาว varint ที่อยู่ข้าง ๆ แล้วข้ามไบต์ส่วนนั้นไปก็ไม่ใช่งานเพิ่มที่ใหญ่นัก อาจต้องคัดลอกบัฟเฟอร์หรือเลื่อนไบต์ แต่สคริปต์ PoC เองก็ต้องคัดลอกอยู่แล้ว เพราะ bytes ที่ API ของ mitmproxy คืนมาเป็นแบบแก้ไขไม่ได้

    • ในระดับโปรโตคอล มันทำงานตามที่คาดไว้ แต่จุดโหว่ดูเหมือนอยู่ที่เมื่อพบฟิลด์ที่ไม่รู้จักในโครงสร้างข้อมูลโฆษณา Google ไม่แสดงข้อผิดพลาดและ จัดการเหมือนว่าไม่มีโฆษณา
      ก่อนที่ Google จะเปลี่ยนโปรโตคอลถึงขั้นทำให้แอปเวอร์ชันเดิมไม่มีโฆษณาเลย ก็คงปล่อยแอปใหม่ออกมาก่อน ดังนั้นแค่ใช้การตรึงใบรับรองพื้นฐาน หรือถอดรหัสแบบไม่ผ่อนปรนต่อความล้มเหลวในการดึงข้อมูลโฆษณา ก็สามารถปิดวิธีบล็อกนี้ได้ทันที ถ้าเป็นทีม YouTube ก็น่าจะมองจุดนี้ว่าเป็นข้อบกพร่อง
    • อ็อบเจ็กต์ bytes แก้ไขไม่ได้ แต่ bytearray ไม่ได้แก้ไขไม่ได้
  • ใช้ พร็อกซี C++/Go ขนาดเล็กก็ทำงานเดียวกันได้โดยมีโอเวอร์เฮดน้อยกว่ามาก งานที่นิยามชัดเจนแบบนี้เสถียรกว่าและยุ่งยากน้อยกว่าการปล้ำกับ mitmproxy
    ถ้าส่งทราฟฟิกทั้งหมดผ่านพร็อกซี ประสิทธิภาพจะตกแม้จะใช้การดัก SNI ก็ตาม pfSense ก็เช่นกัน ถ้ามีเซิร์ฟเวอร์ Linux ธรรมดากับกฎ iptables ง่าย ๆ ก็จัดการได้โดยไม่ต้องสู้กับชั้น abstraction ของ pfSense
    เขียนเฉพาะฟิลด์ proto ที่จำเป็นจากที่ reverse engineer มาไว้ในไฟล์ .proto แล้วสร้างโค้ดอัตโนมัติ จากนั้นเปลี่ยนแฟล็กก็พอ ถูกกว่าการทำด้วย Python และอัปเดตง่ายกว่าเมื่อ proto เปลี่ยน การเมินแท็กฟิลด์ที่ไม่รู้จักเป็นฟีเจอร์สำคัญของ Protobuf และช่วยให้เปลี่ยนสคีมาที่เข้ากันได้โดยไม่ทำให้ deployment เดิมพัง

    • การจงใจทำให้ประสบการณ์ YouTube ช้าลงและการเปลี่ยนวิดีโออืดลงอาจจะดีก็ได้ โดยเฉพาะน่าจะช่วยลดความเสพติด Shorts ได้พอสมควร
    • หวังว่าจะมีบล็อกโพสต์ที่แชร์รายละเอียดวิธีทำแบบนั้น
    • ถ้าคุณช่วยเขียนไกด์เองว่า inefficiency อยู่ตรงไหน และจะบรรเทาด้วยซอฟต์แวร์ที่เรียบง่ายกว่าได้อย่างไรก็น่าจะดี
      ดูเหมือนผู้เขียนบทความจะรับรู้ประเด็นส่วนใหญ่ในคอมเมนต์นี้อยู่แล้ว และบทความก็ค่อนข้างละเอียด เขา benchmark ด้วย Python และ C++ แล้ว implementation สุดท้ายก็ไม่ได้ decode Protobuf ด้วยซ้ำ เขายังลองใช้โซลูชัน mitm หลายแบบแล้ว และใช้ pfSense ไม่ใช่เพราะเป็นแค่เราเตอร์ความปลอดภัยธรรมดา แต่เพื่อเล็งเฉพาะทราฟฟิกของ Apple TV ด้วย VLAN และ VPN
      คอมเมนต์นี้รู้สึกถูกและดูแคลนเกินไป บทความต้นฉบับไม่ได้เป็นแบบนั้น ดังนั้นถ้าจะพูดแบบนี้ ก็ควรพิสูจน์ให้ชุมชนเห็นเอง
    • อยากรู้ว่ามีคำแนะนำสำหรับ พร็อกซีเบา ๆ ที่รันบน macOS และให้บริการกับอุปกรณ์อื่น ๆ ในบ้านได้ไหม
  • ถ้าจ่าย YouTube Premium แล้วถือว่าสนับสนุนครีเอเตอร์ไหม? ถ้าใช่ อยากรู้ว่าเมื่อเทียบกับการสนับสนุนโดยตรงอย่าง Patreon แล้วประมาณไหน

    • เทียบกับ Patreon ก็คงไม่มาก แต่ก็ยากที่จะคาดหวังให้คนที่ดู YouTuber หลายคนสมัคร Patreon ของทุกคน
      รายได้ที่ครีเอเตอร์แต่ละรายได้จากการสมัคร YouTube Premium หนึ่งบัญชีคงเล็กน้อยมาก แต่ก็ยังดีกว่าการดูวิดีโอขณะบล็อกโฆษณา
    • เป็นที่รู้กันว่า ครีเอเตอร์ได้ส่วนแบ่งจาก การรับชมผ่าน YouTube Premium มากกว่ายอดชมที่มีโฆษณาปกติ เพราะถ้าข้ามโฆษณาก็ไม่มีรายได้ อย่างไรก็ดี ผู้ใช้ Premium ยังมีจำนวนน้อย จึงยังมีข้อจำกัดอยู่
    • ข้อมูลล่าสุดมีไม่มาก แต่ตอนเปิดตัวครั้งแรกในชื่อ Youtube Red โดยทั่วไปแล้วมากกว่ารายได้โฆษณาต่อวิวอยู่มาก
    • มากกว่าโฆษณา แต่น้อยกว่า Patreon
      คิดตาม เวลาในการรับชม ไม่ใช่ impression ของโฆษณา ดังนั้นครีเอเตอร์ที่ทำคอนเทนต์แบบยาวจะได้เปรียบกว่า
  • บัญชี YouTube ของแฟนผมแปลกตรงที่ไม่ว่าจะล็อกอินจากอุปกรณ์ไหนก็ไม่มีโฆษณา รวมถึง Apple TV ด้วย ไม่ใช่ Premium และไม่เคยเป็น Premium มาก่อน
    สงสัยว่าภายในมีแฟล็กอะไรตั้งไว้จนปิดโฆษณาหรือเปล่า

    • ส่งชื่อผู้ใช้บัญชีและอีเมลมาทาง DM ได้เลย ผมจะตรวจสอบแล้วแก้ให้
    • แฟนคุณน่าจะอยู่ใน กลุ่มควบคุม ของโฆษณาโดยพฤตินัย อาจใช้เพื่อเปรียบเทียบกับพฤติกรรมของคนที่เห็นโฆษณา เพื่อดูว่าโฆษณาส่งผลต่อผู้ใช้อย่างไร
    • อาจถูกจัดอยู่ใน holdback experiment ก็ได้ มักมีการกันผู้ใช้บางส่วนไว้ในกลุ่ม holdback เพื่อดูว่าฟีเจอร์อย่างการแสดงโฆษณาส่งผลต่อ metric อย่างไร และตอนทำงานที่ Google ก็เคยทำการทดลองแบบนั้น
    • สมัยก่อนถ้ามีการสมัครสมาชิก Google Music โฆษณา YouTube จะถูกปิด แม้บริการจะหยุดไปหรือยกเลิกการสมัครแล้ว โฆษณา YouTube ก็ยังไม่กลับมานานกว่า 6 เดือน
      ตอนนั้นเองถึงได้มีช่วงที่เข้าใจว่าทำไมผู้คนถึงบ่นกัน
    • ผมเจอประสบการณ์เดียวกันบน Twitch
      แม้ไม่ได้ใช้ตัวบล็อกโฆษณา แต่แค่ล็อกอินก็ไม่เห็นโฆษณาเลยทั้งบนเว็บไซต์และแอปมือถือ ไม่มี Twitch Turbo และไม่มี Amazon Prime แล้วด้วย สิทธิประโยชน์ Turbo อื่น ๆ ก็ไม่มี จึงไม่ได้ถูกแฟล็กเป็น Turbo ทั้งหมดแน่ ๆ
      ไม่รู้ว่าเมื่อก่อนตอนทำ bug bounty แล้วไปแตะโน่นนี่จนโปรไฟล์บัญชีพังโดยบังเอิญหรือเปล่า แต่ถ้าจะปล่อยให้ผมได้ประโยชน์นี้ต่อ ผมก็ให้ข้อมูลละเอียดกว่านี้ได้
      ที่แปลกคือผมจำได้ว่าเมื่อก่อนตอนอยู่โรงพยาบาล เมายาและเจ็บปวดจนอยากดูแค่ทีวี แต่โฆษณา Twitch หนักมากจนแทบสติแตก แล้วอีก 1–2 ปีต่อมาจู่ ๆ ก็รู้ตัวว่าไม่ได้เห็นโฆษณามาหลายปีแล้ว
      น่าจะมี A/B test แบบไม่มีโฆษณา ที่ถูกลืมไปนาน และไม่คุ้มที่จะเก็บกวาด เลยยังค้างอยู่ ผมจึงได้ประโยชน์มาหลายปีและดู Twitch มากกว่าแพลตฟอร์มอื่นใด Turbo ของ Twitch ในสหราชอาณาจักรราคาเดือนละ £12 หรือราว $15.50 ซึ่งแพงแม้เทียบทั่วโลก และเมื่อเทียบกับ $12/€12 ในสหรัฐฯ และยุโรป ก็ถือว่าเป็นราคาที่เสียเปรียบพอสมควร
  • การวางพร็อกซีแบบคนกลางไว้ระหว่าง Apple TV กับอินเทอร์เน็ตภายนอกแล้วสามารถถอดรหัสทราฟฟิก HTTPS ได้นั้นค่อนข้างน่าประหลาดใจ
    ปกติคิดว่ามันไม่น่าจะทำงานได้ แต่ภายหลังก็แปลกใจอีกเมื่อรู้ว่าสามารถเพิ่ม CA เข้าไปในที่เก็บใบรับรองของ Apple TV ได้ เป็นบทความที่ละเอียดซึ่งไล่ดูทั้งสแตก

    • ถ้าจะเดาว่าทำไม Apple ถึงรองรับการเพิ่มใบรับรอง ก็น่าจะเป็นเพราะในสภาพแวดล้อมองค์กรหรือการศึกษา มีการใช้ Apple TV เป็นกล่อง AirPlay และต้องทำให้สอดคล้องกับข้อกำหนดด้าน IT และการจัดการอุปกรณ์
      เช่น ในมหาวิทยาลัย ถ้าจะให้อุปกรณ์เชื่อมต่อ Wi‑Fi ได้ ต้องนำ MAC address ไปใส่ allowlist หรือติดตั้งใบรับรอง
    • Google สามารถปิดกั้นวิธีนี้ได้ง่าย ๆ แค่ตรวจสอบ CA ที่เซ็นใบรับรอง SSL ในแอป YouTube
      แต่ถ้าทำแบบนั้น YouTube อาจพังในสภาพแวดล้อมองค์กรจำนวนมาก จึงไม่แน่ใจว่าจะทำจริงไหม ถึงอย่างนั้น น่าเสียดายที่การปิดกั้นทำได้ง่ายมาก
    • ไม่คาดคิดมาก่อนว่าจะสามารถเพิ่ม CA ลงใน Apple TV ได้ คงเพราะไม่เคยลองเข้าถึงทรัพยากรที่ไม่มีสายโซ่ใบรับรองที่ถูกต้องผ่าน Apple TV เลยไม่รู้
    • อุปกรณ์ส่วนใหญ่ยอมให้เพิ่ม CA ได้ แต่ทุกวันนี้แอปแทบทั้งหมดใช้การตรึงใบรับรอง จึงไม่สนใจที่เก็บใบรับรองของระบบ น่าประหลาดใจมากที่ YouTube ไม่ทำแบบนั้น
    • ที่น่าขันคือ Android TV อย่างน้อยในเวอร์ชัน 7.x ไม่อนุญาตให้ทำสิ่งนี้ เคยพยายามเลี่ยงใบรับรอง Let's Encrypt ที่ไม่ถูกเชื่อถือแล้วถึงได้รู้แบบลำบาก
  • เคยพยายามทำบน Apple TV อยู่สองสามครั้ง แต่ไม่เคยสำเร็จเลย เหมือนว่า YouTube จะใส่การตรึงใบรับรองลงในแอปแล้วหรืออะไรทำนองนั้น อยากรู้ว่าช่วงนี้มีใครทำให้มันทำงานได้ไหม

    • ถ้ายอมสละเวลา ลองขุด Frida [0] ดูได้ ใบรับรองที่ถูกตรึงไว้ก็ไม่ใช่ปัญหา
      [0] https://frida.re/docs/home/
  • ชอบความพยายามทุกแบบในการบล็อกทั้งเครือข่ายสำหรับบริการออนไลน์ห่วย ๆ ที่ถูกยัดเยียดให้ใช้
    การบล็อกโฆษณาก็ดี แต่ถ้ามีวิธีที่ง่ายและแพร่หลายกว่านี้ในการบล็อก infinite scroll เชิงรุกอย่าง YouTube Shorts หรือ Instagram Reels ทั้งเครือข่ายก็คงดี
    ใน Instagram แค่อยากดูโพสต์กับสตอรีของคนที่ติดตาม ไม่อยากให้มันแนะนำวิดีโองี่เง่าที่ออกแบบมาเพื่อดึงความสนใจ อาจเป็นการเผยให้เห็นว่าขาดวินัยก็ได้ แต่บ่อยครั้งก็เผลอดูไปสองสามคลิปแล้วเสียเวลาในชีวิตไป 15 นาที

    • ไม่ได้ถูกบังคับให้ใช้นะ จะไม่ใช้ก็ได้ หรือจะจ่ายเงินก็ได้
      ผู้ใช้อินเทอร์เน็ตโดยรวมเลือกทางที่ไม่อยากจ่ายเงิน ดังนั้นจึงต้องมีใครสักคนรับต้นทุน โดยภาพรวมแล้ว ผู้ใช้อินเทอร์เน็ตไม่ได้ตอบแทนฝั่งที่ไม่แสดงโฆษณา อยากได้คอนเทนต์ แต่โดยมากอยากได้ฟรี
    • ลบแอปแล้วใช้เว็บเพจ และใช้เบราว์เซอร์ที่รองรับ userscript ก็พอ
      เจอสคริปต์ที่เปลี่ยนหน้า Instagram ให้เหมือนเป็นแค่แท็กรูปภาพ เพื่อให้ดูได้เฉพาะรูป: https://greasyfork.org/en/scripts/5014-un-instagram
    • มองว่ากลยุทธ์พวกนี้ใช้ประโยชน์จากความอยากรู้อยากเห็นตามธรรมชาติของเราและสุนทรียะที่อยู่รอบ ๆ มัน
      ดังนั้นดูเหมือนไม่ใช่แค่ขาดวินัย แต่ใกล้เคียงกับความชาชินที่เราสะสมมามากกว่า และนั่นค่อนข้างแย่ ความพยายามและความสร้างสรรค์ในการทำให้เรากลับมาเป็นฝ่ายใช้แพลตฟอร์ม แทนที่จะให้แพลตฟอร์มทำให้เราใช้งานนั้นน่ายกย่อง
    • ในฐานะพ่อแม่ เห็นด้วยเป็นพิเศษ การเห็นเด็ก ๆ ถูกอัลกอริทึมดูดเข้าไปนั้นเป็นเรื่องยาก
      คุยกับเด็ก ๆ เป็นประจำ และพวกเขาก็เห็นด้วยว่ามันเป็นอันตราย แต่ต้านทานได้ยากมาก แม้แต่ตัวเองก็ยังถูกดึงไป doomscrolling เป็นครั้งคราว
      ที่ไหนทำได้ก็ตั้งค่า Pi-hole เพื่อกรองโฆษณาไว้แล้ว แต่ไม่อยากบล็อก YouTube ทั้งหมด ถึงอย่างนั้น เพื่อปกป้องครอบครัว ต่อไปคงต้องพิจารณาอย่างจริงจัง
    • แอปนี้เหมาะมากสำหรับการหยุด infinite scroll ของ Instagram: https://www.distractionfreeapps.com/index.html
  • งานวิศวกรรมดี แต่ก็น่าเศร้านิดหน่อยที่ต้องทำถึงขนาดนี้เพื่อให้ใช้งานฮาร์ดแวร์หรือซอฟต์แวร์ของตัวเองราวกับว่าเป็นเจ้าของได้บ้าง

    • ในกรณีนี้ เป็นเจ้าของอุปกรณ์จริง แต่ดูไม่มีเหตุผลให้ยืนยันว่าเป็นเจ้าของ YouTube หรือคอนเทนต์ของมันด้วย
    • เอา NewPipe APK ไปลงบนกล่อง Android ราคา 30 ดอลลาร์ ก็ทำสิ่งนี้ได้มาตั้งแต่เกือบ 10 ปีก่อนแล้ว
  • YouTube มีโฆษณาด้วยเหรอ? เบราว์เซอร์บล็อกให้ดีเกินไปจนไม่รู้เลย
    ปัญหาจริงคือประสบการณ์บน Apple TV แย่กว่าประสบการณ์บนเว็บเบราว์เซอร์ทั่วไปมาก Apple ล็อกฮาร์ดแวร์ไว้แน่นเกินไป จนโครงสร้างกลายเป็นเอื้อต่อรายได้โฆษณาของ YouTube มากกว่าผู้บริโภคปลายทางที่จ่ายเงินซื้อมา

    • บน Linux, Windows, Android ไม่เห็นโฆษณาเลย บางครั้งพอจะดู YouTube บน iPad ก็แปลกใจว่าโฆษณาถี่และน่ารำคาญแค่ไหน
      ตอนท่องเว็บด้วย iPad นอกเครือข่าย Pi-hole ที่บ้านก็เหมือนกัน ไม่รู้ว่าคนอื่นทนสิ่งนี้ทุกวันได้อย่างไร
      iPad เป็นอุปกรณ์ที่ที่ทำงานแจกให้ จึงไม่ค่อยใช้ส่วนตัว แต่ทุกครั้งที่ใช้ก็ถูกเตือนว่ามันน่ารำคาญแค่ไหน
      แปลกตรงที่ก่อนจะได้ iPad คิดว่ามันคงมีประโยชน์แค่สำหรับเสพคอนเทนต์ แต่จริง ๆ แล้วมันสะดวกมากสำหรับการรีโมตเข้าใช้งานทรัพยากรงานอย่างรวดเร็ว ส่วนการท่องเว็บทั่วไปกับสตรีมมิงมีเดียกลับเป็นอุปกรณ์ที่ติดอยู่ในแดนรกร้างที่เต็มไปด้วยโฆษณา
  • ถ้าต้องการ YouTube แบบไม่มีโฆษณา ใช้ https://yewtu.be หรืออินสแตนซ์ Invidious อื่น ๆ https://docs.invidious.io/instances/ ได้
    ระหว่าง YouTube กับ Invidious มีการแข่งขันสะสมอาวุธกันอยู่ และบางครั้ง Invidious ก็ใช้งานไม่ได้ แต่ทีมก็มักหาวิธีใหม่ ๆ ในการเลี่ยง YouTube และส่งวิดีโอแบบไม่มีโฆษณาได้เสมอ

    • มีเหตุผลที่ในชื่อเรื่องมีคำว่า “on AppleTV” อยู่ ไคลเอนต์หรือฟรอนต์เอนด์ทางเลือกใช้ไม่ได้บนเครื่องนั้น
    • บนอุปกรณ์อย่าง Roku TV ไม่มีเบราว์เซอร์ วิธีนี้จึงใช้ไม่ได้