← 返回 Siami 首頁

16 歲駭客用一個 admin 字串 接觸到 17 兆筆 Microsoft 內部紀錄

▲ 243 💬 107
16 歲駭客用一個 admin 字串 接觸到 17 兆筆 Microsoft 內部紀錄

編按:本文綜合整理自 blog.faav.net 原文、The Register、Help Net Security 與 Tom’s Hardware,並加入 Siami 編輯部觀點與分析。

漏洞核心:一個未驗證的登入權杖

十六歲的獨立資安研究員 Faav(化名)在 2026 年 9 月 5 日凌晨,透過一個「upn: admin」的欄位,把自己偽造成 Titan 服務的本機管理員,執行了 SELECT 1,並從 Titan 的 metadata 計算出 **17,333,335,124,315 筆列(17.3 兆)**的潛在觸及範圍。Titan 是 Microsoft 內部的 analytics 服務,前端放在 Microsoft 員工 VPN 後方,但 Swagger 文件意外暴露在公開 Azure 子網域上,於是被 Faav 自製的 AI 駭客助手 Antares 掃到。

關鍵漏洞不在 Titan 本身設計得多脆弱,而是 JSON Web Token(JWT)從頭到尾沒被驗章。Titan 會比對 token 內的 tenant(租戶)、audience(受眾)、application ID(應用程式 ID)、user 等聲明欄位,每一關都會回傳不同錯誤,但從來沒有驗證最關鍵的簽章。當 Faav 把 header 改成 {"alg":"none","typ":"JWT"},整個 header.payload.signature 三段式 token 就只剩前兩段,後面以一個懸空的句點收尾。Titan 看到這個 unsigned token,照樣接受了。


攻擊路徑:十天的 AI 自動偵察,加一個凌晨的直覺

整段攻擊從 2026 年 8 月 25 日開始。Antares(同時跑 Codex 與 Claude)從 Swagger 找到 /v2/Query 端點接受原始 SQL,且只標示 Azure AD bearer 認證,於是展開為期十天的 JWT 偵察。它嘗試了租戶錯誤、受眾錯誤、應用程式白名單錯誤,最後抵達使用者查詢階段——但一直找不到 Titan 認得的使用者。

轉機發生在 9 月 5 日凌晨一點過後。Faav 結束一天的課業,親自看這個 lead,停下來思考「upn 這個欄位到底在做什麼?」一般 UPN(User Principal Name)是 email 格式,AI 一直在試各種電子郵件格式的化名;但 upn 在 Titan 後端其實是本機應用程式使用者名稱,直接對應到 admin 這個超級管理員帳號。把 token 的 upn 改成 admin,Titan 立刻把它解析成本機使用者 ID 1,並且賦予 Admin 角色,SQL 立刻跑通。

這個故事最嘲諷的地方:答案是顯而易見的 admin,但因為它「顯然不是合法 UPN」,AI 從來沒去猜過。AI 缺乏的,恰恰是對欄位語義的直覺質疑。


規模:17.3 兆筆是怎麼算出來的

Faav 從 Wayback Machine 抓回 2023 年的 Titan 登入頁與隱私頁快照,從 Superset 設定檔中挖出 56 個 routing value,逐一對線上 API 測試 SELECT 1。結果 30 個仍然有效,每個 routing value 指向一個或多個資料庫,總共解析出 24 個設定檔、17 個連線中的 analytics 資料庫、9,863 個唯一資料表。

他從 17 個 ClickHouse 資料庫的 metadata 中,分別用 system.tables.total_rows 與 system.parts 兩條路徑加總,兩個結果都指向同一個數字:

17,333,335,124,315

他說,當下凌晨兩點,他想在房間大叫,但父母已經睡了,只好盯著這個數字再算一次。

其中規模較大的子集包括:

  • 約 25,000 筆應用程式帳號與電子郵件紀錄
  • 17,990 筆員工電子郵件
  • 15,001 筆員工組織資料
  • 24,569 個 dashboard、425,891 張圖表、27,347 個資料集定義

修補時程與獎金:四天鎖定,五千美元了事

從 Faav 通報到 Microsoft Security Response Center(MSRC)到 API 被鎖死,中間只隔四天:

日期事件
09/05/26Faav 通報 MSRC,Case 144051 開案
09/06–08/26MSRC 要求停止測試、索取 IP 位址以確認無其他活動
09/09/26Titan API 端點鎖死
09/17/26頒發 5,000 美元 Bug Bounty
09/22/26與 Microsoft 開會協調揭露時程
09/22–24/26在 Microsoft 要求下重寫文章、刪段落、刪圖、改寫衝擊描述

從修補速度看,微軟的反應其實不算慢——四天就讓端點下線。但獎金額度與漏洞嚴重性的落差,才是這次事件最具爭議的部分。


