← 回到 nvnda.dev EN
閱讀時間 12 分鐘

我更新了 LinkedIn,兩天後就有人冒充我們 CEO

釣魚信是怎麼找上你的,以及怎麼在它得逞之前認出它。

加入 Cymetrics 滿一個月了,我想我不會忘記頭幾週有多溫暖。新人會收到共同創辦人的歡迎訊息,本來就認識的人跑來打招呼,團隊一起出去吃飯,還有一場正式的新人歡迎會。不知不覺,我已經坐在每週的 sync 會議裡,也排好了 one-on-one 來聊我的成長跟發展方向。這裡的溝通透明到很少見,不同層級之間是真的很開放。

第一週安頓下來之後,我決定把轉職的消息公開。3 月 7 日那個週末,我更新了 LinkedIn。沒有發公告,只是改了經歷欄位:職稱、公司名稱、到職月份,就這樣。然後我就去享受剩下的週末了。

3 月 9 日,星期一早上。我正在準備出門上班,手機跳出一則 Gmail 通知。寄件人是我們公司的 CEO。

Hi Michelle,有空的時候我想跟妳聊一下。Best regards,

我不會假裝看到的那一刻沒有很興奮。加入 Cymetrics 之前,我做過不少功課,研究過這個組織跟裡面的人,其中很多都是我真心景仰的對象。所以在通知裡看到我們 CEO 的名字,對我來說是有意義的,尤其我們都有 Women in Tech 的背景。

這份興奮大概只維持了零點幾秒。

這封信寄到的是我的私人 Gmail,不是公司信箱。沒有說明為什麼想聊、沒有時間,署名也不完整,只有一個「Best regards,」孤零零掛在最後。主旨就只有「Michelle」。而且如果她真的有急事,內部有更快的方式可以找到我。有哪裡怪怪的。

我點開信,馬上就看到寄件地址:ochatbox267@gmail.com。顯示名稱:我們的 CEO。實際寄件者:一個用完即丟的 Gmail 帳號。

那零點幾秒的懷疑,來自我注意到的四件事:

警訊要看什麼實際例子
寄件地址 vs 顯示名稱Email 地址真的跟它聲稱的身分對得上嗎?顯示「Michelle Ip」,卻是從 ochatbox267@gmail.com 寄出
寄錯信箱應該寄到公司信箱的信,卻跑到私人信箱?寄到 Gmail,不是我的公司 Outlook
沒有脈絡訊息模糊,沒有細節、沒有時間、沒有理由?「我想跟妳聊一下」——沒有主題,也沒提議時間
管道不對這個人平常會用這種方式聯絡你嗎?她大可以直接傳 Teams 訊息

因為這件事發生在我更新 LinkedIn 之後沒多久,我決定深入挖一下。下一段會比較技術一點,我會帶你走一遍背後大概發生了什麼事,以及攻擊流程(attack pipeline)裡的不同步驟,怎麼造成你在釣魚信裡看到的不同結果。最後,我會講怎麼自己認出這些信。

讀出字裡行間(還有 Header)

我在資安業工作,所以自然不可能直接刪掉就算了。我打開原始郵件,開始東翻西找。第一件檢查的事,是這封信有沒有通過 Gmail 內建的安全過濾,也就是專門用來抓偽造跟詐騙郵件的三道檢查。你可以把它們想成你的信箱讓每封進來的信都要經過的警衛。

三個全部通過:SPF、DKIM 跟 DMARC。

SPF、DKIM 和 DMARC 全部通過

SPF、DKIM 和 DMARC 是什麼?

SPF、DKIM 和 DMARC 是 email 安全三人組,任務是保護你的網域不被偽冒(spoofing)、釣魚跟詐騙。

  • SPF(Sender Policy Framework): 一筆 DNS 紀錄,列出所有被授權代表你的網域寄信的伺服器位址。
  • DKIM(DomainKeys Identified Mail): 附在 email header 裡的數位簽章,用來證明信件在傳送途中沒被竄改。
  • DMARC(Domain-based Message Authentication, Reporting & Conformance): 讀取 SPF 跟 DKIM 的結果,並執行一個政策:放行、隔離或拒收。

把寄 email 想成透過快遞送包裹。

用快遞來比喻 SPF、DKIM 和 DMARC

接著我看了 Received header 來追這封信的路徑。發信伺服器是 mail-sor-f41.google.com,Google 自己的外寄郵件伺服器之一。這封信是貨真價實從 Google 的基礎設施寄出來的。

Received header 顯示 Google 的郵件伺服器

