深藏青色背景上的抽象技術插圖:左側一個緊湊的伺服器立方體向右側的代理節點發出三張小型矩形卡片;前兩張蒼白且靜止,第三張投下形似鑰匙的長影。細緻的青色細絲從伺服器延伸至其後方鬆散排列的儲存庫節點網格,一條琥珀色線則將代理節點連接至一小串憑證圓盤鑰匙圈。沒有人物、沒有標誌、沒有文字。OrcaRouter 標誌合成於右下角。
AI Safety Incidents

Deadbugz:一個在第三次工具呼叫時轉為敵意的 MCP 伺服器,在 74 分鐘內被推送至 23 個儲存庫

作者

Magnus Corvin

發佈日期

最新模型 · 20查看全部模型 →
基準測試:Artificial Analysis · 每日更新
返回全部文章

2026 年 8 月 10 日,一個 GitHub 帳號 zellkernel,在 74 分鐘內對無關的 AI、MCP 與開發者工具儲存庫開啟了 23 個拉取請求,每個都新增一個名為 productivity-suite 的 MCP 伺服器,該伺服器宣傳兩個普通工具:format_text 與 summarize。根據 Pillar Security 的說法,該機構將這起行動命名為 Deadbugz,並於 8 月 12 日發表報告;該伺服器在前三次呼叫中回傳誠實的結果,隨後改寫它交給代理程式的中繼資料:工具描述與提示內容開始引導模型轉向 SSH 金鑰、AWS 憑證、shell 歷史紀錄與 Kubernetes 設定,並告訴它要對使用者隱瞞這項活動。在 Pillar 審查這些請求時,23 個拉取請求中有 19 個已關閉、4 個仍開啟,且沒有任何一個已合併。尚未確認任何受害者。 這是一筆紀錄,由他人報導,並在此引用他們。其他已記錄的代理事件,各自有其來源、嚴重程度、信心等級與爭議標記,收錄於 AI 事件檔案庫——因此,針對代理工具的供應鏈行動,可以與其餘實際發生的事件並列閱讀。

檔案將這份紀錄評為高嚴重性與 A 級信心——紀錄完善,且一手來源彼此一致——同時另行記載未確認任何實際傷害。這兩件事同時成立,而兩者之間的落差正是這份紀錄的重點:一場行動,其設計在出現任何可指名受害者之前,便以異常詳盡的方式被記錄下來。關鍵的兩個日期相隔兩天。這些拉取請求於 8 月 10 日發出;Pillar Security 的 Ariel Fogel 於 8 月 12 日發表分析,而該文章附有一則固定註記,表示會在已驗證資訊送達時更新。

三次呼叫後,中繼資料就會變更。

MCP 伺服器不必在機器上執行程式碼,就能改變代理程式的行為。工具定義在每次工作階段都會作為上下文交給模型,這表示提供這些定義的伺服器可以改寫代理程式所讀取的指示,同時讓工具的名稱、其儲存庫與其清單檔維持原樣。Deadbugz 正是建立在這種不對稱之上,而 Pillar 對它的稱呼是「執行階段閘控的 MCP 中繼資料投毒」。

這套機制簡單到可以用一句話說明。伺服器會針對每個用戶端,在記憶體中保留 tools/call 請求的計數器。前三次它會正常運作。一旦計數器被觸發,之後的 tools/list 與 prompts/get 回應就會被篡改——不同的工具描述、不同的提示內容——引導代理指向 SSH 金鑰、AWS 憑證、shell 歷史紀錄和 Kubernetes 設定,並指示它向使用者隱藏這項活動。被投毒的提示文字帶有標記 deadbugz 和一個比特幣地址。

閘門也是一般防禦措施無法偵測到它的原因。酬載從第一次請求起就已存在於原始碼中;在切換的那一刻,程式碼或設定都沒有任何改變。靜態掃描、SBOM 條目,或安裝時一次性讀取工具資訊清單,看到的都是格式化工具,因為在計數器變動之前,該工具回傳的就是這個。Pillar 將這種延遲切換描述為一種規避研究的手法,並表示其研究人員透過向運作中的遠端服務傳送純文字請求,並將回應與公開原始碼比對,證實了閾值與遭變更的中繼資料。

