Back Socket.Dev Malicious Firefox Extensions Impersonate Phantom, Jupiter, and Bitget to Steal Wallet Secrets
Malicious Firefox extensions mimic Phantom, Jupiter, and Bitget wallets to steal recovery phrases and private keys, with one fetching its payload remotely.
Socket’s Threat Research Team identified a cluster of malicious Firefox extensions that impersonate well-known crypto wallets and steal recovery phrases and private keys. The extensions use Unicode homoglyphs to copy the names of Phantom, Jupiter, and Bitget, and they route stolen secrets to brand-named subdomains of a single command-and-control apex, bonto[.]io . Each signed package carries a complete, always-on stealer, so the malicious code is present in what Mozilla reviewed. The Phantom impersonator adds a second layer: a loader that pulls a stealer from a server at runtime and runs it in the page, letting the operator swap or refresh the payload after review. All three listings were live on Firefox Add-ons during analysis and have been removed as of publication.
The campaign breaks down as follows:
Phantom impersonator (add-on ID 3092199): a small loader inside the signed extension fetches a second-stage stealer from phantom[.]bonto[.]io/config and runs it in the main world of every page the victim opens, and also bundles a stealer and the operator’s drainer backend.
Jupiter and Bitget impersonators (IDs 3092666 and 3092059): the stealer is bundled in the package and routes stolen secrets to jupiter[.]bonto[.]io and bitget[.]bonto[.]io .
Shared infrastructure : at least five brand-named subdomains of bonto[.]io are provisioned as exfiltration hosts, including coinbase[.]bonto[.]io and exodus[.]bonto[.]io , each listing published from its own throwaway AMO ( Addons.Mozilla.Org ) developer account.
What the Extensions Pretend to Be #
Each listing impersonates a real wallet. The Phantom listing sets its public display name to the string 𝐏ha𝐧†օ𝗺 , built from Unicode homoglyphs that render on the page as “Phantom,” and reuses Phantom’s real ghost icon and marketing copy, including the heading “OFFICIAL PHANTOM WALLET (Firefox Update).” The Jupiter listing renders as “Jupiter” and claims to be “Built by Jupiter Exchange.” The Bitget extension’s manifest name is “TabFlow Pro,” while its listing presents Bitget Wallet branding to users.
These are among the most widely used crypto wallets, which is the reputation the campaign trades on. The impersonation is cross-ecosystem: the real Phantom shows 5,000,000 users on the Chrome Web Store and roughly 83,000 daily users on Firefox Add-ons, and these fakes ride that brand recognition.
How the Theft Works #
A Loader That Fetches a Second Stage #
The signed Phantom package carries a benign-looking wallet bundle plus a loader appended to background/serviceWorker.js . The loader rebuilds its C2 host from a character-code array, requests a configuration object, decodes a base64 payload, and runs it as code inside the page. It injects into the main world first, which gives it access to page objects such as the wallet’s own injected provider, and falls back to the isolated content-script world. It re-injects on every tab load and on install and startup.
The character-code array decodes to phantom[.]bonto[.]io , and the claiming the code loads an analytics module is the threat actor’s own disguise.
The Server Decides When and What to Steal #
The configuration endpoint returns a JSON object with an active flag and a base64 code field. Because the payload is delivered at runtime, the operator controls both whether the stealer runs and what it does, with no new submission to Mozilla. The endpoint can return an inert response during review and the live stealer afterward. At the time of writing, phantom[.]bonto[.]io/config returned active: true and a 4,029-byte payload.
The returned stage is a recovery-phrase and private-key stealer. It classifies captured strings, detecting BIP-39 seed-phrase word counts (12, 15, 18, or 24 words) and both Ethereum (EVM) and Solana private-key formats.
It captures secrets through several paths: reading every input and textarea value, listening for paste and focusout events, and scanning page text for a numbered recovery-phrase grid of the kind shown on a wallet’s reveal-secret-phrase screen.
Because it runs in the main world, it also hooks the page’s injected Solana provider to capture the connected public key.
Captured data is posted as JSON to the C2 host, with an XMLHttpRequest fallback and a simple set to avoid sending the same value twice.
The Bundled Variant #
The Jupiter and Bitget impersonators do not use a remote loader. Their stealers are bundled in the package and post the captured mnemonic straight to the brand subdomain. The Jupiter impersonator sends the phrase on its “standalone” and “mnemonic” code paths.
The Jupiter impersonator also declares host access to Trezor Connect at connect.trezor.io , which widens the surface it can read. The Bitget impersonator references bitget[.]bonto[.]io in its static/js/hook.js and follows the same bundled pattern.
The Stealer Also Ships In-Package, and Phantom Bundles the Operator's Backend #
All three packages ship a complete, always-on stealer inside the signed code Mozilla reviewed, each rated 10 out of 10 by Socket's scanner. Phantom's is analytics.js , wired into its own popup and onboarding pages. Jupiter ships two: a 621 kB trojanized background.js that sends the mnemonic and private key to jupiter[.]bonto[.]io on wallet import, and a smaller hook.js that captures seed phrases and keys from page inputs and the clipboard on any page. Bitget also ships two: static/js/hook.js , which scans page content and extension messages, and static/js/bg-init.js , a background worker that hooks the wallet's own storage to lift the seed as it is decrypted and overrides tab creation to funnel the victim into the local import screen. Both route to bitget[.]bonto[.]io . The remote loader described earlier is Phantom-only, and it gates and refreshes a payload that already ships in the package rather than being the only copy.
Phantom also bundles the operator's own drainer backend as server.js , a Node.js server inside the signed add-on. It logs captured secrets to local files, forwards them to a Telegram bot, and automatically sweeps funds to hardcoded payout addresses across Ethereum, BSC, Polygon, Arbitrum, Optimism, Base, Avalanche, Solana, and Bitcoin. A in the file notes the payload reaches the extension only "after approval flip," meaning after Mozilla's review.
The package also ships server-review.js , a stripped server that returns an inactive config during Mozilla's review. After approval the operator switches to the live server.js , the "approval flip" the refers to.
Infrastructure and Attribution #
All exfiltration points to subdomains of a single apex, bonto[.]io, fronted by Cloudflare so the origin is hidden. The Phantom host behaves as a second-stage delivery and exfiltration point, while the other brand hosts accept exfiltration POSTs directly. Probing the apex for additional brand subdomains returned provisioned hosts for coinbase[.]bonto[.]io and exodus[.]bonto[.]io , each responding with the same signature as the confirmed Jupiter and Bitget exfiltration hosts, which indicates the campaign also targets the Coinbase Wallet and Exodus brands. Corresponding AMO listings for those two brands were not located at the time of writing.
Each of the three confirmed listings was published from a separate throwaway AMO developer account ( anonymous-30b17a249a34fdf5d2be64b3dfcc8494 , anonymous-3efb89873d4c425c012cd1cb1736629a , and anonymous-ca2bf8b1ba371a1426c1049d9dad8168 ), a pattern that spreads the campaign across accounts and slows bulk takedown.
The Phantom and Jupiter packages also ship a CLAUDE.md file the extension never loads at runtime. It is an AI-assistant jailbreak prompt, which points to AI-assisted malware authoring and an attempt to subvert AI-assisted review.
When a victim installs one of these extensions and enters or reveals a recovery phrase, or pastes a private key, the secret is sent to the threat actor. A recovery phrase and a private key are bearer secrets: whoever holds them controls the wallet and can move every asset in it. The main-world injection means the Phantom variant can read secrets both when they are typed during import and when they are shown on a reveal-secret-phrase screen, and it can observe the page’s wallet provider directly.
The Phantom listing shows active rating manipulation. Over roughly two days the review count rose from 275 to 546 and the average rating rose from 2.9 to 3.9, which pushes down the one-star reviews in which users report losing funds. Reported losses in those reviews are self-reported and unverified. Average daily users reported by AMO for each listing were low, between one and three, but the listings were live and the infrastructure was active.
Install wallet extensions only from the vendor’s official website link, not from store results. Homoglyph names and copied icons make a fake listing look identical to the real one.
Treat any extension that asks for a recovery phrase or private key outside the real wallet flow as hostile, and never enter a seed phrase into a page you reached from a store listing.
If you entered a seed phrase or private key into one of these extensions, move funds to a new wallet created on a clean device immediately and treat the old wallet as compromised.
Pin the exact extension IDs your team uses and review extensions that request access to data for all websites together with tabs or scripting.
Watch for extensions that fetch and execute code at runtime, which is visible as a fetch of a configuration endpoint followed by eval or scripting.executeScript .
Block the bonto[.]io apex and its subdomains at the network layer and alert on DNS lookups for brand-named subdomains under it.
Hunt for browser extensions whose signed bundle contains a loader that injects into the main world.
Socket’s browser extension protection analyzes extension bundles for hidden data flows, undisclosed credential exfiltration, and C2 backdoors, blocking malicious extensions before they reach user endpoints.
T1176 Browser Extensions
T1105 Ingress Tool Transfer
T1620 Reflective Code Loading
T1140 Deobfuscate/Decode Files or Information
T1027 Obfuscated Files or Information
T1555 Credentials from Password Stores
T1041 Exfiltration Over C2 Channel
T1657 Financial Theft
Indicators of Compromise #
AMO developer account: anonymous-30b17a249a34fdf5d2be64b3dfcc8494 (user id 20229996), Phantom impersonator
AMO developer account: anonymous-3efb89873d4c425c012cd1cb1736629a (user id 20231205), Jupiter impersonator
AMO developer account: anonymous-ca2bf8b1ba371a1426c1049d9dad8168 (user id 20229610), Bitget impersonator
coinbase[.]bonto[.]io
Hardcoded Wallet Addresses #
EVM (ETH, BSC, Polygon, Arbitrum, Optimism, Base, Avalanche): 0x93ce11fAA9FC83741e8b392879b383bcc5f7f3Ad
Solana: GCo8tAh5WjAuH51bnRZtkmKDRuoXHFDNz9MZY25Zuvsr
Bitcoin: bc1qrsfyjrsel924nny9q0qak5cfyf7pahmsydwnrq
Telegram Exfiltration #
Bot token: 8834114695:AAGC99--r8KFikBpDw5JCkAteIc4cRi2VTU
Extension Identifiers (Firefox AMO) #
Phantom impersonator : add-on id 3092199, slug ha-օ, gecko id a8f3k2m9x1fefb7q4n6p0r5t@j2w8c4fefy6v1d3z9, version 25.6.0
Jupiter impersonator : add-on id 3092666, slug j-ρi, gecko id {48392751-9302-4817-5621-703829164830}, version 1.19.2
Bitget impersonator (internal name TabFlow Pro): add-on id 3092059, slug ві-е, gecko id {c31e7a95-2f64-4b18-a0d3-6e92f5c7481b}, version 2.21.8
File Hashes (SHA-256) #
Phantom impersonator XPI (ha-25.6.0.xpi): 311c49974f28d33947b8b74d78b48f51855eacac182d519a4fe1daa6af7f30e9
Phantom second-stage payload (served by phantom[.]bonto[.]io/config, 2026-10-21): 999bccd41188a238a50d05b5aca8e35af45d107f32d7443389313816f0cb226a
Jupiter impersonator XPI (j_i-1.19.2.xpi): fd7b138f4fba003db332a4eee833e84491bf7ffec5a3d91f7451d7b95aabcf6a
Bitget impersonator XPI (3092059-2.21.8.xpi): e688bff5df32f209b4ebb882985e3ad19ddee68666405c39ff523307068a8611
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