為什麼這件事重要

這次揭露的意義不只在「17.3 兆」這個震撼數字,而在於它示範了三個產業級問題同時在一個漏洞裡爆發:

第一,JWT 的 alg: none 攻擊已經是 2015 年的老問題。當年各家函式庫緊急修補,現在仍有像 Titan 這種內部服務忽視規格細節,只驗欄位不驗簽章。微軟內部其實有一套 MISE(Microsoft Identity Service Essentials)函式庫可以避免這類問題,但根據 HN 留言中的微軟前員工說法,這個團隊「刻意延後了合規警報」。這代表 Secure Future Initiative(SFI)的推動在內部仍有部門級的落差。

第二,AI 駭客助手的實戰能力首次被完整公開記錄。Antares 跑了十天自動化偵察、列舉子網域、逐欄位試 JWT 錯誤,最後雖然卡在「猜不到 admin」,但 Faav 接手時不必從零開始。這預示未來漏洞挖礦的進入門檻會大幅下降——一個高中生用開源工具 + API 金鑰,就能在十個工作天內摸到財星 500 大企業的內部核心系統。

第三,Bug Bounty 金額與漏洞價值的脫節。在漏洞黑市上,一個能存取 17 兆筆內部資料、繞過認證直達管理員 SQL 的後門,價格遠超 5,000 美元。微軟 MSRC 自己的獎金上限是 10 萬美元,但本案顯然沒拿到這個級距。這引發一個產業級疑問:當合法獎勵遠低於黑市價格時,研究者是否仍願意走白帽揭露?


數據解讀與質疑

「17.3 兆筆」這個數字需要被嚴格檢視。Faav 自己也在文中承認,這是「metadata 估算值」,很可能包含歷史複本與衍生資料,並非實際可下載的客戶資料量。實際敏感資料集中在三類:25,000 筆應用程式帳號、17,990 筆員工郵件、15,001 筆員工組織資料。這些才是真正的攻擊面——足以用於社交工程或內部魚叉式釣魚,但離「17 兆筆客戶資料外洩」還有一大段距離。

另外值得質疑的是 Microsoft 對原文的編輯介入。Faav 在文章開頭明確寫道「Microsoft 對本文擁有編輯權,刪掉部分段落與圖表,並改寫衝擊描述」。這種作法在 CVE 揭露圈並非常態,會讓讀者懷疑文章最後呈現的「衝擊範圍」是否已經被 Microsoft 刻意淡化。微軟此舉或許出於減少對客戶的恐慌,但對獨立研究者的敘事權是一種侵害。

最後,獎金額度的選擇邏輯值得追問。微軟的 MSRC 獎金表有明確分級,根據嚴重性從數百美元到 10 萬美元不等。本案觸及內部最高權限等級、可執行任意 SQL、影響範圍橫跨 17 個資料庫,最終只頒 5,000 美元——這個數字落在「高嚴重性」級距的中段,但遠不及最高級距。外界解讀可能是:微軟傾向以「未實際外洩客戶資料」為由降低獎金,但這忽略了漏洞本身的潛在破壞力。


給開發者的提醒

Faav 在文末留下一句話,值得所有後端工程師與 AI 程式代理人記住:

任何認證檢查,最重要的就是驗章。Titan 的「多層驗證」邏輯就像一間旅館,每道門都有讀卡機,但任何一張卡都能打開任何一間房——只要其中一個環節沒驗章,所有其他防護都形同虛設。

這不只是 Titan 的問題,這是整個產業對 JWT 規格「寬鬆實作」的老毛病。在 AI 代理人開始大量生成認證程式碼的今天,這個教訓尤其重要:模型會寫出看起來完整的 verify_token 函式,但很容易漏掉簽章驗證這個最關鍵的呼叫。

網友熱門留言 (5)

#1 john_strinlai (Hacker News) 0
Microsoft 完全掌握了這篇文章的編輯權——刪段落、刪圖、改寫衝擊描述。這是對未成年研究者的施壓,讓他交出揭露內容的完全控制權,這種行為很可恥。
#2 sdfhbdf (Hacker News) 0
17 兆筆資料、員工個資都攤在陽光下,微軟只給 5,000 美元。MSRC 上看是 10 萬美元,這個數字真的太低了。
#3 rdtsc (Hacker News) 0
JWT 規格居然把 alg: none 放進去、還被各家函式庫採用,這件事本身就是個長久以來的災難。
#4 er0k (Hacker News) 0
每次看到 JWT 出事都不意外——howmanydayssinceajwtalgnonevuln.com 那個計時網站就是最好的註腳。
#5 throwaway2037 (Hacker News) 0
這個漏洞是一名 16 歲少年找到的。微軟安全團隊要不要解釋一下?