本文是一份圖解優先的對照誌。左欄是 kwara(特化於數位廣告生態的操作者歸因鑑識工具)實際蒐集的偵察標的——URL 參數、HTML pixel、HTTP Archive 的第三方請求、ads.txt 變現宣告、TLS 憑證、HTTP header、cloaking 行為差異;右欄是這些標的在數位廣告產業裡的本來身分——它們分別是 SSP、DSP、DMP、廣告交易所、IAB 透明度標準、轉換追蹤 pixel 等機制為了各自的商業目的而製造、並且刻意公開或無法擦除的人工痕跡。
把兩欄並排,會浮現一個反覆出現的結構:廣告生態為了「讓錢正確流動、讓轉換被正確計數、讓供應鏈可被買方查核」,在網頁與協定層鋪了一整套機器可讀的識別碼與宣告檔。詐騙與協同網路的營運者也在這套生態裡變現,因而不得不帶上同一批識別碼。kwara 的工作,本質上就是站在這套廣告機器的幾個固定接點上取樣,再把同一識別碼跨網域聚合成「同一操作者」的證據。
程式化廣告(programmatic advertising)是一條從廣告主(錢的起點)經買方技術、市場、賣方技術,流到發布商(錢的終點)的供應鏈,每一個中介各抽一手費用 [1][2]。下圖把這條鏈攤平,並用琥珀色標出 kwara 在哪些站點取樣。關鍵觀察:kwara 並不需要進入交易所或 SSP 的內部——它只在使用者瀏覽器看得到的那一端(URL、HTML、第三方請求)與發布商自己公開的宣告檔(ads.txt)取樣,就能反推出供應鏈另一端的帳號身分。
這是全文的核心。每一列是一個 kwara 鑑識標的,對到它在廣告產業的本來身分、產業造它的原始目的,以及 kwara 從中讀出什麼。抗匿名化強度沿用 kwara 自身的分層(docs/analysis-design.md 第一節)。
| kwara 鑑識標的(函式) | 訊號層 | 對應的廣告產業實體/標準 | 產業造它的目的 | kwara 揭露什麼 | 抗匿名化 |
|---|---|---|---|---|---|
redirect topologyscanner.scan_url() | 網路層 | 短連結 / wrapper 導流 | 把點擊導到落地頁 | 跳轉拓樸 | 低 |
IP / ASN / 託管商asn_clusters() | 主機層 | Hosting / CDN | 承載網站 | 共置基礎設施 | 低 |
| WHOIS / 註冊商 (domain 子分頁) | 網域層 | Domain Registrar | 網域註冊 | 註冊指紋 | 低 |
TLS issuer/serial/SANshared_certificates() | 憑證層 | CA + Certificate Transparency | HTTPS 信任根 | 同伺服器 / 同批次部署 | 中 |
utm_* / fbclid / gclidshared_params() · shared_param_keys() | URL 參數層 | click ID + UTM(DSP / 廣告帳號歸因) | 把點擊歸因到 campaign | 同活動 / 同後台 | 中 |
跨域 redirect 改名wrapper_relationships() | Wrapper 層 | Affiliate / redirect 包裝 | 聯盟導流與隱藏目的地 | 同串接結構 | 中 |
第三方 endpoint 共用shared_endpoints() | HAR endpoint 層 | 第三方追蹤器 / 後端 API | 蒐集行為資料 | 同後台 / 直連 IP 繞 CDN | 中-高 |
Pixel ID / GA / AdSenseshared_tracking_ids() · fingerprints | HTML pixel 層 | Meta Pixel / GA4 / GTM / AdSense / TikTok… | 轉換追蹤 + 變現 | 同變現/測量帳號 | 高 |
URL+HTML 交叉確認ad_tracking_platforms()(both) | 跨來源合併 | click ID × pixel 雙證據 | — | 獨立確認(強) | 高 |
ads.txt DIRECT / byte 相同shared_ad_accounts() · adstxt.py | 變現宣告層 | IAB ads.txt / sellers.json / 供應鏈物件 | 供應鏈透明、反網域偽冒 | 同收款方 / 同模板 | 高 |
origin 洩漏 / 假版本header_analysis.py(4 函式) | HTTP header 鑑識層 | origin server / WAF(CDN 後) | 服務部署 | origin 揭露 / 同模板 / 主動造假 | 高 |
with-param vs strippedcloaking.detect_cloaking() | Cloaking 層 | 廣告 / SEO 詐欺 cloaking | 對審查者隱藏真內容 | 主動規避偵察意圖 | 最高 |
lightweight vs Playwrightopsec.compute_opsec_profile() | OPSEC 路徑層 | WAF / bot gating | 擋爬蟲與審查工具 | 同 WAF 部署模板 | 中-高 |
帳號×內容 / 時間分布account_content_matrix() | 行為層 | —(由上列訊號合成) | — | 協同分布(不下 flag) | 合成 |
表格深淺由抗匿名化強度排序的設計,反映 kwara 蒐證鏈「往上爬」的順序:越往下,操作者越難在不放棄變現的前提下抹除。
當使用者點擊一則廣告,廣告平台會在落地頁 URL 後自動附加一個 click ID——Google 的 gclid、Meta 的 fbclid、TikTok 的 ttclid、Microsoft 的 msclkid [12][14][16]。這個參數是「廣告側(campaign / ad group / 出價)」與「網站側(pixel 的轉換事件)」之間的橋。落地頁上的 pixel 會把 click ID 抓下來、寫進第一方 cookie(如 Meta 的 _fbc),再經 Conversions API 回報,讓轉換被歸因到正確的廣告帳號 [15]。utm_* 則是 2005 年 Google 併購 Urchin 留下的人類可讀標籤 [17]。
kwara 的 param_attribution.py 把這整張 click-ID 與 UTM 對照表內建為常數:identify_param() 把 utm_* 對到 Google Analytics、fbclid 對到 Meta、gclid 對到 Google Ads。其上有兩個刻意分開的聚合函式:
shared_params(key, value) — 同一活動:兩篇貼文帶同一個值(如 ?utm_term=145)=同一支 campaign。過長的不透明 token(JWT、加密 affiliate ID)改用 SHA-256 前綴比對。shared_param_keys(key, *) — 同一後台:操作者給每位受害者派獨一無二的 ?aff_id=A1, A2, A3…,每個值只出現一次,但這個 key 本身存在就指向同一套後台系統。靠三個門檻(最少貼文數、最少不同值數、最多網域數)過濾掉 ?q= 這種通用 key。
一個「pixel」或「tag」在技術上是一段 JavaScript + 一個網路訊標(beacon,回傳資料用的微小請求);「pixel」之名是早年 1×1 透明圖的歷史遺留,今天圖只剩 <noscript> 後備(fallback) [18]。鑑識上最關鍵的特性是:帳號/property 識別碼被當成字串字面值,直接寫死在初始化呼叫裡,沒有混淆——因為 vendor 的 script 必須讀得到,所以任何人 view-source 也讀得到:
fbq('init', '<pixel-id>') — 綁定到 Events Manager 裡的某個 Meta 廣告帳號 [18]gtag('config', 'G-XXXXXXXXXX');舊版 UA UA-XXXXXXX-X 的中段是帳號號碼,跨同一擁有者所有 property 共用 [19]AW-XXXXXXXXX(每個 Google Ads 帳號唯一);AdSense:ca-pub-+16 碼,在 ads.txt 裡寫成 pub-,是收款的發布商帳號 [20]ttq.load('<id>');LINE:_lt('init', {tagId:'…'})
kwara 的 fingerprints.extract_tracking_ids 不啟動 JS engine、純 regex 抽取,目前涵蓋 11 個平台。兩個經審查強化的設計修補很關鍵:(1) 錨定呼叫情境(context-anchoring)——每條 pattern 都要求 ID 出現在真實 invocation(gtag/fbq/ttq 呼叫或 vendor host URL)裡,避免撈到文件範例;(2) 佔位字串過濾(placeholder filter)——剔除 G-XXXXXXXX 這類佔位字串。聚合函式 shared_tracking_ids 在同一 (platform, ID) 跨 ≥2 網域時入列。
ca-pub- 是收款帳號,Meta Pixel 與 AW- 綁計費與轉換歸因,底下累積的轉換歷史、最佳化學習、受眾名單、金流關係都掛在那個帳號上。換網域免費且即時;換帳號等於放棄全部累積。所以操作者換域遠比換 ID 勤——ID 因此活得比網域久,出賣了叢集。
ads.txt(Authorized Digital Sellers)是 IAB Tech Lab 在 2017 年 6 月為對抗網域偽冒與偽造庫存而推出的純文字檔,由發布商放在自家網域根目錄,逐行宣告「誰被授權賣我的廣告版位」[23][24]。每行四欄:
| 欄 | 內容 | 鑑識意義 |
|---|---|---|
| ① 廣告系統網域 | SSP / Exchange 的標準網域(如 google.com) | 哪個 SSP 在賣此版位 |
| ② 發布商帳號 ID(seller_id) | 發布商在該 SSP 內的帳戶識別碼 | 把網站綁到某具名 SSP 上的一個帳戶 |
| ③ 關係 | DIRECT 或 RESELLER | DIRECT = 網站擁有者本人直接收款;RESELLER = 授權第三方代賣 |
| ④ 認證機構 ID(選填) | TAG ID | 輔助驗證 |
ads.txt 只給匿名的帳號 ID;另一半是 sellers.json——由 SSP 公開在自家根目錄,把 seller_id 反查成具名實體(name + domain + seller_type)[25][8]。兩者一組合,調查者就能:網域 → ads.txt 授權清單 →(對每個 SSP)sellers.json 反查 → 得到真實收款身分。執行期還有 OpenRTB 供應鏈物件(SupplyChain object) 逐跳記錄中介路徑(asi/sid 對齊 sellers.json)[26]。ads.txt 1.1(2022)再加 OWNERDOMAIN/MANAGERDOMAIN 兩個自我宣告變數。
(seller_id, exchange) 對聚類,發現 7.9 萬個混池,其中約 8,700 個含至少一個不實資訊網站 [27];Papadogiannakis 等(2023)以 700 萬站建 AdSparency,量到約 1.5 萬個混池 [28]。
kwara 的 adstxt.py對每個落地網域抓 /ads.txt,落出兩個操作者訊號:(1) 跨網域共用的 DIRECT 帳號(須頻率加權——被「每個」網域共用的少數帳號是共同變現代管商,不是同一操作者);(2) byte 相同的 ads.txt(同一 raw_sha256)=共用模板,是最強的操作者訊號。設計上 ads.txt 比 GA4 共用更硬:GA4 是無意識的追蹤洩漏,ads.txt 是刻意的變現宣告。連 403(部分 cloaker 連 ads.txt 路徑也會 WAF 擋)也記錄不丟——狀態本身是 cloaking-adjacent 的 OPSEC 訊號。
Playwright 截圖落地頁時,會順手記錄頁面發出的所有第三方請求網域(HTTP Archive / HAR 的核心資料)。shared_endpoints() 找出被 ≥2 個落地網域呼叫的非白名單第三方 endpoint——這往往是操作者的後台 API 或自架統計伺服器。能做到這件事,背後是一整套網頁量測學術基礎設施:Englehardt & Narayanan 的百萬站量測(OpenWPM,CCS 2016)[29]、WhoTracks.Me 與 Disconnect 的「追蹤器→母公司」實體解析資料庫 [30]。
config.HAR_NOISE_HOSTS 先濾掉通用 CDN/SDK;is_direct_ip 把走 IP 而非 hostname 的請求浮到頂部——詐騙頁繞過 CDN 直打 origin 後端的鐵證。lightweight fetch 路徑不貢獻 HAR,只有 Playwright 截圖會記錄。廣告識別碼之外,網路會透過承載流量的基礎設施聚類。Certificate Transparency(CT)是所有受信任 CA 簽發憑證的公開、僅可附加的日誌,近即時公布——讓分析者能發現並循線追查到新簽發的網域 [31]。威脅情報的循線擴搜手法包括共用 issuer+serial、重疊的 SAN(一張 cert 涵蓋多個關聯網域)、簽發時間模式,再配 passive DNS 與 ASN 共置做圖聚類。
shared_certificates() 同時輸出兩類叢集:by_cert(同一 issuer+serial=同伺服器鐵證)與 by_issuance(24 小時窗口內批次簽發=同一自動化部署 pipeline)。例如多個落地網域在數小時內、由同一 CA 各自連續簽發一張憑證,就是 by_issuance 會命中的模式。
這層不是廣告產業專屬,而是承載廣告頁的伺服器留下的痕跡。scanner 把每個 redirect hop 的完整 response headers 存進 redirect_hops.response_headers_json,header_analysis.py 提供四個正交視角。關鍵:origin response header 不會被 Cloudflare proxy 擦掉,所以這個訊號繞過 CDN 隱身:
per_domain_constants:某網域多次掃描裡永遠出現且值穩定的 header。例如某網域在多次掃描裡持續回傳一個非標準的自訂 header(如 x-server-hosted: …)——揭露 Cloudflare 後面的真實 origin。cross_domain_shared_template:多網域同時帶相同(異常、非預設)header 值=同一 server 部署模板,證據力比肩 GA4 共用。detect_fake_versions:比對已知「不存在版本」表(Apache 2.5.1、PHP 9.x…),命中即操作者主動造假指紋——主動防偵測訊號。cookie_origin_signals:Set-Cookie; Domain=.realorigin 洩 origin;flag 設置一致性也是跨域指紋。Cloaking——對爬蟲/審查者(Googlebot、廣告平台審查器、Facebook 爬蟲)回與真實使用者不同的內容——是詐騙站與「為廣告而生的劣質站」(MFA)操作者同時規避搜尋與廣告審查的手段,而偵測它本身就是歸因訊號。學術奠基:Wang & Savage《Cloak and Dagger》(CCS 2011)定義了 user-agent / redirection / IP cloaking 的分類 [32];Google 的《Cloak of Visibility》(IEEE S&P 2016)發現 Google 前 100 名搜尋結果中 11.7% 導向 cloaked 內容 [33]。偵測法的共通核心是跨視角比對:用不同 UA/referrer/IP 重複抓同一 URL、追蹤每個 redirect hop,標出內容或跳轉鏈分歧者。
cloaking.detect_cloaking() 把學術 cross-view 法落成「with-param vs stripped」雙抓比對。stripped 版本的 body 也持久化為 cloaking_alt snapshot,供事後 SEO-side 分析。一個域被標 cloaking_suspect,已足以下「operator 故意規避調查」的判定。
OPSEC 路徑層(opsec.compute_opsec_profile)是同一邏輯的另一面:比較 lightweight HTTP fetch 與 Playwright 兩條截圖路徑的成功率。「擋 UA 但放 Chromium」是 WAF 的特定部署模板;同 case 多個域共享同一 OPSEC level,獨立於 GA4 / TLS / 參數訊號指向同操作者。例如同一案件裡,部分網域兩條截圖路徑都擋、另一些兩條都放——這個切割獨立於 GA4/TLS 訊號,卻指向同一組操作者分界。
把全文收束成一條原理:存在是為了「賺錢或測量」的識別碼(AdSense ca-pub-、analytics ID、ads.txt 帳號 ID)與存在是為了「承載流量」的基礎設施(cert、IP、ASN),都帶高輪替 OPSEC 成本——新 AdSense 帳號要重新審核、新 cert 會在 CT 留下新的追查切入點、把追蹤拆到多帳號會打爛操作者自己的營收與分析。威脅情報實務一再指出:操作多半不是被異國檢測手法揭穿,而是被識別碼/基礎設施重用與被忽略的 metadata 揭穿 [34]。
這就是 kwara ad_tracking_platforms() 的 signal_source 設計動機。它對每個平台同時看 URL 參數證據與 HTML pixel 證據,落出四種狀態,而 both 必須要求 URL+HTML 在同一個 ua_id 或 domain 上交集——這是「兩種訊號都有」與「兩種訊號交叉確認」的分水嶺,是必須保留的契約。把前者誤標成後者,就是 UI 對分析師說謊。
UA-XXXXXXX-X 中段帳號號碼可直接聚類;GA4 的 G- 與 GTM 缺少揭露擁有者的後綴,且較少被編目,逼研究者轉向 Wayback 歷史資料與其他訊號 [21]。capture_status='ok' 且非空),而非「最新一張」——否則一次 Cloudflare challenge 失敗的重截圖會無聲蓋掉先前的好證據。適用 shared_tracking_ids、ad_tracking_platforms、shared_endpoints。把前十一節收束成一句:kwara 的價值不在任何單一訊號,而在於把廣告生態裡彼此獨立的「黏性」痕跡,疊起來、交叉確認、再打包成不需信任工具或分析師就能重現的證據。任何一個取樣點——一支 pixel ID、一條 ads.txt DIRECT 行、一張憑證——別的工具都查得到;真正難以複製的,是把這六層痕跡 join 成單一案件的歸因,並同時守住「不誤指」與「可重現」兩條線。
both 契約要求 URL 證據與 HTML pixel 證據在同一 ua_id 或 domain 上交集,才升級為「獨立確認」——這條線把「兩種訊號都有」和「兩種訊號互相佐證」分開。both 跨來源交叉確認、頻率加權與信心標注、最後打包成可重現的證據封包。| 面向 | kwara | 反查工具 SpyOnWeb/reverse-analytics | 廣告反詐供應商 DoubleVerify/HUMAN/Adalytics | 學術爬蟲 OpenWPM/AdSparency |
|---|---|---|---|---|
| 訊號覆蓋 | 全層:URL/pixel/ads.txt/HAR/憑證/header/cloaking | 多為單一(GA/AdSense ID 反查) | 供應鏈與品牌安全為主 | 視研究而定,多為單一面向 |
| 跨來源交叉確認 | 有(both 契約) | 無 | 部分(內部、不外露) | 視研究 |
| 主動規避意圖 cloaking/OPSEC | 有 | 無 | 部分(以偵測為主) | 少數研究 |
| 偽陽性防護 | 有(頻率加權+假旗警示) | 弱 | 商業黑箱 | 視研究 |
| 逐案可重現證據封包 | 有(可重現 ZIP) | 無 | 商業報告,不可逐案重現 | 論文資料集,非案件導向 |
| 設計導向 | 單一案件歸因、可上呈 | 提供線索 | 產業規模商業偵測 | 學術量測 |
tmax 約束、約 100 毫秒完成。[9]本研究的廣告產業側由 randomfindings deep-research 工具四路平行蒐集(供應鏈角色/IAB 標準/追蹤 pixel/鑑識前例),下列為去重後的合併清單;kwara 側事實引自工作區內 docs/analysis-design.md 與 adstxt.py、param_attribution.py、fingerprints.py 等程式碼,不另列。
編按:兩份 IAB 官方 PDF(ads.txt 1.1、sellers.json final)在自動抓取時回傳二進位/解碼錯誤,逐字法律措辭以高一致性二手來源(Equativ、Index Exchange、Google Ad Manager Help)交叉佐證;如需引用原文措辭建議再核對官方 PDF。buyers.json / DemandChain(需求側對應)本輪查無權威規格頁、採用有限,未納入主文。