技術 約10分で読めます

“StegaBin” hides C2 with Pastebin zero-width characters and distributes malicious npm packages

いけさん目次

Kieran Miyamoto of Socket and Kmsec.uk reported a new npm supply chain attack called StegaBin by the North Korean threat cluster Famous Chollima. Over the course of two days, February 25th and 26th, 26 malicious npm packages were published, using a steganography technique to embed C2 URLs with zero-width Unicode characters in harmless essays posted to Pastebin. Socket detected the first package within two minutes of publication, and classified all 26 packages as unsafe within six minutes each.

Famous Chollima and Contagious Interview

Famous Chollima is a North Korean-based cyber threat cluster tracked by CrowdStrike that is closely associated with Lazarus Group. This group has been running a campaign called “Contagious Interview” (in the security field, it refers to a series of attack activities) since late 2023, posing as a fake recruiter on LinkedIn etc., using a technical interview as an excuse to run a Node.js project, and developing an infection chain from BeaverTail downloader to InvisibleFerret backdoor.

This StegaBin campaign extends the Contagious Interview technique to npm supply chain attacks. There is no need to set up an interview, and npm install alone can infect someone. Similar to SANDWORM_MODE reported in February, Famous Chollima uses typosquatting (a technique used to target false installations with fake packages with similar names), but Famous Chollima is a state-sponsored attack group and differs in the scale and persistence of its attack infrastructure.

26 packages and typosquatting

The following was published on separate disposable accounts between February 25th and 26th:

argonist       bcryptance    bee-quarl      bubble-core
corstoken      daytonjs      ether-lint     expressjs-lint
fastify-lint   formmiderable hapi-lint      iosysredis
jslint-config  jsnwebapptoken kafkajs-lint  loadash-lint
mqttoken       prism-lint    promanage      sequelization
typoriem       undicy-lint   uuindex        vitetest-lint
windowston     zoddle

Misleading developers by naming them similar to the names of existing popular packages, such as bcryptbcryptance, lodashloadash-lint, expressexpressjs-lint, winstonwindowston, zodzoddle. They disguise themselves as development tools or authentication libraries by adding suffixes such as -lint, token, js. Each package declares regular dependent packages in dependencies to improve visual reliability.

How Pastebin steganography works

The main feature of this campaign is that it uses steganography, which combines Pastebin and zero-width Unicode characters, to hide C2 URLs.

What is a zero-width Unicode character?

“Zero width” refers to invisible characters whose display width is zero. Although it cannot be seen in a text editor or browser, it exists as a string. The main character types are as follows.

CharacterCode PointOriginal Use
Zero Width Space (ZWSP)U+200BHint for possible line breaks. Used in languages such as Thai and Khmer that do not have separate writing
Zero Width Non-Joiner (ZWNJ)U+200CLigature suppression. Preventing letter combinations in Persian and Arabic
Zero Width Joiner (ZWJ)U+200DForce character join. Familiar with emoji composition (👨‍👩‍👧 = 👨+ZWJ+👩+ZWJ+👧)
Zero Width No-Break SpaceU+FEFFBOM (Byte Order Mark). Encoding identifier placed at the beginning of the UTF-8/16 file
Word JoinerU+2060Hints for where line breaks are prohibited. Characters that took over the original role of U+FEFF

These are all legal Unicode characters and are commonly used in text processing. ZWJ is essential for compositing emoji, and without ZWNJ, the display of Arabic characters will be broken. That’s why security tools cannot simply determine that “zero-width characters = malicious”.

It also has a long history of abuse. “Watermarking” has been used since the 2010s to trace the source of copied text by adding zero-width characters to the text of web pages to prevent copy-pasting. StegaBin is a version of this technique used to hide C2.

Decoding flow

The attacker posted a seemingly innocuous computer science essay in three Pastebin pastes, replacing evenly spaced characters in the text with characters from the C2 address. The decoder included in vendor/scrypt-js/version.js in the package operates as follows.

  1. Remove zero-width Unicode characters from text
  2. Read the first 5 characters as a number and get the payload length
  3. Extract characters at evenly spaced positions in the entire text
  4. Divide the extracted string at ||| and restore the C2 domain sequence using ===END=== as the termination marker.

The entire attack chain is illustrated below.

flowchart TD
    A["npm install"] --> B["install script自動実行"]
    B --> C["Pastebinからエッセイ取得"]
    C --> D["ゼロ幅文字をデコード"]
    D --> E["C2ドメインを復元"]
    E --> F["Vercel 31台からDL"]
    F --> G["OS別ペイロード実行"]
    G --> H["9モジュールRAT展開"]

    style A fill:#dc2626,color:#fff
    style B fill:#dc2626,color:#fff
    style C fill:#2563eb,color:#fff
    style D fill:#7c3aed,color:#fff
    style E fill:#7c3aed,color:#fff
    style F fill:#2563eb,color:#fff
    style G fill:#2563eb,color:#fff
    style H fill:#dc2626,color:#fff

There is no C2 URL directly in the code, and the communication to Pastebin appears to be just “retrieving the essay.” Even if you change the C2 URL, you only need to update the Pastebin side, which has the operational advantage of not having to republish the distributed package. The design makes it difficult to detect with static analysis tools and sandboxes.

Delivery infrastructure with Vercel 31 deployment

