RuntimeBroker npm Typosquat Plants Crypto Clipper

RuntimeBroker:一個 npm Typosquat 植入了一個 40 鏈加密剪幣器,作為跨作業系統的「系統運行時助手」。

TL博士

2026年05月21日,npm 發布者 jaggle 發布了九個版本(1.0.0 通過 1.0.8)的 @jaggle/resizeobserves 大約在兩個小時的時間窗口內。

該軟體包是對合法軟體包的拼字錯誤搶注。 @juggle/resize-observer polyfill 是一個廣泛使用的軟體包,每週下載量達數百萬次,但它並沒有提供實際的 ResizeObserver 實作。

相反,包裹的 安裝後鉤子 安裝捆綁的 Python 有效載荷,將持久性註冊為平台原生的運行時代理,並部署針對加密貨幣交易的跨平台剪貼板劫持程式。

Linux 持久性表現為 python3-dbus-helper, MacOS as com.apple.python.runtime以及 Windows as PyRuntimeBroker.

此有效載荷持續監控剪貼板,尋找錢包位址。 超過40個區塊鏈 並悄無聲息地將複製的地址替換為攻擊者控制的錢包地址。

該惡意軟體完全在本地運行,沒有對外 C2 基礎設施,因此剪貼簿替換本身就是一種資料外洩機制。

主要 IOC 就是軟體包名稱本身: @jaggle/resizeobserves — 注意「jaggle」中省略的元音和「resizeobserves」中新增的「s」。

嚴重程度:高。

攻擊原理

npm:@jaggle/resizeobserves 從表面上看不像惡意軟體 npm 視圖。 其 README.md 這是 README 的逐字原文 npm:@juggle/resize-observer — 相同的程式碼範例,相同的使用說明,相同的 import { ResizeObserver } from '@juggle/resize-observer' 全文引用過多。抄襲如此徹底,以至於任何瞥一眼文件的人都會以為自己在閱讀正版軟體包的文檔。

的package.json相比之下,則十分稀疏:沒有 知識庫 字段,單一 箱子 入口指向 bin/clipboard-guardian.js,配備 安裝後 運行的腳本 node npm-install.jsREADME 檔案中的「基本用法」範例引用了一個 tar 套件中根本不存在的 JavaScript 實作。該軟體包中唯一的 JavaScript 檔案是安裝腳本。

第一階段 — npm postinstall 引導 Python 有效載荷

npm-install.js 它具有平台感知能力。它可以定位一個 點子 沿固定搜尋路徑可執行(/usr/bin/pip3, /usr/local/bin/pip退而求其次 python3 -m pip),從 tarball 目錄安裝捆綁的 Python 包,並且在 Linux 系統上,會拉取 XCLIP or Xsel 通過 apt-get的, 吃豆子, 或者 DNF 如果兩者都不存在:

使用 –break-system-packages 這是有意為之:現代 Linux 發行版預設啟用了 PEP 668 中關於外部管理環境的 Python 標記,這會在預設情況下阻止全站範圍內的 pip 安裝。安裝腳本會強制執行此安裝。

該腳本也支援 sudo。當運行的 uid 是以下結果時: sudo npm install腳本內容如下: SUDO_USER 並掏錢 getent passwd 找到了 然後將其持久化檔案寫入使用者的主目錄,而不是寫入其他目錄。 /根持久化是針對每個使用者的,而不是系統範圍的。

第二階段-運行時代理名稱下的跨作業系統持久化

安裝 Python 套件後,該腳本會在每個作業系統上註冊一個名稱不同的自動啟動項目:

  • Linux — 一個 systemd 用戶單元 ~/.config/systemd/user/python3-dbus-helper.service該單元的 產品說明 is Python D-Bus 運行時助手該腳本也會嘗試透過以下方式啟用它: systemctl –user enable回退到手動符號鏈接 default.target.wants/ 當 systemctl 失敗時。如果以 sudo 運行,腳本將切換到 sudo -u systemctl –userXDG_RUNTIME_DIR 設定用戶總線呼叫功能。
  • MacOS — LaunchAgent plist ~/Library/LaunchAgents/com.apple.python.runtime.plist - RunAtLoad=true 以及 KeepAlive=true然後透過以下方式加載 launchctl 加載.
  • Windows — 一個名為 PyRuntimeBroker 的排程任務,在 AtLogOn 觸發,執行時間限制為零(即無逾時),透過 PowerShell 註冊。

