TL;DR
The Glassworm/ForceMemo campaign — active since October 2025 and surging again in March 2026 — weaponizes the Solana blockchain's memo program as a decentralized command-and-control (C2) channel. Malware hidden in GitHub repos, npm packages, and VS Code extensions polls a Solana address every five seconds for encrypted instructions. Because blockchain data is immutable, there's no server to seize and no domain to sinkhole. This post dissects the C2 mechanism, maps the full kill chain, and provides concrete detection and hardening steps for every developer running npm install or pip install from source.
The Kill Chain in Three Phases
Phase 1 — Initial Access: Invisible Unicode in Your Dependencies
Glassworm's signature trick is encoding malicious JavaScript payloads inside invisible Unicode characters (Private Use Area variation selectors U+FE00–U+FE0F and U+E0100–U+E01EF). The injection looks like an empty template literal:
eval(Buffer.from(s(``)).toString('utf-8'));
That backtick string appears empty in every editor, terminal, and GitHub diff view — but it's packed with invisible codepoints. A small decoder converts them back to bytes and passes the result to eval(). No suspicious URLs in the source. No obfuscated strings. Just... nothing visible.
In March 2026, at least 151 GitHub repositories were compromised this way between March 3–9, with expansion to npm (@aifabrix/miso-client, @iflow-mcp/watercrawl-watercrawl-mcp) and VS Code extensions (quartz.quartz-markdown-editor) by March 12.
Phase 2 — Credential Theft: GlassWorm Harvests Everything
Once the invisible payload executes, GlassWorm's stage 3 module harvests:
-
Git credentials:
~/.git-credentials,git credential fill,GITHUB_TOKEN -
NPM tokens:
.npmrcfiles, VS Code extension storage -
SSH keys:
~/.ssh/ - Crypto wallets: Browser extension data, local wallet files
These stolen credentials enable the ForceMemo phase — the attacker uses your own GitHub token to inject malware into all your repositories.
Phase 3 — Propagation: Force-Push with Perfect Camouflage
ForceMemo doesn't open PRs or create new commits. It:
- Takes the latest legitimate commit on the default branch
- Rebases it, appending obfuscated Python malware to
setup.py,main.py, orapp.py - Force-pushes to the default branch
The commit message, author name, and author date are all preserved from the original commit. The only forensic indicator? The committer date doesn't match — often showing a gap of months or years. The committer email is set to "null", a fingerprint of the attacker's tooling.
Hundreds of Python repositories have been compromised this way, including Django apps, ML research code, and PyPI packages.
The Solana C2 Mechanism: Why It's Unkillable
This is the most novel and dangerous part of the campaign. Traditional C2 relies on domains or IPs that defenders can block or seize. Glassworm eliminates that single point of failure.
How It Works
- The malware contains a hardcoded Solana wallet address (e.g.,
BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC) - Every ~5 seconds, it queries this address via multiple Solana RPC endpoints for recent transactions
- It reads the memo field attached to transactions — Solana's Memo Program (
MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr) allows arbitrary UTF-8 data up to 566 bytes per instruction - The memo contains encrypted JSON instructions with payload URLs and commands
- The malware decrypts the memo, downloads the next-stage payload, and executes it
Why Traditional Defenses Fail
| Defense | Why It Fails Against Blockchain C2 |
|---|---|
| Domain takedown | No domain — uses Solana RPC (many public endpoints) |
| IP blocklist | Dozens of public RPC providers; malware rotates between them |
| SSL inspection | Traffic to Solana RPCs looks like normal Web3 API calls |
| Threat intel feeds | The C2 "address" is a blockchain wallet, not a traditional IOC |
| Network sandboxing | Solana RPC traffic may be allowlisted in Web3 dev environments |
The attacker can update C2 instructions by simply sending a new Solana transaction with a memo — costing fractions of a cent and taking ~400ms to propagate globally. The instructions are immutable once written, so even if researchers discover them, they cannot be deleted.
The Geofencing Tell
Before executing, the malware checks the system locale. If a Russian language setting is detected, execution is skipped — a classic indicator of Eastern European cybercrime groups protecting their own region from collateral damage.
Detection: What to Look For
In Your Codebase
1. Search for the invisible Unicode decoder pattern:
# Check for Glassworm's Unicode decoder signature
grep -rn '0xFE00.*0xFE0F.*0xE0100.*0xE01EF' --include='*.js' --include='*.ts' .
# Check for ForceMemo's Python marker variable
grep -rn 'lzcdrtfxyqiplpd' --include='*.py' .
2. Scan for invisible characters in source files:
# Find files containing Unicode variation selectors
find . -name '*.js' -o -name '*.ts' -o -name '*.py' | \
xargs perl -ne 'print \"$ARGV:$.: $_\" if /[\\x{FE00}-\\x{FE0F}\\x{E0100}-\\x{E01EF}]/'
3. Audit git history for force-push indicators:
# Check for author/committer date mismatches (ForceMemo signature)
git log --format='%H author:%ai committer:%ci email:%ce' | \
awk -F'[ T]' '{ split($0, a, \" \"); if (a[2] != a[4]) print \"DATE MISMATCH:\", $0 }'
# Check for committer email \"null\"
git log --format='%H %ce' | grep -i 'null'
In Your Network
4. Monitor for Solana RPC polling patterns:
Suspicious patterns in network logs:
- Repeated POST requests to known Solana RPC endpoints every ~5 seconds
- JSON-RPC method:
getSignaturesForAddressorgetTransaction - From non-Web3 application processes
Known RPC endpoints to monitor:
api.mainnet-beta.solana.comsolana-mainnet.g.alchemy.comrpc.ankr.com/solanamainnet.helius-rpc.com
5. Watch for the specific C2 wallet address:
Add BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC to your network monitoring IOC list. Any process querying this address is compromised.
Hardening: A Defense-in-Depth Checklist
For Individual Developers
- Enable branch protection rules on all repos — require PR reviews, disable force-pushes to default branches
-
Enable GitHub's commit signing (
git config commit.gpgsign true) — unsigned commits from your account become instantly suspicious - Rotate all tokens if you've installed any VS Code/Cursor extension from an untrusted source in the past 6 months
- Audit installed extensions — remove anything you don't actively use; check extension publisher verification status
-
Use lockfiles religiously —
package-lock.json,yarn.lock,poetry.lock— and review diffs on update -
Never
pip installfrom GitHub default branches without verifying the latest commit
For Teams and Organizations
- Deploy a supply chain firewall — tools like Socket, Aikido Safe Chain, or Snyk can detect malicious packages before installation
- Add invisible-character linting to CI — reject PRs containing PUA Unicode characters in source files
- Monitor git push events via GitHub audit log — alert on force-pushes to protected branches
- Segment network access — CI/CD runners and dev machines shouldn't need Solana RPC access unless you're building Web3 applications
- Implement egress filtering — block or alert on JSON-RPC calls to Solana mainnet endpoints from non-Web3 services
For Web3 Teams (Who Actually Need Solana RPC Access)
- Allowlist specific Solana addresses your applications interact with — alert on queries to unknown wallet addresses
- Use your own RPC node or a single authenticated RPC provider — easier to monitor and audit
- Separate Web3 development environments from general-purpose dev environments
The Bigger Picture: Blockchain as Adversary Infrastructure
Glassworm represents a paradigm shift in supply chain attacks. By using an immutable, decentralized, censorship-resistant blockchain as C2 infrastructure, the attackers have created a communication channel that:
- Cannot be taken down by any single authority
- Costs almost nothing to operate (~$0.00025 per transaction on Solana)
- Looks like legitimate traffic in Web3 development environments
- Provides global propagation in under a second
- Leaves an immutable audit trail — ironically making it easier for researchers to study, but impossible to remediate at the infrastructure level
We should expect this technique to spread to other blockchains. Ethereum calldata, Arweave storage, IPFS pinning — any decentralized data layer can serve as a dead-drop for C2 instructions.
IOCs
| Type | Value |
|---|---|
| Solana C2 Address | BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC |
| Python Marker Variable | lzcdrtfxyqiplpd |
| XOR Key (Python payload) | 134 |
| Committer Email (ForceMemo) | null |
| Unicode Range (JS payload) |
U+FE00–U+FE0F, U+E0100–U+E01EF
|
References
- StepSecurity: ForceMemo — Hundreds of GitHub Python Repos Compromised
- Aikido Security: Glassworm Returns — Invisible Unicode Attacks
- BleepingComputer: Glassworm Malware Hits 400+ Code Repos
- SecurityWeek: ForceMemo Attack Targets Python Repositories
This article is part of an ongoing series on Web3 security research at DreamWork Security.
Top comments (0)