After restoring the C2 domain, the malware downloads platform-specific shell scripts and RAT components from 31 deployments hosted on Vercel. Only one was active at the time of analysis, an example domain being ext-checkdin.vercel[.]app.

By exploiting Vercel’s free tier, they are able to reduce attack infrastructure costs to zero while ensuring redundancy to switch to another deployment in the event of a takedown (forced deletion).

RAT with 9 modules

npm installThe installation script is automatically executed and the payload (malicious code body) in the vendor directory is launched. In the end, the following nine modules will be developed.

ModuleImplementationFeatures
vsNode.jsVS Code Persistence. Add runOn: "folderOpen"trigger task to tasks.json and connect to Vercel domain every time you open the project
clipNode.jsKeylogger/mouse tracker/clipboard theft. Send data externally at 10 minute intervals
broPythonBrowser authentication information collection. Targets password stores such as Chrome, Firefox, Edge, Brave, etc.
jNode.jsCryptocurrency wallet theft. MetaMask・Phantom・Coinbase Wallet・Exodus etc.
zNode.jsFile system enumeration and target file extraction
nNode.jsWebSocket RAT. Permanently connect to 103.106.67[.]63:1247 and execute commands in real time
truffleNode.jsDeploy genuine TruffleHog and scan secrets such as .env, private key, API key
gitNode.js.sshCollect directory and Git repository credentials
schedNode.jsPersistence mechanism by redeploying the initial loader

The C2 server is 103.106.67[.]63 and uses port 1244 for command execution and port 1247 for WebSocket RAT. This IP overlaps with Famous Chollima’s past infrastructure, which is one of the basis for the attribution.

truffleIt’s interesting that the module uses the official security tool TruffleHog as an “attacker’s tool”. The secret scanner used by defenders has been repurposed as an infostealer (information stealing malware).

Attribution confirmed due to OPSEC failure

A Threat Intelligence Report investigation revealed operational security lapses at Famous Chollima. The attackers used single-use email services such as generator.email, emailfake.com, and tempm.com to publish npm packages, but these services had public inboxes.

IP address was exposed from npm publication notification email.

  • 216.227.145.218 — Astrill VPN exit node (high reliability)
  • 193.118.55.19, 193.118.55.77 — hide.me VPN
  • 67.43.59.10 — Astrill VPN
  • 203.160.80.72 — China Unicom ISP space
  • 62.33.223.164 — TransTeleCom ISP space

The same single-use email address also received registration confirmation emails from job platforms such as bayt.com and HireLatam. This confirms that the npm supply chain attack and Contagious Interview’s fake recruitment campaign are operating on the same infrastructure. Consistent IP usage has been confirmed from September 2025 to the end of January 2026.

Associated stager via Google Drive

Apart from StegaBin, a related stager (an intermediate loader that downloads the main body) in a single package called express-core-validator has also been confirmed. This will deliver the next payload via Google Drive. This variant, which uses cloud storage rather than Pastebin steganography, shows Famous Chollima experimenting with multiple distribution channels in parallel.

Comparison with SANDWORM_MODE

When compared to SANDWORM_MODE reported in February, the approach is significantly different from the npm supply chain attack from the same period.

SANDWORM_MODEStegaBin
ActorUnknownFamous Chollima (North Korea)
Number of packages1926
Public account2 accounts26 disposable accounts
C2 Hidingbase64+XOR ObfuscationPastebin Steganography
Delivery InfrastructureCloudflare WorkerVercel 31 Deployment
Automatic propagation3-path worm (npm/GitHub/SSH)None
AI environmental targetingMCP injectionNone
Persistencegit hook + MCP settings tamperingVS Code tasks.json
FeaturesPolymorphic engine (automatically transforms code to avoid detection)Zero-width Unicode character steganography

SANDWORM_MODE specializes in worm propagation and AI tool targeting, while StegaBin focuses on C2 concealment and evasion. Although they share the same general direction of targeting the developer environment, the attack design philosophy is different. The trend of development tools themselves becoming attack surfaces is accelerating.

IOC and countermeasures

TypeValue
C2 server103.106.67[.]63 (port 1244, 1247)
Vercel domain exampleext-checkdin.vercel[.]app
VPN exit node216.227.145.218, 67.43.59.10 (Astrill), 193.118.55.19, 193.118.55.77 (hide.me)

26 packages have been removed from npm, but Famous Chollima has republished successor packages in the past immediately after removal. npm audit only searches for known vulnerabilities registered in the registry, and does not detect malicious code within the package itself.

The following are effective measures:

  • Package analysis before installation with Socket CLI (socket scan npm install <package>)
  • Incorporate a package scanner into your CI pipeline
  • git hook to detect unknown package addition to lockfile
  • Block the IP address of the above IOC with a firewall
  • Check if there are any unfamiliar tasks in tasks.json of VS Code

Up until now, npm supply chain attacks have mainly been worm-type attacks like SANDWORM_MODE and attacks via CI like Clinejection, but StegaBin is new in that it takes so much effort to hide C2. Including URLs in Pastebin essays with zero-width characters exploits a blind spot on the part of defenders who assume static analysis and network monitoring. Famous Chollima’s leak of IP from a public inbox on a single-use email was a goof, but the method itself is becoming more sophisticated. Still, Socket detects it in 2 minutes, so even if you try to hide it well, you can be caught the moment you publish it to a public repository. This group seems to have both the sophistication of their attacks and the sloppyness of their operations.