有一個細節讓這個陷阱的影響範圍超出單一工作階段。伺服器會公告 tools.listChanged,這是 MCP 的一項能力,會告知用戶端其工具清單已被修訂。會遵循該訊號的用戶端,會在工作階段進行中重新讀取定義,並在操作人員未採取任何動作的情況下取得遭汙染的版本;而在核准時快取定義的用戶端則不會。特定代理程式具有哪種行為,取決於用戶端本身的性質,而非伺服器;Pillar 的報告並未逐一列出用戶端名稱。

HTML card titled 'Three calls, then the metadata changes', kicked 'MCP · productivity-suite', with the subtitle 'The payload is present from the first request; the gate is a counter in memory'. Three columns. 'Calls one to three — benign' lists format_text returning formatted text, summarize returning a summary, and tools/list and prompts/get returning honest tool definitions, with a note that nothing on disk differs from what a reviewer approved. 'The gate' lists an in-memory per-client counter of tools/call requests, a threshold of three, altered tool descriptions and prompt content in later tools/list and prompts/get responses, and the advertised tools.listChanged capability that lets compliant clients re-read definitions mid-session. 'What the poisoned metadata asks for' lists SSH keys, AWS credentials, shell history and Kubernetes configuration, an instruction to keep the activity from the user, and the embedded marker deadbugz with a Bitcoin address. A footer reads 'Per Pillar Security's disclosure of 12 August 2026. Pillar says its researchers confirmed the threshold and the altered metadata against the live remote service using text-only requests, matching the public source.'

交付:74 分鐘內完成 23 個 Pull Request

這次散布的內容,既不是套件登錄網站上的套件,也不是埋藏在鎖定檔裡的遭汙染相依套件。它是針對那些與該伺服器所謂功能毫無關係的專案所發動的拉取請求垃圾訊息,而這正是攻擊者拿不到維護者帳號時,低成本供應鏈攻擊嘗試會呈現的樣貌:送出足夠多的設定變更,然後等待其中一筆被合併或在本地端套用。

Pillar 對這 23 個對象的拆解分為三類。其中十七個新增了遠端 MCP 端點,productivity-suite-mcp[.]onrender[.]com/mcp,託管於 Render;四個則呼叫位於 ~/.config/.cache/.sys/.deadbug-mcp.py 的隱藏本機 Python 檔案;兩個屬於目錄或清單提交,報告將其視為偵察或填充內容,而非實際交付。時間窗口標示為 2026 年 8 月 10 日 UTC 晚上 9:52 至 11:07——以披露文件的說法為 74 分鐘,儘管這兩個時間戳本身相隔 75 分鐘,而紀錄中沒有任何內容取決於那一分鐘。僅有一個目標儲存庫被單獨點名:getsentry/sentry-mcp,pull request #1239,被引為本機產物交付方式的例子。

其背後的帳號就帳齡而言規模相當可觀。在 Pillar 進行收集時,zellkernel 有 50 個公開儲存庫,其中 20 個是分叉,而這 50 個中有 21 個是在 8 月 10 日建立,與該活動同一天。該個人檔案與 X 帳號 @llmgod 相互連結,而該帳號又連回這個 GitHub 帳號;這種相互連結顯示這是專為特定目的打造的身分,而非遭劫持的身分。

「十九個已關閉、四個仍開啟、零個已合併」是紀錄中重複出現最多次的數字,也是最常被解讀為一切無虞的數字,但實際並不盡然。GitHub 的合併按鈕並不是主機的執行紀錄:維護者可以拉取分支並執行它、手動套用設定,或者由 CI 工作在任何人留言之前取得 PR 的 head。那四個 pull request 所撰寫的設定會叫用本機腳本路徑,而這正是這個落差最要緊的地方,因為該腳本的取得與執行完全不在 GitHub 的合併核算範圍內。Cloud Security Alliance Labs 在 9 月 2 日的說明中也提出相同觀點:已關閉與未合併的計數不能證明什麼都沒執行過。