乍一看,這三個名字都可信。 python3-dbus-helper 遵循 Linux 桌面上合法的 Python-D-Bus 整合命名約定。 com.apple.python.runtime 模仿蘋果公司對其自身服務的反向 DNS 標籤。 PyRuntimeBroker 這與Windows的聲明相呼應 RuntimeBroker.exe — 一個真實存在的、經過簽署的微軟服務,用於代理 UWP 應用的權限請求。在此上下文中,這些都不是真正的蘋果/微軟/Python 服務,而是一位防御者在快速目視檢查時發現的。 systemctl –user list-units or 取得計劃任務 不太可能退縮。

第三階段-剪貼簿劫持者

安裝在以下位置的 Python 有效載荷 clipboard_guardian/guardian.py運行一個無限循環,每 400 毫秒輪詢一次系統剪貼簿。每次循環,它都會透過以下方式拉取目前剪貼簿內容: pyperclip.paste() 並針對四十多個預先編譯的正規表示式清單運行它們,這些正規表示式涵蓋了以太坊、比特幣、門羅幣、索拉納、波場、TON、瑞波幣、萊特幣、狗狗幣、波卡幣、NEAR、Cosmos、Algorand、恆星幣、卡爾達諾、比特幣現金、達世幣、Zcash 、Aptos、Sui、Tezos、MultiversX、Harmony、Terra、Injective、Osmosis、Kava、Celestia、Nano、Filecoin、Ronin、Ergo、DigiByte、Hedera、BNB智慧鏈以及其他一些在預設組態中被存根但為空的加密貨幣(Sei、IOTA、Kaspa、Flow、Nervos、Decred、Ravencoin)。

當配對成功時,腳本會從該鏈中讀取攻擊者的位址。 ~/.config/clipboard-guardian/config.json (或其平台等效項)並用替換後的文字覆蓋剪貼簿:

沒有網路信標。該竊取器不會向伺服器發送數據,不會記錄受感染的主機,也不會竊取任何數據。竊取行為本身就是替換:當用戶從錢包介面複製收款地址並貼上到發送對話框中時,貼上的地址實際上屬於攻擊者。資金在用戶不知情的情況下以帶內方式丟失。

這裡有什麼新內容

與通用的加密剪枝模板相比,有幾個細節比較突出:

1. npm → Python 交叉。 我們在 npm 上看到的加密程式碼剪輯器大多是純 JavaScript,通常會使用混淆技術來處理。 _0x 數組旋轉或 eval(atob(…)) 堆疊。此範例使用 npm tarball 作為 Python 套件(乾淨的 Python)的交付包裝器,並讓 pip 處理依賴項安裝(pyperclip, psutil可選 設定程序標題) 在捆綁包中聲明 pyproject.toml不存在需要破解的 JavaScript 混淆。程式碼剪輯器本身就是純正易讀的 Python 程式碼。

