VDB
GCVE-110-OSM-2026-14803
GCVE-110-OSM-2026-14803
Advisory PublishedCVSS 8.8/10
Contagious interview targeting blockchain developers delivers infostealer/RAT via blockchain.
A malicious NodeJS-based Solidity/Hardhat project contains an obfuscated JavaScript blob hidden in a fake SVG file, `public/404.svg`. At runtime it downloads and installs a persistent cross-platform RAT/stealer via a multi-phase TRON → BSC blockchain dead drop, which steals crypto wallets, browser passwords and cookies, SSH keys, `.env` files and `.aws` files.
### Details
- **Lure:** a recruiter persona sends a GitHub collaborator invitation to a take-home exercise repo: Express API, ethers, Hardhat `TestToken` contract, README `fails all 7 tests on purpose`. npm-based but not published to npm.
- **Trigger:** `src/middleware/notFound.js` runs `require("../../public/404.svg")` when the server starts (`npm start`, `npm run dev`, pm2). `npm install`, compiling and contract tests trigger nothing.
- **Concealment:** the `.svg` is obfuscated JavaScript below ~24,600 blank lines, so it looks empty in an editor and on GitHub; GitHub code search does not surface it.
- **Chain:** stage 1 drops a loader in `~/.vs_cache/`; the loader reads the latest TRON transaction, follows it to a BSC transaction and runs the decoded payload with full Node access. One new TRON post rotates the payload for every infected host.
- **Payloads:** five posted 2026-09-03 to 09-15: one full RAT/stealer (remote shell, file access, credential and wallet theft, persistence on Windows, macOS and Linux, optional remote-control client) and four small loaders that fetch a further stage from rotating C2 IPs.
- **Attribution:** tradecraft matches public reporting on "Contagious Interview". This report makes no attribution.
- **Scope:** 7 repositories, 4 operator accounts (3 users, 1 org) plus 1 associated account, and 4 builds of `404[.]svg`.
- **Verified depth:** the stage 2 loader, keys and wallets were decoded from build `846fd25c` (`berinity-org/solidity`) only. The other three builds share the trigger and padding; their keys and wallets are unverified.
## Technical breakdown
**Trigger.** `src/app.js` requires `src/middleware/notFound.js` at load, which does `const notFoundImage = require("../../public/404.svg");`. Node evaluates the `.svg` as CommonJS on server start (`npm start`, `npm run dev`, pm2). The server keeps working normally. `npm install` alone triggers nothing (no lifecycle scripts).
**Stage 1: dropper (`public/404.svg`).**
- Obfuscated JavaScript below ~24,600 blank lines and ~37,800 spaces (build `846fd25c`), so the file looks empty in an editor and on GitHub.
- Creates `~/.vs_cache/`, writes `main[.]js` (stage 2, obfuscated) and `package[.]json`.
- Runs `npm install` hidden, via the `npm-cli[.]js` next to the running `node` binary. Dependencies: `axios`, `better-sqlite3@13.0.3`, `node-machine-id`, `socket.io-client`; on Windows also `@primno/dpapi`, `koffi@3.1.2`.
- Launches `main[.]js` detached. Windows: writes `main[.]vbs` and runs `wscript[.]exe //B main[.]vbs`.
**Stage 2: dead-drop loader (`~/.vs_cache/main.js`).**
1. TronGrid: latest confirmed outgoing transaction of TRON `TBMcSRezuxdoNEC8gD3uS4GQVGvybYU4UU` (`only_from=true&limit=1`, attacker's API key in header). Memo hex → swap halves → hex-decode → BSC tx hash.
2. BSC JSON-RPC `eth_getTransactionByHash` (`bsc-dataseed[.]binance[.]org`, fallback `bsc-rpc[.]publicnode[.]com`); payload is the tx `input`.
3. Hex-decode → reverse → XOR with `02e4f3e7-9442-4f9c-a6f4-4fa136605d1c`; if prefixed `BCGZ1|`, base64 + gunzip.
4. Replace the placeholder `9999` → `106` (campaign/affiliate client ID) and `__SESSION_TOKEN__` → `1460d20e7505bb18`; run with `new Function("require","module","exports","__dirname","__filename", code)`.
5. Errors go to `~/.vs_cache/loader.log` (tag `blockchain loader`).
The latest TRON post wins, so one transaction rotates the payload for every new launch.
**Stage 3: chain payloads** (BSC sender `0x4f145ea9b91a73acc9c6a61922cb12414e4358b2`, data-only transactions to the burn address `0x000000000000000000000000000000000000dEaD`):
| Posted (UTC) | BSC tx | Kind | C2 |
|---|---|---|---|
| 2026-09-03 08:55 | `0xb26f7e5f…520094d` | Full RAT/stealer (self-reported version `1.5.2`), ~162 KB | `38[.]92[.]47[.]164:5000`, `:5056`; `5[.]175[.]213[.]135:3011` |
| 2026-09-03 12:25 | `0x933b70be…a399e4` | Session fetcher | `38[.]92[.]47[.]164:5000` |
| 2026-09-07 06:27 | `0xc5368c2f…956ee1` | Session fetcher | `45[.]43[.]11[.]224:80` |
| 2026-09-08 06:13 | `0x8080681d…ebabb6` | Obfuscated "tiny loader" | `45[.]43[.]11[.]224:80` |
| 2026-09-15 06:27 (latest) | `0xbf3fa7a3…5fca9f` | Obfuscated "tiny loader" | `138[.]226[.]247[.]152:80` |
All four small loaders ("session fetcher" and "tiny loader" are their own log tags) `GET hxxp://<C2>/session/1460d20e7505bb18` over plain HTTP and run the response (raw JS or JSON `{"sessions": "<js>"}`) with `new Function`. Errors log with tag `tiny loader`. Stage 4 was not retrieved.
**RAT capabilities (09-03 payload, read statically).**
- socket[.]io C2 events: `client_data`, `exec_result`, `dir_result`, `file_content`, `search_result`, `ssh_status`, `pc_perf` (remote shell, file browse/read/search, telemetry).
- Upload/download endpoints on `:5056`: `/download-app`, `/download-win-key`, `/download-client-portable`, `/download-elev-helper`, `/upload`, `/file-upload`, `/content-upload`.
- Targets (string-level): `.env`, `.ssh`, `.aws`, browser cookies and `Login Data`, Chrome `Local State`, macOS Keychain, MetaMask (`nkbihfbeogaeaoehlefnkodbefgpgknn`), Exodus, Electrum, Atomic, Phantom, screenshots.
- Windows DPAPI theft via a one-shot SYSTEM scheduled task (created and deleted); downloads `win_key_agent.js` and an elevation helper.
- Persistence: Windows HKCU Run `Microsoft Realtime Agreegator` [sic] → `wscript[.]exe %USERPROFILE%\.vs_cache\main.vbs`; macOS LaunchAgent `com[.]AppleAccountSync[.]plist` + hidden `AppleAccountSync[.]app`; Linux `~/.config/autostart/unixkernalloader.desktop` [sic].
- `TakePC` (a RAT command, Windows only): downloads a portable client zip and installs `Service[.]exe`, `client32[.]ini`, `cksini[.]exe` to `%LOCALAPPDATA%\Microsoft\Windows\SettingSync\Caches\{8F7A2C1E-9B4D-4E6A-A3C8-1D5E7F90B2C4}\Win32\ResCache\`, with Run value `SettingSyncResCache` → `ResCache[.]vbs`. `client32[.]ini` is the NetSupport Manager config name (inferred from the file name; binary not captured).
- Victim geolocation via `ip-api[.]com/json`, `freeipapi[.]com/api/json`. Self-delete routine present.
## Malicious repositories
All have `require("../../public/404.svg")` on line 1 of `src/middleware/notFound.js`. README phrase shared by all: `fails all 7 tests on purpose`. A "build" here is one distinct `404[.]svg`, named by its git blob SHA-1 (first 8 hex); SHA-256s are under File hashes.
| Repo | Repo ID | Created (UTC) | `404[.]svg` git blob (build) | Size (B) |
|---|---|---|---|---|
| `hxxps://github[.]com/berinity-org/solidity` | 1429787044 | 2026-10-22 13:29 | `846fd25c09ae9210ad32ae2644edf6baad383242` | 92,416 |
| `hxxps://github[.]com/marianroser/solidity` | 1354498867 | 2026-09-02 08:04 | `1f7eeeec1a823286ebf32d56d50bd9641834fc2b` | 99,609 |
| `hxxps://github[.]com/marianroser/solidity-test` | 1409462427 | 2026-10-07 22:54 | `d86f0658266a858b9d5348a3431bc25475f1d119` | 117,021 |
| `hxxps://github[.]com/marianroser/test` | 1409463451 | 2026-10-07 22:56 | `d86f0658266a858b9d5348a3431bc25475f1d119` | 117,021 |
| `hxxps://github[.]com/hidranoaureo/solidity` | 1409514023 | 2026-10-08 00:16 | `d86f0658266a858b9d5348a3431bc25475f1d119` | 117,021 |
Two further copies sit in accounts of developers who appear to be targets (one with build `d86f0658`, one with build `c087e5d889951645e8b1871f4289c8ade9e2bdc6`, 94,058 B, created 2026-11-04). Withheld here to protect them; available to platform trust-and-safety on request.
Related, not a lure: `marianroser/berinity` (fake company site source), `marianroser/Cubix` (NovaChain Hub site), `marianroser/defi-demo`.
## Accounts
| Account | ID | Role | Evidence |
|---|---|---|---|
| `DaWithCentaur` | 340081843 | Recruiter / sender of invitations | Created 2026-10-09. Sent collaborator invitations to `berinity-org/solidity`; four developers accepted 2026-10-27 to 10-30. Its public event feed shows it made `berinity-org/solidity` public at creation (`PublicEvent`, 2026-10-22 13:29:08), indicating admin rights on the org. Commit author email on its own profile repo: `abubakarharunanng215@gmail.com`. |
| `berinity-org` (org) | 346380819 | Lure host | Created 2026-10-22, 33 min before its only repo. Profile: `berinity[.]com`, `hello@berinity.com`. Single squashed commit authored as `gitlab <gitlab@gitlab.com>`, a generic identity; GitHub maps that email to the account `GitlabJoin`, which has no other link to this activity. |
| `marianroser` | 302610104 | Lure builder | Created 2026-07-11. Earliest lure; 3 lures; operator edits under the git default `Your Name <you@example.com>`; commit author email `marianrosemonte65@gmail.com`. Owns the fake-company site repos. |
| `hidranoaureo` | 326645230 | Sock puppet | Created 2026-09-08. Only repo is a lure sharing commit `ed995f6732bbb864174370bb465203ea9a92619e` with `marianroser/solidity-test`. |
| `dantelabs-bdm` | — | Possibly associated (account now 404) | On 2026-11-07 GitHub mapped `hidranomagica@outlook.com` (author email of `marianroser/berinity`'s first commit) to this login. The email-to-login mapping is the only link; unconfirmed. |
Gmail addresses above are commit-author emails seen in the repos; ownership by a real person is not established.
**Commit author personas** (invented names in commit metadata, no linked GitHub accounts): "Sarah Chen" `sarah@blockvion.com`, `blaize@blockvion.com`; "Amira Hassan" `amira@blockvion.com`; "Hidrano Magica" `hidranomagica@outlook.com`.
**Other lead:** GitLab user `cryptobucket26` (clone URL in `marianroser/defi-demo`).
## Indicators
**Domains and email (fake fronts and personas)**
- `berinity[.]com` (Berinity Labs), `novachainhub[.]com` (NovaChain Hub), `blockvion[.]com` (persona emails)
- `hello@berinity.com`, `hello@novachainhub.com`, `sarah@blockvion.com`, `blaize@blockvion.com`, `amira@blockvion.com`, `hidranomagica@outlook.com`, `marianrosemonte65@gmail.com`, `abubakarharunanng215@gmail.com`
**C2 / infrastructure**
- `38[.]92[.]47[.]164` (5000 socket[.]io + session; 5056 download/upload)
- `5[.]175[.]213[.]135:3011`
- `45[.]43[.]11[.]224:80`
- `138[.]226[.]247[.]152:80` (current per the latest chain post, 2026-09-15; wallet read 2026-11-07)
- C2 path: `/session/1460d20e7505bb18`
- Abused legitimate services (anomalous from `node`): `api[.]trongrid[.]io`, `bsc-dataseed[.]binance[.]org`, `bsc-rpc[.]publicnode[.]com`, `ip-api[.]com`, `freeipapi[.]com`
**Wallets**
- TRON `TBMcSRezuxdoNEC8gD3uS4GQVGvybYU4UU` (dead-drop index; 5 outgoing txs 2026-09-03 to 09-15)
- BSC `0x4f145ea9b91a73acc9c6a61922cb12414e4358b2` (payload poster)
- BSC payload txs: `0xb26f7e5fb047f399ea207f2f46d9d03e4fac8d8f9d63695daf9c61483520094d`, `0x933b70be9cba4e8d4c79603cd760409ef16b1c4bb37a700167e8c283efa399e4`, `0xc5368c2fec126ff648e4bf20ac69337e043111a1fba063df987136d021956ee1`, `0x8080681d6cd1db72cf7fe283c8236723509372df76e9a02a8778baf0e4ebabb6`, `0xbf3fa7a35ab2ee7e243134f39e367b8774d32810fd9b66355c8eba135b2fca9f`
**File hashes (SHA-256)**
| File | SHA-256 |
|---|---|
| `404[.]svg` build `846fd25c` (berinity-org) | `61fea60bd62fe5cb714581c146b2966e139d10b37bf040f4330b50c765cd47cf` |
| `404[.]svg` build `1f7eeeec` | `d779d67cba4eed17f3e7c97cec0c9fcc9bf26c68ce3359666b00de45e97e0999` |
| `404[.]svg` build `d86f0658` | `1336efc845b5a4f2979f0658ecf1c3915497ff9c560b14db3d5cf48e160762b2` |
| `404[.]svg` build `c087e5d8` | `2b8914f75d3dd67d47a1dd76ea605b388e34b3a1f42720ba4e6fc4fcfe632b81` |
| Stage 2 `~/.vs_cache/main.js` as written by build `846fd25c` (reconstructed statically from stage 1) | `5c9857d15e0ed51995a6162e4d70030d777321886aa5b8802e6a8c19b4fec7ff` |
| Chain payload `b26f…` decoded (RAT) | `140664ba522dfb53baaa17bfc75ae1e487a3f3b2446e665976160b99941415b0` |
| Chain payload `933b…` decoded | `9766914f60c23ac9f6fa6b10b482cc08b97f7b917a9117180d43ff2602369aa2` |
| Chain payload `c536…` decoded | `2d17c314119e5f2b39632227e2d592b032b8d939a5f4c74a9dfbddc6e1420aa0` |
| Chain payload `8080…` decoded | `86aff4317ed17b161862be5dd236c111ca9eba963704027f272ed40fc58a4c2a` |
| Chain payload `bf3f…` decoded | `1856068cc3960e23df6ef4f8599332e30a58154f1dbb243e0839594e32e6648a` |
Only build `846fd25c` was deobfuscated; the other three builds' wallets and keys are unverified.
**Samples:** all of the above available on request as 7z AES-256 archives (password `infected`).
**Host artifacts**
- `~/.vs_cache/` (`main[.]js`, `main[.]vbs`, `package[.]json`, `node_modules/`, `loader[.]log`, `log[.]log`, `main[.]js[.]pending`); `win_key_agent.js`
- Windows Run values `Microsoft Realtime Agreegator` [sic], `SettingSyncResCache` (cleanup code also removes `NvidiaDriverUpdate`, `VScode[.]Update[.]Publisher`)
- `%LOCALAPPDATA%\Microsoft\Windows\SettingSync\Caches\{8F7A2C1E-9B4D-4E6A-A3C8-1D5E7F90B2C4}\Win32\ResCache\`
- `~/Library/LaunchAgents/com.AppleAccountSync.plist`, `~/Library/Application Support/AppleAccountSync/`
- `~/.config/autostart/unixkernalloader.desktop`, `~/.local/share/unixkernalloader/` [sic]
- Processes: `wscript[.]exe //B …\.vs_cache\main.vbs`, `node …/.vs_cache/main.js`; env `VS_BACKUP_CHILD`, `VS_BACKUP_FORCE_RUN`
**Embedded secrets:** TronGrid API key `0abf12d7-601d-4565-bba3-7f94d807468c`; XOR key `02e4f3e7-9442-4f9c-a6f4-4fa136605d1c`; marker `BCGZ1|`; session token `1460d20e7505bb18`; campaign/affiliate client ID `106`.
## Timeline (UTC)
| Date | Event |
|---|---|
| 2026-07-11 | `marianroser` created |
| 2026-08-31 | Earliest lure base commit ("Sarah Chen", `blockvion`) |
| 2026-09-02 | `marianroser/solidity`, earliest lure repo |
| 2026-09-03 to 09-15 | Five chain payloads posted; C2 rotates `38[.]92[.]47[.]164` → `45[.]43[.]11[.]224` → `138[.]226[.]247[.]152` |
| 2026-10-07/08 | `marianroser/solidity-test`, `marianroser/test`, `hidranoaureo/solidity` created within 82 minutes |
| 2026-10-09 | `DaWithCentaur` created |
| 2026-10-22 | `berinity-org` and `berinity-org/solidity` created |
| 2026-10-27 to 10-30 | Four invited developers accept collaborator invitations to `berinity-org/solidity` |
| 2026-11-04 | Newest known lure copy (withheld target-owned repo) |
## Detection
- Repo: a `.svg` (or other asset) loaded with `require(...)` from server code; a "small" asset of 90–120 KB starting with blank lines rather than `<svg`.
- Host: `node` or `wscript[.]exe` with `.vs_cache` in the command line; `npm install` spawned by `node`; `node` contacting TronGrid or BSC RPC.
- Network: plain-HTTP `GET /session/<16 hex>` to a bare IP on port 80.
- GitHub code search does not surface these files (padding); README-phrase and commit-email searches do.
Weaknesses (CWE)
CWE-506Embedded Malicious Code
Risk Scores
CVSS 3.1
8.8/10
High · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Affected Products
| Vendor | Product | Versions | Platforms |
|---|---|---|---|
| unknown | all (affected) | — |
References
Browse GCVE Records
851 records in the GCVE database · Updated November 12, 2026
No matching records found.
Explore Further
Investigate this vulnerability in the interactive console or download the raw GCVE record.