HTML card titled 'Twenty-three pull requests in seventy-four minutes', kicked '10 August 2026 · delivery', subtitled 'Times UTC. Counts are Pillar Security's review snapshot.' Three columns. 'The window' lists the first pull request at 21:52, twenty-three pull requests to unrelated AI, MCP and developer-tooling repositories, the last at 23:07, and a note that the 74-minute framing spans 75 minutes on the clock. 'What each pull request added' lists seventeen adding the remote endpoint productivity-suite-mcp.onrender.com/mcp, four invoking the hidden file at ~/.config/.cache/.sys/.deadbug-mcp.py, two directory or listing submissions, and one named example, getsentry/sentry-mcp pull request 1239. 'At review' lists nineteen closed, four open, zero merged through GitHub's review, zero confirmed victims, and the account zellkernel linked to the X handle llmgod, with fifty public repositories and twenty-one created that day. A footer reads 'Per Pillar Security. Cloud Security Alliance Labs repeated the same figures on 30 August and 2 September 2026 without independent verification. As of 29 October 2026 the GitHub account and the productivity-suite-mcp repository both return 404.'

什麼是已經確立的,什麼不是

這些是由該揭露內容所確立的——之所以這麼說,是因為 Pillar 是從它讀取過的產物中加以報導,其中一項則是從它查詢過的服務得知:伺服器及其原始碼儲存庫、所宣傳的兩項工具、計數器與三次呼叫的門檻、四個憑證目標、PR 數量及其審查時的合併狀態,以及該 GitHub 帳號與 X 帳號代稱之間的連結。Pillar 針對實際運行端點自行所做的測試,是這份清單上最有力的一項,因為那是實際重現,而非閱讀原始碼。

尚未確立,而紀錄對此相當謹慎:受害者。檔案庫的 real_harm 欄位為 false,這是關於證據的陳述,而非關於意圖——沒有人提出與此活動相關的主機、日誌或遭竊憑證。zellkernel 與 @llmgod 背後的人或團體也未被查明;Pillar 將該行動歸因於這些帳號,便止步於此。財務動機仰賴內嵌於酬載中的比特幣地址,這是從指標推論而來,並非關於行為者的認定。而防禦者最想獲得解答的問題——該活動是否仍在進行——在紀錄中沒有答案:該貼文被標記為將會更新,且看不到 GitHub 或 Render 之後的修訂或下架通知。

佐證比信心等級所可能暗示的更薄弱,而這一點值得直白說明。兩份Cloud Security Alliance Labs的研究筆記,日期分別為 2026 年 8 月 30 日與 9 月 2 日,重述了該活動;較晚的那份明確表示,它將發現、公關細節、伺服器行為與帳號歸因歸功於 Pillar,且未描述其自身的任何獨立驗證。一篇Armor部落格文章,日期為 2026 年 9 月 22 日,提供防禦指引,並稱 Pillar 拆解了該伺服器;它未提供自身的任何鑑識證據。未指派 CVE 編號,且 CSA 表示這不是 MCP 規格漏洞。截至 2026 年 10 月 29 日,搜尋未發現來自 GitHub 或 Render 的公告,也未見主流安全專業媒體的報導——沒有 BleepingComputer、The Register、SecurityWeek 或 Hackread 的報導——這對如此形態的供應鏈活動並不尋常,而這本身正是紀錄所顯示的一部分。此處的「主要來源一致」意指一個原始主要來源,以及一組衍生自該來源的次要文件。

有兩個較小的模糊之處值得指出,而不是含糊帶過。次級摘要對於第三次呼叫還是第四次呼叫才是第一個接收到遭汙染中繼資料的呼叫說法不一,這是因為計數器被描述為在第三次請求時觸發;紀錄與揭露資料兩者都採用三次。而交付時間窗口被描述為 74 分鐘,但時間戳涵蓋 75 分鐘。

有一項無法重複的檢查:2026 年 10 月 29 日,GitHub 帳號 zellkernel 與儲存庫 zellkernel/productivity-suite-mcp 都回傳 404,而唯一被單獨點名的拉取請求 getsentry/sentry-mcp #1239 也已無法解析——該儲存庫本身現在重新導向至 getsentry/toolkit。因此,PR 數量、合併狀態與儲存庫內容今天都無法由第一方重新驗證;它們仍是 Pillar 於八月中旬取得的快照。

