Bromure 如何在釣魚攻擊找上你父母之前就攔下它
逐步拆解 Bromure 的反釣魚機制——本機掃查、模型判定、最終提示,以及我們為什麼就是為你的父母、你的祖父母、以及走廊對面那位鄰居打造這項功能。
你的父母不需要再多聽一場「點連結要小心」的訓誡。他們需要的是一款能看見眼前陷阱的瀏覽器——並且在來得及的時候,用他們聽得懂的話,說出那句提醒。
你們之中有些人已經接過那通電話。電話那頭,母親的聲音又輕又小,她說:我好像在電腦上做錯了什麼事。你們之中有些人正在等那通電話。這篇文章的用意,是詳細說明我們打造的整套機制,好讓那通電話發生的次數少一點——而真的發生時,損害也能止於一次警示,而不是一個被掏空的帳戶。
攻擊產業一直在獵捕長輩。
釣魚從來不是聰明人的遊戲,它是一場機率遊戲:一條工業化的產線,每天批量產出上千個假登入頁、冒用熟悉品牌、寫出聽起來萬分緊急的訊息,然後透過電子郵件、簡訊、社群網路、電話四處散佈。攻擊者只需要有一個人,在某一天,在某個分心的瞬間,把密碼輸進錯誤的框框裡。祖父母、父母、喪偶的鄰居,以及任何一個從小就相信銀行寄來的紙本信件的人——他們不是反應慢,他們是信任別人。攻擊者心知肚明,並且有計畫地鎖定他們。
端給祖父母的資安建議,向來都是「再小心一點」的各種變體。檢查網址。滑鼠懸停看連結。別信任寄件者。問題不在於祖父母粗心大意,問題在於攻擊產業雇用了一整批全職專業人士,他們的工作就是擊穿「再小心一點」這道防線。防守方與進攻方之間的差距,到了今天,已經令人難堪。
我們做了什麼,概觀一下。
當網頁在 Bromure 裡載入時,一個小小的檢查器會在封閉的瀏覽器 VM 內部跟著啟動。它像站在門口一位多疑的引導員那樣盯著這個頁面——看網址、看表單、看可見的文字、看連結、看任何 QR 碼,甚至看這個頁面偷偷試圖往剪貼簿寫的東西。只要哪裡不對勁,檢查器收集到的線索就會透過一條隔離通道送到模型那邊。模型讀過這些訊號、做出判定、寫下一句話的說明,然後回傳回來。Bromure 會把判定以橫幅的形式直接渲染在頁面上。如果是徹頭徹尾的釣魚頁面,它還沒騙到任何人之前,就會被導向一個封鎖警示頁。
這篇文章剩下的部分,就是怎麼做的細節。它是刻意寫得很詳細。如果你父母就是你讀這篇文章的原因,你大可以直接跳到 你的資料到底去了哪裡 那一節——而簡短的答案就是:這項功能預設關閉、會徵求你的同意,而且它做的每一件事都記錄在下面。
第一步——本機掃查。
在任何資料離開你的電腦之前,一段內容指令稿會先在 guest VM 內執行。它會分幾個各自獨立的回合檢視頁面。每一回合的成本都不高,全部都在瀏覽器裡、在你自己的電腦裡、在和這個頁面相同的封閉沙箱裡完成。
密碼欄位,一出現就被盯上
只要一個 <input type="password"> 被掛到 DOM 上——你甚至還沒把游標移上去——檢查器就已經記下這個網域,並標記你以前在這裡是否輸入過密碼。第一次在一個新網域上看到?光這一點就已經是個訊號。
表單結構
只有登入框、沒有任何導覽的頁面。把資料 POST 到和網址列不同網域的表單。冒用某個品牌,但品牌 Logo 卻是從另一台主機熱連結過來的表單。單看任何一項都不夠強,但加總起來,風險天平就會傾斜。
品牌不相符
如果頁面寫著「Apple ID」,但網域並不是 Apple 的;或者 Logo 是從一台可疑的主機送來的,這種不相符都會被記下來。不需要任何網路呼叫——純粹是對頁面上已經存在的東西做模式比對。
同形字網域
像 аррӏе.com 這樣的網域——看起來和「apple.com」一模一樣,實際上卻是用西里爾字母的相似字拼出來的——幾乎篤定就是釣魚。檢查器會拿渲染後的字元與一組已知的易混字元集比對,揪出它們。
詐騙慣用語
「請確認您的密碼。」「請驗證您的帳戶。」「您已被選中。」「點此領取獎品。」每一句都是一個弱訊號。但如果一個沒人聽過的網域上,在一個登入表單裡,同時出現三句這樣的話,故事就完全不一樣了。
QR 碼與剪貼簿酬載
一個 QR 碼解碼後指向一個毫無關聯的錢包的加密貨幣付款連結。一個頁面一邊要你「按 Win+R 然後貼上」,一邊悄悄把一段 shell 指令寫進你的剪貼簿。這些都是現代攻擊手法,傳統過濾機制對它們束手無策。
本機的預先過濾也會確保檢查器不會為了大家其實不需要擔心的網站去打擾伺服器。Tranco 清單上前十萬名的網域,加上一組精選、涵蓋超過 30 家 SSO 服務供應商(Google、Microsoft、Okta、Apple 等等)的名單,只要沒有其他可疑跡象,就會被靜靜地略過。你母親真正在用的銀行、真正在用的藥局、真正在用的電子郵件服務,永遠不會被送去伺服器打聽。
如果本機掃查完全沒發現值得注意的東西,故事到這裡就結束了。沒有任何請求會離開電腦。
第二步——第二意見。
如果蒐集到的這份資料確實有意思——或者一個密碼欄位剛剛出現在一個陌生的網域上——那麼一份結構化的報告就會被送出去做評估。不是截圖,也不是整份 DOM,而是一份有明確上限、經過消毒的訊號摘要。
這份資料包包含:網址、網域、可見文字(上限約 800 個字元,並清除控制字元)、每一份表單的摘要(欄位型別、按鈕文字,以及 action URL)、偵測到的敏感欄位、頁面標題與主要標題、Logo 圖片來自哪裡、網域不相符與同形字的旗標、網址層級的紅旗(子網域內含品牌名、punycode、連字號過多)、結構性旗標(只有登入表單、密碼自動填入被停用、data-URI favicon、隱藏的 iframe)、若有解碼成功的 QR 碼的內容,以及若被偷偷寫入的剪貼簿酬載。所有字串都被截到很短的上限,所有陣列也被限制在很小的數量,控制字元一律剔除。
到了伺服器端,這份資料會交給 Claude Haiku 4.5——一款小而快的模型。系統提示詞會教這個模型把資料包裡的一切都當成不可信任的鑑識證據來對待:預設這個頁面是由某個知道這個提示詞存在、並刻意把頁面寫得讓模型混淆的人製作的。提示詞會帶著模型依序跑九項檢查(網域分析、品牌冒充、頁面結構、憑證收集、可疑連結、詐騙內容、QR 碼、剪貼簿酬載、最終綜合判斷),並要求它輸出單一一個 JSON 物件:
{
"verdict": "phishing" | "suspicious" | "safe",
"confidence": 0.0,
"reason": "一句話,用平實的語言說明"
}
這些門檻是刻意校準過的。高於 0.85,判定為 phishing,網站會被封鎖。介於 0.4 到 0.84 之間,判定為 suspicious,會顯示一道警示橫幅。低於 0.4 則是 safe,什麼都不會顯示。單一一個弱訊號——一個詐騙用詞、一個不相符的 favicon——不足以跨過門檻。我們明白地告訴模型:在你奶奶的藥局頁面上誤報一次,比放過一個平庸的詐騙還要糟。
當答案已經很明顯時,有兩條快速通道會完全跳過模型:
- 品牌不相符捷徑——如果頁面聲稱自己是 PayPal,但網域卻是
paypai-secure.xyz,伺服器會立刻回傳 suspicious,不做任何 LLM 呼叫、不產生任何成本。 - 快取命中——判定結果以
{domain, normalized path}為鍵,儲存在 memcache 裡一小時。第二次造訪同一個頁面完全不花成本,以毫秒級的速度回應。
第三步——頁面上的判定。
判定回來之後,Bromure 會把它以內嵌的方式渲染出來——就在頁面裡、在內容的上方。沒有彈出式視窗,也沒有你父母得先關掉才能看到自己要看的東西的 modal。
那句理由永遠只有一句話,是寫給看它的人看的,不是寫給除錯的人看的。橫幅上顯示的是*「這個網站正在冒充 PayPal。請勿輸入您的登入資料。」*——不是信心分數、不是訊號軌跡、也不是一串正則比對清單。目標是:你母親只要把橫幅讀過一次,就知道該怎麼做。
每一次關閉一道可疑橫幅,只會影響目前這個工作階段;如果她按下我認得這個網站,則會被升級到這個設定檔的可信任清單裡。信任這件事的決定權,是在她身上,不在模型身上。
跨網域攔截——一張不需要判定的安全網。
在任何判定回來之前,Bromure 都會嚴格執行一條硬性規則:密碼絕不會在未經確認的情況下,被送到網址列以外的網域。如果 login.bank.com 上的某個表單正要把資料 POST 到 credentials.attacker.example,這次送出就會被攔截,然後彈出一個 modal。
一份精選、涵蓋已知身分提供者的白名單——Google、Microsoft、Okta、Apple,以及其他幾十家——會讓合法的聯合登入免於被攔截。除此之外的一切,一律每次都顯示這個 modal。光是這一條規則,就能在模型都還來不及回傳判定之前,攔下相當驚人比例的憑證釣魚頁面。
你的資料到底去了哪裡。
有兩條原則在主導資料的流動路徑。第一條是同意,第二條是隔離。
同意。 這項功能在每一個新的設定檔上都是關閉的。要啟用它,使用者要打開隱私與安全,並會看到一個專屬的說明視窗,在切換開關之前,就把所有細節寫得清清楚楚:到底送出了什麼(網址、頁面文字、表單結構、警示訊號)、送到哪裡(由 Bromure 維運、位於 bromure.io 的伺服器)、保留多久(短期日誌,用於防濫用與模型改進)、以及怎麼關掉。這項功能只在持久性的設定檔上才可用——不會出現在用完即丟的臨時工作階段裡——以免一次匿名的研究工作階段不小心把資料送到伺服器。如果你把 Bromure 裝在祖母的 Mac 上、並替她開啟這項功能,她看到的橫幅就是一項證明:這是由她信任的人,代為做出的一個明確的決定。
隔離。 瀏覽器並未直接連上網際網路,檢查器也一樣。所有的線索都會透過一條 vsock 通道,從 guest VM 傳到主機上,走的是一個內部連接埠——不是網頁看得見的那張網路介面,也不是任何網頁可以影響的代理。主機會把這個請求轉送到 API、收到判定,再交回給檢查器。世界上沒有任何網頁能碰到這條 vsock 橋接通道,沒有任何網頁能直接碰到主機,甚至沒有任何網頁能知道這條橋接通道存在。
被檢查的那個頁面的網址確實會在伺服器上短暫記錄,用於防濫用。可見的文字會送到模型做分析,回應結束後就不再保留。你在表單裡輸入的任何東西,都不會出現在那份資料包裡。如果你把這項功能關掉,任何一點資料都不會被送出去。
在你已經熟悉的頁面上,速度要快。
每次頁面載入都呼叫一次語言模型,會讓瀏覽器感覺很笨重。Bromure 非常積極地快取判定結果,讓網路上那些最熱門的頁面在第一次造訪之後,判定成本幾乎為零——而如果伺服器真的連不上,本機掃查也會繼續把自己的工作做好。
先查快取,最後才動模型
判定結果以 {domain, normalized path} 為鍵,快取一小時。第二次造訪同一個頁面,會在毫秒之內回應,完全不動用模型。品牌不相符捷徑則是完全跳過模型。
本機掃查是最低保障
如果伺服器連不上或反應太慢,本機掃查會繼續跑。那些最明顯的情況的橫幅——跨網域的密碼、同形字網域、剪貼簿酬載——完全在你的電腦裡就能產生,不需要網路。
兌現承諾。
我們在第一篇文章裡說過,防禦應該是一雙永遠不會眨的第二雙眼睛。這就是這雙眼睛在 Bromure 裡,此刻,實際上在做的事。
你母親不該為了讀新聞而先通過一份資安考題。你父親不該非得知道什麼叫同形字。你祖父不該因為電話那頭一個客氣的聲音叫他裝某個東西,就覺得自己笨。瀏覽器該看見陷阱,並且在來得及的時候,用一句話——不是用專業術語——把它說出來,在密碼離開鍵盤之前。
這就是 Bromure 反釣魚功能存在的目的。這就是為什麼它預設關閉、在啟用前就已經寫好文件、和頁面之間是隔離的,而且能以低廉的成本大規模運作。把它裝上你父母的 Mac。帶他們走一遍隱私與安全面板。替他們把這項功能開起來。然後,一起去吃頓飯吧。