Every time a supply-chain story breaks, I do the same ritual: open the lockfile, grep for the names, and pray nothing new shows up. The last one to make me stop and stare was this week’s NullReceiver disclosure from OpenSourceMalware — North Korean operators hiding a command-and-control server’s IP address inside the recipient address of an empty Ethereum transfer. No payload field. No smart contract. Just a made-up wallet address that spells out where the malware should phone home. If you work with npm packages at all, this is the kind of trick you need to know how to spot.

Ethereum cryptocurrency security concept illustration
Image: Edwin.images via Wikimedia Commons (CC BY-SA 4.0)

What is NullReceiver?

NullReceiver is a blockchain-based command-and-control (C2) resolution technique used by DPRK-linked npm malware. Instead of hardcoding a server address in the package itself — which defenders could block in minutes — the malware looks one up on the public Ethereum ledger at runtime.

The mechanics are simpler than they sound. The package contains a hardcoded attacker wallet address. When it runs, it asks the blockchain for that wallet’s most recent outgoing transaction, reads the destination address of that transaction, and decodes the first four bytes of that address into an IP address. It then connects to that IP for its next-stage payload or instructions. The recipient address in the transaction isn’t a real destination at all — it exists only to carry data in its own bytes.

In the sample OpenSourceMalware analyzed, the wallet 0xa322e5f3d311d3080e6f0121063e9adc2490ef1a sent a zero-value, zero-data transfer to 0xa658863ea658863e68656c6c6f6970626f742121. The first four bytes of that address — a658863e — decode to 166.88.134.62, the C2 server. The trailing bytes spell out helloipbot!! in ASCII, which researchers believe is an attacker fingerprint. The transaction itself is completely blank: no data field, no contract call, nothing to fingerprint.

The packages behind the technique

OpenSourceMalware first flagged two trojanized npm packages: bianira-ui and fluid-type-ui, both DPRK-linked clones of legitimate Tailwind CSS plugins. Published on July 28, 2026, they’d already racked up a few hundred downloads combined — 109 for bianira-ui and 587 for fluid-type-ui — before researchers caught them. A follow-up The Hacker News report on the campaign added five more: post-css-transfer, scrollbar-hide-plugin, tailwind-anim, tailwind-animation-founder, and tailwindcss-anim, with download counts ranging from 124 to 1,357.

All seven are gone from the registry now. I verified that myself today: npm view bianira-ui returns a 404 with the note “Unpublished on 2026-07-28T04:19:31.430Z” — the same day it was published. Others, like fluid-type-ui and tailwindcss-anim, now resolve to version 0.0.1-security, npm’s placeholder version squatting the name so nobody else can re-publish a malicious copy. If you ever see that version string in a package you didn’t intentionally pin, treat it as a red flag, not a coincidence.

The technique itself is an evolution of EtherHiding, first documented by Guardio Labs in October 2023. EtherHiding hid malicious content in the transaction data field sent to Ethereum’s well-known burn address (0x000...dEaD) — which gave defenders a permanent landmark to watch. Google’s Threat Intelligence Group used exactly that to tie it to North Korean actors last year. NullReceiver patches that weakness: every lookup uses a brand-new, throwaway destination address, so there’s no fixed target to monitor and no field to fingerprint.

Why this matters more than a single package

NullReceiver is the leanest blockchain dead drop we’ve seen. EtherHiding could smuggle a full URL or script in calldata, but it pays gas for every byte and reuses a fixed destination. NullReceiver carries almost nothing — just an IP’s worth of bytes in an address — which makes it the cheapest, least conspicuous transaction shape on the network. Researchers think it’s a strong candidate to become the DPRK ecosystem’s default blockchain dead drop going forward.

And DPRK operators are already targeting developers hard. OpenSourceMalware links the campaign to Contagious Interview, the long-running fake-job-opportunity scheme that tricks targets into running malware as part of a “coding assessment.” The same infrastructure connects to PolinRider, a campaign that has spent months getting into developer machines through fake interviews, poisoned forks, malicious VS Code tasks, and typosquatted packages. For anyone who installs npm packages, this is the threat model to internalize: the package manager itself is now a phishing surface.

How the decoder works — tested

The heart of the technique is dead simple to reproduce. Here’s the decoder I ran against the address from the disclosure:

addr = 'a658863ea658863e68656c6c6f6970626f742121'
ip_part = addr[:8]       # first 4 bytes
marker = addr[-24:]      # last 12 bytes
ip = '.'.join(str(int(ip_part[i:i+2], 16)) for i in range(0, 8, 2))
print('C2 IP:', ip)                    # 166.88.134.62
print('Marker:', bytes.fromhex(marker).decode('ascii'))  # helloipbot!!

Output: C2 IP: 166.88.134.62 and Marker: helloipbot!!. That’s the whole trick — eight hex characters become four decimal octets. No cryptography was broken, no contract involved. That’s exactly why it’s dangerous: any blockchain explorer you can reach at runtime becomes a potential lookup channel for malware.

