Back to reports

32 Days on npm, Zero Victims, and a Developer Who Tested Malware on His Own Laptop: The FEZBOX Supply Chain Post-Mortem

QR code steganography, a dual C2 architecture, and an operator who exfiltrated his own system fingerprint to his own open database

PublishedApril 3, 2026
npmsupply-chainqr-steganographyself-doxxchinahuawei-cloudcookie-theft

On August 21, 2025, a package called fezbox appeared on npm. It contained a QR code steganography payload that stole browser cookies. It accumulated up to 476 downloads before npm's security team seized it on September 22 -- 32 days later. The C2 server is still running today, seven months after the takedown.

We know all of this because the developer tested the malware on their own machine and exfiltrated their own system fingerprint to their own C2 database, which they left open to the internet with no authentication.

The Self-Doxx

The exfiltration endpoint at 1[.]94[.]210[.]59/data returns a JSON array. Five records. Three are from the operator's test runs. The data includes:

  • Hostname: hstx
  • Username: asus
  • CPU: 13th Gen Intel Core i7-13700H (20 cores)
  • RAM: 16 GB
  • OS: Windows 11 (build 10.0.26100)
  • Working directory: D:\pycharmObject\fezbox-attack-test
  • Node.js: v20.18.0
  • IP address: 183[.]210[.]123[.]88
  • Network interfaces: Chinese-locale names ("本地连接"), VMware adapters installed
  • Location: Nanjing, Jiangsu Province, China (China Mobile, AS56046)

The operator literally named their project directory fezbox-attack-test. They ran it from PyCharm. They didn't use a VPN, a VM with a clean IP, or a test C2. They pointed the malware at their production server and pressed run.

The npm Identity

The package was published under the alias janedu with registration email janedu0216@gmail.com. npm suspended the account on September 22, 2025, and replaced the package with a 0.0.1-security holding package. The original versions 1.0.0 through 1.3.0 are gone, but the C2 infrastructure they called home to is still answering requests.

The Attack Chain

FEZBOX used QR code steganography -- an unusual choice for npm supply chain attacks, which typically rely on postinstall scripts or typosquatting. The chain:

  1. Developer installs fezbox (dependency confusion or direct install)
  2. Package loads and waits 120 seconds (sandbox evasion)
  3. Checks environment to ensure it's running in a real development context
  4. Fetches a QR code image from 1[.]94[.]210[.]59
  5. Decodes the QR content: a base64-encoded JavaScript payload tagged [FEZBOX]
  6. The JS payload steals document.cookie, window.location.origin, and navigator.userAgent
  7. Exfiltrates via HTTP POST to /collect on the C2

The QR steganography adds a layer of indirection that most static analysis tools miss. They scan for suspicious URLs, obfuscated strings, and shell commands -- not image files that happen to contain executable code.

Dual C2

The investigation revealed two exfiltration endpoints:

  1. Primary: 1[.]94[.]210[.]59 (Huawei Cloud ECS, Beijing) -- the dashboard, QR delivery, and /collect endpoint
  2. Secondary: my-nest-app-production[.]up[.]railway[.]app/users -- a Railway.app deployment receiving structured credential data

The Huawei Cloud instance runs three services:

  • Port 80: Node.js Express application (main C2)
  • Port 8080: "C2 Monitor Panel - Educational Use" dashboard
  • Port 9090: "DARKNET C2 CONTROL PANEL" with matrix rain effect

The "Educational Use" label is a fig leaf. The package was published to npm's public registry, accumulated hundreds of downloads from real developers, and the C2 collected real system fingerprints. Labeling it educational doesn't make it a classroom exercise.

Zero Real Victims

Despite 476 downloads and 32 days live on npm, the exfiltration database contains zero victim records. All five entries are from the operator's own IP (183[.]210[.]123[.]88) or our investigation probes. Two possible explanations:

  1. The cookie theft payload failed in most environments (browser context required, but npm packages run in Node.js)
  2. Victims' data was collected via the Railway.app secondary endpoint and isn't reflected in the primary database

The first explanation is more likely. The payload targets document.cookie -- a browser API that doesn't exist in Node.js. The attack would only work if the package was somehow loaded in a browser context (via bundler, test runner with browser environment, or Electron). A fundamental design flaw that the operator apparently didn't catch, even after testing.

Seven Months Later

The C2 at 1[.]94[.]210[.]59 is still running as of April 3, 2026. The /health endpoint confirms the server is online. The /data endpoint still serves the exfiltration database. The operator either forgot about it, doesn't know how to decommission Huawei Cloud instances, or is using the infrastructure for something else.

npm did their part -- the package is gone, the account is suspended. But the infrastructure behind it persists, and the techniques (QR steganography, dual-C2 architecture, environment fingerprinting) could be reused in a more competent campaign.

Indicators of Compromise

Network Indicators

  • 1[.]94[.]210[.]59 (Huawei Cloud, Beijing)
  • 183[.]210[.]123[.]88 (China Mobile, Nanjing -- operator IP)
  • my-nest-app-production[.]up[.]railway[.]app

Package Indicators

  • npm package: fezbox (versions 1.0.0-1.3.0, seized)
  • Publisher: janedu / janedu0216@gmail.com (suspended)

Behavioral Indicators

  • 120-second execution delay (sandbox evasion)
  • QR code fetch from C2 server
  • [FEZBOX] tag in decoded payload
  • HTTP POST to /collect with cookie data
  • document.cookie access from Node.js context (design flaw)

Share