那這封詐騙信到底為什麼會進到我的收件匣?

因為 ochatbox267@gmail.com 是一個真的 Gmail 帳號,從真的 Google 伺服器寄出(SPF 通過),帶著真的簽章(DKIM 通過),而且 Google 的政策允許它(DMARC 通過)。

快遞的比喻老實說有一個漏洞:這三道檢查都不管顯示名稱。任何人都可以把自己的 Gmail 顯示名稱設成任何東西,而這部分完全沒有人把關。

為了讓你對照看看比較粗糙的攻擊長什麼樣子,這是另一封落在我垃圾郵件匣的信。

被垃圾郵件過濾器抓到的粗糙釣魚信

垃圾郵件過濾器抓到了這封。但注意它花了多少:超過五個獨立的訊號才觸發警示,而且就算這樣也沒有被擋下,只是被分類。對照那封冒充 CEO 的信:沒有可疑連結、沒有驗證失敗、沒有明顯破綻。下面是兩封的並排比較:

訊號我收到的釣魚信Pleximus 垃圾信
發信伺服器Google 自己的伺服器便宜的 VPS(contaboserver.net)
SPF通過通過——但是自己認證自己
DKIM通過——合法通過——「剛產生,假設沒問題」
DMARC通過沒有設定
垃圾郵件分數沒有被標記3.481——偽造的 reply-to、金錢相關關鍵字
Reply-to跟寄件者一致偽造——另一個不同的 Outlook 地址
發信 IPGoogle(合法)非洲——跟伺服器時區對不上
結論乾乾淨淨進到收件匣——沒東西可抓很粗糙——破綻一堆

Scraper 是怎麼找到我的

前面提到,這封信在我更新 LinkedIn 兩天後就寄到我信箱,這件事很耐人尋味。補充一下背景:在這之前我沒有公開過轉職的消息,只告訴了朋友跟有問起的人,所以合理推斷 bot 是從 LinkedIn 拿到我的資訊。

追查下去,我開始玩一種叫 LinkedIn scraper bot(爬蟲機器人)的東西。Scraper bot 被業務、行銷跟招募團隊廣泛用在開發潛在客戶、市場研究、招募流程跟人才分析上。很不幸地,它們也被拿來做針對性的社交工程攻擊。下面是我認為被用在我身上的攻擊鏈:

從更新 LinkedIn 到收到釣魚信的攻擊流程

為了示範每個步驟怎麼運作,我用了一個叫 Apify 的工具。

市面上有很多 scraper,免費的、付費的都有,而且你不需要很懂技術就能用。有 AI 幫忙的話,你甚至可以自己寫一個。Apify 是一個雲端平台,做網頁爬取、資料擷取跟瀏覽器自動化。它跑的是他們稱為 actor 的工具,也就是為了完成特定任務而打造的 agent,由全球的開發者社群開發。功能跟價格各不相同,你可以挑適合自己需求的,或自己做一個。

Apify Store 上可用的 actor

光是 LinkedIn 相關的,截至我寫這篇的日子(3 月 23 日)就有 1,751 個 actor。跟這個故事最相關的兩個是:LinkedIn Profile Scraper 跟 LinkedIn Company Employee Scraper。

步驟 1:找到目標

工具:LinkedIn Profile Scraper

第一個 actor 負責鎖定受害者。它只需要你的 LinkedIn session cookie,以及你想爬的個人檔案網址。

Session cookie 是什麼?為什麼需要它?

Session cookie 是瀏覽器存起來讓你保持登入狀態的暫時性 token。就是因為有它,你關掉分頁再回來時不用重新輸入密碼。Scraper 需要它,是因為它必須假扮成你。它代替你登入 LinkedIn,像真人一樣瀏覽個人檔案,然後把資料抓下來。沒有有效的 session cookie,LinkedIn 只會看到一個匿名請求,然後擋掉它。

這也是為什麼你絕對不該把自己的 cookie 分享出去。Session cookie 在功能上等同於把密碼交給別人。拿到它的人在 session 過期之前都能存取你的帳號。

貼上 cookie 之後(從瀏覽器匯出只要點幾下),列出你想爬的個人檔案,設定 user agent 跟等待時間,再決定要不要順便抓公司檔案跟 email 地址。然後按下開始,等著就好。

爬 6 個 LinkedIn 個人檔案花了我大約 3 分鐘,成本是 US$0.032。它回傳的資料完整到令人害怕。我拿自己的檔案跟另外五個知名人士的檔案去跑,拿回來的有全名、雇主、職稱、職級、地理位置、email 地址,甚至還有電話號碼。