2. 選擇合理的 Tri-OS 持久性標籤。 許多跨平台安裝程式以通用名稱註冊持久性(更新程式服務, helper.plist這個樣本煞費苦心地選擇了與各作業系統原生運行時代理相似的標籤。命名是唯一的隱藏嘗試-沒有rootkit,沒有使用者空間隱藏,也沒有路徑混淆。其目的在於,防禦者很少會進行審計。 ~/.config/systemd/user/ 以及一項名為 python3-dbus-helper 在一般的評價中不會脫穎而出。

3. 過程標題的偽裝是真實的,但反分析是休眠的。 Python酬載定義了一個 _disguise_process() 透過以下方式設定流程標題的函數 設定程序標題 (Linux/macOS)或 設定控制台標題W (Windows)-以及 主要() 確實這麼叫。所以 ps aux 將會呈現 python3-dbus-helper 而不是 python3 …/guardian.py然而,同一個模組定義了一個 is_monitor_running() 列舉已知過程監控工具的函數(HTOP, btop(例如任務管理器、活動監視器、進程駭客、資源監視器、GNOME/KDE/Xfce/MATE 系統監視器等等)—以及 主要() 它從未被調用。無論使用者是否開啟進程監視器,替換循環都會無條件運作。該函數在已發布的版本中已失效。它很可能是早期迭代遺留下來的程式碼,或是尚未實現的功能的框架。無論如何,已發布的有效載荷的反分析手段僅僅是重命名進程名稱,而不是主動規避監視器。

4. 捆綁配置合併行為。 npm-install.js 將預設錢包清單寫入 ~/.config/clipboard-guardian/config.json 如果設定檔已存在,則會合併所有現有值為空的鍵。這意味著先前已被感染並部分清理過設定檔的使用者(例如,透過清空設定檔)也會受到影響。 復仇 該值會在每次後續惡意軟體安裝時重新填入。任何程式碼路徑中都不會清理持久化檔案。

日期/時間(UTC) 創建
2026-05-21 18:50:32 @jaggle/resizeobserves@1.0.0 出版。
2026-05-21 19:55:55 1.0.1 發布-第一個版本被外部掃描標記。
2026-05-21 19:58:10 1.0.2 出版。
2026-05-21 20:05:03 1.0.3 出版。
2026-05-21 20:09:24 1.0.4 出版。
2026-05-21 20:13:48 1.0.5 出版。
2026-05-21 20:41:52 1.0.6 出版。
2026-05-21 20:43:56 1.0.7 已發布-新增 try/catch 對 wallet-config 寫入步驟的封裝 npm-install.js.
2026-05-21 20:46:15 1.0.8 發布 — 安裝程式已重新命名 npm-install.jsnpm-install.cjs (位元組相同的內容)。
2026-05-22 裁決和國際奧委會意見書已發布。版本在發佈時仍保留在註冊表中(持續更新)。

一小時五十六分鐘內發布九個版本,即使對於一個拼字錯誤佔位符來說也相當快了。這種模式與…一致 發布即銷毀活動 — 使用一個句柄向註冊表中大量寫入數據,讓檢測過程自行完成,並在刪除單一版本後切換到新的句柄。運行過程中可見的差異僅為外觀上的:1.0.1 版本添加了明確的 /usr/bin/pip31.0.7 版本將 pip 搜尋清單的路徑樣式改為 sudo 相容模式,並將 wallet-config 寫入操作封裝在 try/catch 語句中,1.0.8 版本則將安裝程式重新命名為 -style 格式。 JS。.cjs 同時保持其內容位元組完全相同。 .cjs 重命名曲目時,npm 會發出關於套件中模組解析不明確的警告,提示缺少明確模組解析。 “類型” 這或許是為了抑制安裝時可能引起注意的干擾。 Python有效載荷——唯一真正竊取資料的部分——在所有九個版本中都保持不變。

妥協指標

配套

生態系統 小包裝 版本 狀態
NPM @jaggle/resizeobserves 1.0.0 通過 1.0.8 發佈時已上線;已要求下架。

文件與灰燼

途徑 筆記
clipboard_guardian/guardian.py
(md5 f7935c2c82bc881288611ab6cd634f17)
所有九個已出版版本均相同(1.0.0 通過 1.0.8)快船有效載荷。
npm-install.js (1.0.0 – 1.0.7)
npm-install.cjs (1.0.8)
持久化安裝程式;端到端行為相同。 1.0.7's .js 以及 1.0.8's .cjs 位元組完全相同。
~/.config/clipboard-guardian/config.json Linux 持久化配置和錢包包。
~/Library/Application Support/clipboard-guardian/config.json macOS 持久化配置和錢包包。
%APPDATA%\clipboard-guardian\config.json Windows 持久化配置和錢包包。
~/.config/systemd/user/python3-dbus-helper.service Linux 自動啟動持久化。
~/Library/LaunchAgents/com.apple.python.runtime.plist macOS LaunchAgent 持久化。
~/Library/Logs/com.apple.python.runtime.log 代理程式的 macOS 標準輸出/標準錯誤日誌。
Scheduled Task PyRuntimeBroker Windows 自動啟動任務(AtLogOn(無超時)。

行為指標

Signal 產品說明
pip install --break-system-packages 來自 npm postinstall 強制全站安裝 Python,繞過 PEP 668 保護措施。
apt-get install -y xclip (或吃豆人/dnf) 在Linux系統上安裝軟體套件時,安裝剪貼簿實用程式。
python3-dbus-helper.service systemd 用戶單元 持久化程序註冊在一個看起來很合理的運行時輔助程式名稱下。
com.apple.python.runtime 啟動代理 持久化標籤位於合法的蘋果系統路徑之外。
PyRuntimeBroker 計劃任務 偽造的 Windows 運行時代理持久化機制,沒有合法的安裝程式來源。
Python行程名為 python3-dbus-helper 輸入 pyperclip 以及 psutil 顯示的進程名稱與匯入的庫不符。
錢包位址複製後約 0.4 秒剪貼簿發生變化 加密貨幣位址替換的特徵行為。

攻擊者錢包捆綁包(防御者獵殺列表)

錢包列表是硬編碼在系統中的。 npm-install.js 以及 clipboard_guardian/guardian.py防禦者可以將此清單用作黑名單(將企業錢包向這些地址的任何轉帳視為可疑交易)和狩獵金鑰(將未經身份驗證的設定檔、建置工件或開發人員機器中出現的任何這些字串視為感染指標)。

攻擊者錢包捆綁包

地址
以太坊/BSC 0x450c0E58Fc2ba03632d3F5780ad8C966648B6F18
浪人(EVM) ronin:450c0E58Fc2ba03632d3F5780ad8C966648B6F18
比特幣 bc1qs2mpls4p0f7fng073gy2rcdgjpf7la4eugpt6y
比特幣現金 bitcoincash:qqmvyxxklzp7l3eslxavhc8phl6hprdf25lwc29nlt
Litecoin ltc1qnefc8x59a9cwtqnflt8hmqvezqw4hc7lt3fkqe
多吉幣 DNEJmYRZtzyK44tZea4S7wV3otTyRk48Fy
短跑 XtJ7E6mnhPK93Vib29PGQrTmQjhTTqFwbS
Zcash t1d4hcEnBjdh9X6Wb6R2dxqjnxddJ6ocP8M
DigiByte DPmH2dhiGK3hk3A69tZUMz6tHzGFHBzSrH
Monero 42zhAidVhP7QETk83JAspS59ASALSHFio44vmu6MdDCz15cSqtqsG4QVyzY8vTrjGrTEA6zMbWW6Yft1Ynz1xLfCN5FVbXf
索拉納 DWBAmQLi9gP6mk7UfJfQGYTV1UPK32WekLTqg83q1mc5
TRON TVgEgMemmJABYYnbNr1Wi8bSgADEkdEBt2
TON UQDTSkvwmptU9eG988KgxS3WjnYAZlXgfpJxnz4mhWZAvULr
Ripple r9tj3cMCiqRijNYqNVYNuwKykkQfS8FE4H
波爾卡圓點 1JSkYqXQE4d28HdcmTPhbgCrdiPFTfSHxD67tam16p53oBG
NEAR 5d6aec44551529e8cd9ebd3aaa84b3832fc3c7463596b2b6e72635b80096a364
宇宙 cosmos1pzfl3kv5g8g0ernj86rwpar08u2zl9suthx28e
滲透 osmo1pzfl3kv5g8g0ernj86rwpar08u2zl9surv463t
勒斯蒂亞 celestia1pzfl3kv5g8g0ernj86rwpar08u2zl9su6ah6a5
內射式 inj1g5xquk8u9wsrvvkn74uq4kxfvejgkmccn578gh
卡瓦 kava1kjfvgcz4q0y9yae2f3pa33vhj2estxxj3sqqux
和諧 one19hn0n7dzkhtl9ta9ekv5592s85jwstpka76t3a
terra1h0dwu8z405jagdlr0fgr9jllac2sxajzlgme5x
Algorand XSAMN3FTB5SUHUQFENBDDRXIMOPNFVLKAWA3RNOU54DWROMDZ6SR7DZ2PI
Stellar GACNZSV4EQO65NZZUOBS3TMJM7GFTSRNKQBVJOX5P2G7U7SEBQ2ZUDJE
卡達諾 addr1qyj050vla4cglmyrgm4vzf3dxtn0gynpks4t7vp7s3lg49e9wt0s94hcztzdgecxcz5hu9uk56q60yth6d66w026s2kq3ma56f
多元宇宙X erd1slvlgqsmwzk0c8xtksm4eq5vdfnc26slpzqsyxhz456zvme5rpasue6ge0
阿普托斯 0x580ecda1ebd6ca5a46be2097568d013308bd54ef1d147acb880b59f7709f280e
0xf7e8a9a970fa65c058745c4b2cf2a856cc0283863e4ed1e142648f26097b0c78
納米 nano_393n56a5pfz8zg3nkzf7mytfgagzhu5mn9i3xiqg54weq8n1u8jgezxas7dn
Filecoin f1fypyww3xubopfnv7q6yh5l4bko44wmfktf3ckui
Tezos tz1RccjnorHk61bt73ArLXcdgFjEj6T1ochk
ERGO 9g1pNQGnFg7Hk1d9Z66bgHMkguGU7R41btypAnbG1NF5FJoNdBA
常春藤 0.0.10488092

預設配置中錢包槽位為空但正規表示式覆蓋的鏈(例如 Sei、IOTA、Kaspa、Flow、Nervos、Decred、Ravencoin 和 Beacon-Chain BNB)在此版本中不會被主動替換,但會被偵測到。請將它們視為監控範圍而非替換範圍。

歸因與動機

此廣告系列的歸因分析數據有限。我們尚未能確認運營者的身分。我們可以記錄的資訊如下:

  • 發布商元資料。 npm 帳戶 晃動 其電子郵件地址列為 olgascarlet@deltajohnsons.com. 領域 deltajohnsons.com 無法解析為我們可驗證的企業身分。 npm 帳戶未顯示電子郵件驗證,也沒有其他資訊。 SCM 已驗證。沒有關聯的公開 GitHub 實例。
  • 存儲庫字段。的package.json 不攜帶 知識庫 領域。合法的 npm:@juggle/resize-observer 指向一個擁有數千顆星和活躍 issue 的真實 GitHub 程式碼庫。缺少程式碼庫連結是 npm 使用者介面上最直觀的判斷依據。
  • README文件抄襲。 該軟體包的 README 文件是合法的。 @juggle/resize-observer README 逐字節說明,包括 進口 引用範例 @juggle/resize-observer 是程式本身(而非發布包)。運營者甚至懶得重寫導入語句——這通常表明README文件是直接照搬而非修改的。
  • 沒有可以依靠的基礎設施。 沒有C2端點,沒有DNS查詢,也沒有IP位址。惡意行為完全封裝在本地的Clipper程式和硬編碼的錢包包中。這使得基於域名或ASN的橫向移動攻擊無法進行。跨攻擊活動進行橫向移動的防禦者應該將錢包與先前存檔的Clipper程式進行雜湊匹配;在不同攻擊包中重複使用錢包是最容易追蹤的跨攻擊活動關聯。
  • 命名選擇。 @jaggle/resizeobserves 比…少一個字符 @juggle 與眾所周知的稍稍不同 調整大小觀察者合併後的編輯距離為兩個字形。這是一種刻意營造的視覺碰撞效果,並非普通的蹲姿。

動機源自於酬載行為:純粹透過機會主義的剪貼簿替換進行貨幣化。不涉及憑證竊取、主機指紋辨識或環境變數讀取。攻擊者並不關心受害者是誰——他們只關心受害者的下一次轉帳是否指向已列出的地址之一。四十條鏈的覆蓋範圍就像是彩票模型:廣撒網,希望每 N 次安裝中能有一次高價值的粘貼內容命中。

該運營商似乎並不擔心被下架。在兩小時內發布九個相同版本的惡意軟體,這明顯是一種「發布即銷毀」的策略:在下架延遲到來之前,盡可能擴大其在註冊表中的佔用空間,然後繼續下一步。我們尚未觀察到 @jaggle 在撰寫本文時,該出版物已根據新的範圍重新出版,但我們預計會出現類似的範圍(@jaggie, @juggle-, @嚙合如果運營商仍然活躍,則將在未來幾天內出現。

影響、趨勢及防守者應採取的措施

 影響性

根據現有數據集,無法量化實際影響。該剪幣器不寫入遙測數據,且截至分析截止日期,尚未觀察到錢包接收到替代轉帳(我們計劃對列出的鏈進行後續掃描)。合法 npm:@juggle/resize-observer 平均每週下載量高達七位數——這是一個高流量的域名搶注目標——而且該惡意軟體包在披露時上線時間不到 24 小時,這限制了受影響的人群,但並沒有使其為零。

值得追蹤的爆炸半徑並非直接下載 @jaggle/resizeobserves — 這些可能很小。這是**傳遞安裝**:開發人員將軟體包添加到沙盒專案中,運行 npm安裝然後,他們忘記了安裝鉤子曾經運行過。現在,所有處理過安裝後處理的機器都會自動執行一個針對每個使用者的剪貼簿劫持程序,無論項目是否仍在磁碟上。從…移除包目錄 node_modules **不會**移除持久性。

新興模式

此次活動反映了兩大趨勢。

npm 作為 Python 有效載荷傳遞包裝器。 npm tarball 是一個 4 行的安裝程式;真正竊取資源的是 Python,它透過系統層級安裝的方式取得資源。 點子 從捆綁目錄中。這並非新鮮事——我們之前就見過 npm 套件放棄 Python——但這在加密剪貼簿攻擊活動中變得越來越普遍。對攻擊者而言,優勢有兩面:Python 剪貼簿庫(pyperclip 其中最重要的是)比 JavaScript 等效程式碼更簡潔、更具跨平台性,而且 大多數自動化的 npm 掃描器對 JavaScript 檔案和 Python 檔案賦予很高的權重。 的.py 輕輕地捆紮起來。 代價是安裝體積更大,噪音也更大——一個全新的 點安裝 在通常不會出現問題的開發人員機器上很難隱藏。 點安裝npm安裝.

平台原生名稱是唯一的隱藏手段。 最近一些程式碼剪輯器和小有效載荷竊取器完全放棄了程式碼層級混淆,轉而使用看起來很合法的持久化標籤。 python3-dbus-helper, com.apple.python.runtime以及 PyRuntimeBroker 這些都是典型的例子──在四十個使用者服務清單中,防禦者會忽略這些名稱。這是一種廉價而持久的隱蔽手段:雖然下架是針對每個軟體包的,但持久化文件卻能倖存下來,而且一個以看似真實的平台組件命名的服務,除了明確的審計之外,不會受到任何影響。

防守隊員該怎麼做

  • 審核 ~/.config/systemd/user/、~/Library/LaunchAgents/ 和 Get-ScheduledTask 產量 在開發者機器上,IOC 中列出的條目仍然存在。移除 npm 套件後,這些條目仍然保留;需要手動移除。
  • 阻止向列出的錢包位址進行轉賬 在公司財務部門和 DeFi 錢包邊界,地址允許清單可用。
  • 尋找 ~/.config/clipboard-guardian/config.json (以及平台上的同等版本)在開發者的所有機器上均存在。無論該文件是由哪個軟體包版本提供的,只要存在該文件,就高度確信已感染病毒。
  • 在 node_modules/ 目錄中搜尋 clipboard_guardian/guardian.py 檔案。 在可能早於文件下架的建置快取快照中,該檔案的 MD5 值在所有已審查的版本中均保持穩定。
  • Lockfile-pin @juggle/resize-observer (合法的軟體包),因此,即使輸入字元錯誤,未來的安裝也不會解析成其他任何內容,尤其是在沒有鎖定檔案的工作流程中,例如 NPX.
  • 將任何呼叫 pip install 的 npm postinstall 操作都視為已完成 嚴重程度高 內建-pipeline 政策方面,npm 套件在安裝時沒有理由需要 pip——Python 工具集本身就包含 Python 工具集。
  • 搜尋名為 python3-dbus-helper 且導入了 pyperclip 的程序的 process_iter() 可比較的監控數據 — 偽裝不符(D-Bus 助手持有剪貼簿庫)是我們擁有的最清晰的行為指標。
  • 輪換從受感染機器貼上的錢包地址。 剪貼簿劫持程式會破壞錢包使用者介面和貼上目標之間的路徑;在感染期間複製的位址可能會被悄悄竄改。在感染期間發送的任何訊息都應視為可能被錯誤發送。

關鍵在於:持久性比下架更持久。註冊表最終會被刪除。 @jaggle/resizeobserves 在所有九個版本中,systemd 單元、LaunchAgent 和 Scheduled Task 都不會自行刪除。

參考

sca-tools-software-composition-analysis-tools
優先處理、補救並保護您的軟體風險
註冊免費帳號。
不需要信用卡。

確保您的軟體開發和交付安全

使用 Xygeni 產品套件