HTML card titled 'What is established, and what is not', kicked '2026-08-10-deadbugz-mcp-supply-chain', subtitled 'One record, one originating source, two secondary notes that restate it'. Three columns. 'Established by the disclosure' lists the server, its source repository and the two advertised tools; the counter and the three-call threshold, confirmed against the live endpoint; the four credential targets; twenty-three pull requests, nineteen closed, four open, none merged; and the delivery account linked to the X handle llmgod. 'Not established' lists any victim or executed payload, with the archive recording real harm as false; the actor behind the account and handle; motive, which rests on a Bitcoin address in the payload; and whether the campaign is still running, the post having promised updates that are not visible. 'Corroboration' lists the Cloud Security Alliance Labs notes of 30 August and 2 September 2026 as restatement without independent checks; the Armor blog of 22 September 2026 as guidance without forensic evidence; no CVE assigned; no GitHub or Render advisory found; and no mainstream trade-press coverage found as of 29 October 2026. A footer reads 'The archive grades the record A, well documented with primary sources that agree. The secondary documents here all derive from Pillar Security's post, so agreement between them is not a second measurement.'

該披露要求防禦者做什麼

Pillar 建議的應對措施主要是在把中繼資料視為一種安全表面,而不是對它的描述。對主機而言,具體要求是封鎖或追查 productivity-suite-mcp[.]onrender[.]com/mcp,將本次行動較早的 trycloudflare.com 端點保留在拒絕與追查清單中,即使 Pillar 表示它目前未啟用,並且不要執行 deadbug-mcp.py——隱藏檔案路徑 ~/.config/.cache/.sys/.deadbug-mcp.py 是應在家目錄、儲存庫與 MCP 用戶端設定中搜尋的構件。

調查順序比封鎖清單更重要。Pillar 表示,如果某台主機可能曾建立連線,應先保留 MCP 用戶端日誌,再清理任何東西,然後檢視工具定義重新整理,以及代理程式在第三次呼叫之後做了什麼;只有在本地證據支持確有暴露時才應輪換憑證,這與一有懷疑就輪換所有憑證的反射動作相反。該伺服器的設定也允許將選用遙測傳送至 WEBHOOK_URL,並在連線、首次呼叫與觸發事件時發出信標——這項細節讓調查除了用戶端日誌與端點流量之外,還有第三個可查看的地方。

對於打造 MCP 用戶端的人來說,這項建議是結構性的,而它是紀錄中保存期限最長的部分:

• 在核准時為工具定義建立指紋,並在每次重新整理時進行比對,而不是信任伺服器的名稱與儲存庫。

• 將已核准伺服器上的定義變更視為安全事件,讓操作員看見並重新核准,而非視為可被無聲吞下的例行中繼資料變動。

透過政策強制執行敏感操作——憑證存取、程式碼執行、外送電子郵件、儲存庫寫入——而非依賴伺服器提供的描述。

第三項正是讓 Deadbugz 成為一項紀錄、而非僅是奇聞的原因。上述每一項控制措施都假設:代理會被伺服器附加在工具上的文字說服去做某些事,而且該文字可在信任決策作出之後變更。Pillar 將這起行動置於一條事件脈絡中,包括 Invariant Labs 的 2025 年 MCP 潛伏攻擊、偽冒的 postmark-mcp 套件,以及一個由 Koi 記錄、透過更新被武器化的 MCP 套件——這些全是該技術的先例,Pillar 引用它們正是為此,而非作為關於本次投遞的證據。

為什麼「門」比受害者人數更重要

一場有 23 次投遞嘗試、沒有合併、也沒有已確認受害者的行動,很容易被歸類為未遂並略過。它之所以應以高嚴重性歸入檔案,是因為其規避手法不依賴投遞在大規模上成功。它依賴於今日大多數 MCP 部署共有的特性:核准只在安裝時發生一次,而且被核准的定義被假定就是將被提供的定義。Deadbugz 讓該假定在前三次呼叫中保持不變,然後將其打破。

這次的修正並不是針對某一台特定伺服器打補丁,也沒有 CVE 可供追蹤。重點在於,「已核准」必須成為一種持續成立的狀態,而且背後要有實際比對作為依據——這改變的是客戶端及其操作人員的行為方式,而不是掃描器要找什麼。八月的時候究竟有沒有人真的跑過這台伺服器,目前仍不得而知;就現有紀錄而言,發現本身就在於這個機制。