Scraper 結果顯示完整的個人檔案資料

Scraper 的 JSON 輸出,包含電話號碼和地址

拜託不要拿這個去狂打電話給你的偶像 :D

步驟 2:找到要冒充的人

工具:LinkedIn Company Employee Scraper

鎖定潛在受害者之後,下一步是找一個人來冒充。這個 actor 會爬一家公司的 LinkedIn 頁面,回傳員工清單,可以依職位跟職級篩選。我設得很簡單:只要 Co-founder 跟 CEO。

Employee scraper 設定

大約 30 秒後,它就準確又整齊地回傳了我們組織的領導層。

Employee scraper 執行紀錄

Employee scraper 結果

Michelle Ip 的名字。跟出現在我收件匣裡的一模一樣。只需要兩個工具、US$0.032、幾分鐘,加上一點公開資訊。做出那封信,就只需要這些。

從這件事可以帶走什麼

用不只一個 email 帳號

從上面的故事來看,我之所以馬上察覺不對勁,是因為這封信寄到了我的私人信箱,而不是公司信箱。我會依照不同用途使用多個帳號:一個公開的 email 用來跟人聯繫,一個用在網購跟電子報,還有一個不公開的,專門處理銀行跟報稅這類敏感的事。收件匣分開,可疑訊息就更容易被看出來。

檢查寄件地址,不要只看顯示名稱

我們已經看到了,任何人都可以把顯示名稱設成任何東西。只要寄件網域通過驗證、信件沒被竄改,釣魚信就有相當的機會進到你的收件匣。如果覺得哪裡怪怪的,就去檢查實際的寄件地址。你讀到這裡,已經有一份 checklist 了——往上捲回那張比較表就好。Microsoft 也有一份很實用的釣魚信辨識指南。

小心分享資訊,並掌握哪些是公開的

活在數位時代,很容易分享過頭。但這不是藉口,反而是要更刻意去決定自己放出去什麼的理由。

我會特別小心的資訊分成三類:

在對的情境下、跟對的人分享,這些都是再正常不過的話題。但公開放出去就是另一回事了。一塊一塊拼起來,它們會給攻擊者聽起來很可信所需的一切。

以研討會為例。我自己也會發文分享,這是經營個人曝光跟建立人脈的一部分。但「宣布你會去某場活動」跟「廣播你住哪間飯店、你的即時位置跟完整行程」是兩回事。老實說,如果你有特別想見的人,直接私訊效果反而更好。雜訊更少、重點更多,也不會變成要同時跟十個人喬時間。

我會跟朋友說的事

養成定期檢查的習慣

我每天清收件匣,看到可疑的東西就當場封鎖。每個月我會坐下來看一次財務紀錄。這要花一兩個小時,但它是那種會默默回本的習慣。如果你把 AI 工具加進流程,花的時間會比你想的還少。Harvard Online 整理了一份很完整的 checklist,值得加進書籤,而且真的照著跑一遍。

用同樣的方式檢查你的帳密

以前每次公司 IT 提醒我每三個月要換一次密碼,我都覺得很煩。道理很簡單:如果你的密碼在某個地方悄悄外洩了,定期更換可以縮短它對拿到的人有用的時間。但定期更換代表要一直想新密碼,而在不同帳號之間記住不同的密碼,很快就會讓人吃不消。

我個人很愛用 Bitwarden。它把你所有的登入帳密放在同一個地方,用一組 master password(主密碼)鎖起來,讓你每個帳號都可以用不同密碼,又不用花腦力全部記住。對,這就是把雞蛋都放在同一個籃子裡。但到處重複使用同一組密碼,代表一次外洩就能解鎖所有東西。一組夠強的 master password,加上用完就關掉 app 的習慣,就能有很大的幫助。

有一件事值得檢查:我的 Bitwarden 原本設定成「On restart」才鎖定,意思是只要我沒重開機,它就整天開著。到 Settings 裡確認你的 vault timeout 設成合理的選項,像是「On system sleep」或一段短的時間。順便把「Automatically clear copied values from clipboard」設短一點,30 秒就夠了。


釣魚不是什麼新鮮事。讓我措手不及的不是這次嘗試本身,而是它找到我的速度,以及整個流程有多順。網路上到處都是 bot 在跑我描述的這套東西:有耐心、自動化,而且便宜得驚人。好消息是,破綻都在那裡,只要你知道去哪裡找。

希望這篇能幫你找到它們。謝謝你讀到這裡,保持警覺。