I also verified the attacker wallet is still live on Ethereum mainnet. A read-only query against a public RPC endpoint (eth_getBalance) returned a balance, confirming the address exists on-chain. The wallet is the shared infrastructure behind multiple packages — another reason to check IOCs against your own dependency graph.

How to audit your own project

You don’t need a blockchain forensics lab to check whether you’re exposed. These are the steps I run through now on any Node.js project:

1. Check your lockfile for known names

Grep package-lock.json (or yarn.lock/pnpm-lock.yaml) for the seven names above: bianira-ui, fluid-type-ui, post-css-transfer, scrollbar-hide-plugin, tailwind-anim, tailwind-animation-founder, tailwindcss-anim. Also check npm ls --all for anything you don’t recognize in your dependency tree — especially packages that look like one-character-off typos of tools you actually use.

2. Scan for hardcoded wallet addresses and RPC endpoints

The malicious packages embed a wallet address and public Ethereum RPC URLs (1rpc.io/eth, eth.drpc.org). Search your node_modules and source for 0x-prefixed 40-character hex strings and for RPC hostnames:

grep -r "1rpc.io/eth\|eth.drpc.org" node_modules/ 2>/dev/null | head
grep -rE "0x[a-fA-F0-9]{40}" node_modules/ 2>/dev/null | head

Legitimate packages rarely hardcode wallet addresses. If you get hits, inspect the file and trace which package it came from before touching anything else.

3. Verify the publisher before you install

Before adding any new dependency, run npm view <package> and look at who published it, when, and how long it’s been alive. The NullReceiver packages were published by accounts like npmuser1101 and npmuser3002 — generic names with no history, pushing brand-new packages cloned from popular tools. A fresh clone of a well-known plugin with a nearly-identical name is the classic typosquat profile, the same pattern I covered in how to detect compromised npm packages.

4. Run npm audit — but don’t trust it alone

npm audit is worth running, but it has a real blind spot: it only knows about published advisories. Malware that’s been taken down and squatted as 0.0.1-security won’t necessarily surface as a vulnerability in the audit output. I ran into exactly this with the Keyv npm worm — audit reported zero vulnerabilities while the registry was quietly restoring poisoned versions. Treat audit as one signal among several, never the final word.

5. Watch what your AI assistant installs

A growing number of these packages end up in projects because an AI coding tool hallucinated or guessed a package name that happened to exist as a malicious typosquat. If you let Claude Code, Copilot, or any assistant add dependencies automatically, review every name it proposes against the registry before running npm install. I wrote up the full version of that trap in your AI coding assistant is hallucinating package names — worth a read if you’ve ever let an assistant pick a package for you.

What to do if you find something

If any of the known names show up in your dependency tree, don’t just delete the folder. The package may have already run its downloader, and a C2-capable dropper on a developer machine is a serious incident:

  • Isolate the machine and remove it from the network until you’ve had a chance to check for persistence (registry Run keys, scheduled tasks, LaunchAgents).
  • Rotate every secret the machine could reach — cloud credentials, npm tokens, GitHub tokens, VPN keys. Treat anything cached in .env files or shell history as compromised. I covered the general pattern in finding leaked API tokens before attackers do.
  • Check for outbound connections to 166.88.134.62 (ports 80/443) in your firewall or EDR logs, and block that IP at the network layer while you investigate.
  • Look upstream: if the package was installed as a transitive dependency, find what pulled it in and fix that package’s manifest too.

If your code never calls the malicious package — say, it’s sitting unused in a lockfile — removing it and re-locking is usually enough. The threat is execution, not mere presence. But the safest posture is to treat any sign of the C2 IP in your logs as an infection until proven otherwise.

The bigger picture

Blockchain dead drops are attractive to malware authors for one simple reason: public ledgers are effectively impossible to take down. You can kill a domain, block an IP, sinkhole a DNS record — but you cannot delete a transaction from Ethereum. That resilience is exactly why we’re seeing DPRK operators iterate so aggressively: hardcoded domains gave way to EtherHiding, and now NullReceiver fixes the one weakness that made EtherHiding trackable.

The uncomfortable conclusion is that registry hygiene — checking publishers, verifying lockfiles, questioning every new dependency — is no longer optional. It’s the only defense layer that actually scales when the malware stops using fixed infrastructure entirely. The same discipline applies to the crypto-adjacent code we write: weak randomness in wallet software has already cost millions, as I detailed in auditing your JavaScript for CryptoJS’s weak randomness.

Here’s my rule of thumb now: if a package does something clever with the blockchain, it’s either a legitimate Web3 library or malware trying to look like one. There’s very little in between. When the cleverness is hidden inside an empty transaction’s recipient address, you’re not looking at a library anymore — you’re looking at a dead drop.

Keep your lockfiles clean, verify every publisher, and remember that the cheapest transaction on Ethereum is sometimes the most expensive thing that ever happens to your dev machine.

Filed under Tech & Gadgets
Last Update: August 11, 2026 by Felix AlterEgo
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Newest
Oldest Most Voted