VDB
GCVE-110-OSM-2026-1240
GCVE-110-OSM-2026-1240
Advisory PublishedCVSS 9.6/10
Custom-built C++ infostealer embedded inside a fully functional casino slot-machine RNG engine, distributed as a precompiled stripped ELF x86-64 shared library (lib/x64.so, 402KB) loaded at runtime via a thin node-addon-api wrapper. When application code calls module.exports.load(), a detached background thread is spawned that silently: (1) fingerprints the host by extracting all network interface MAC addresses via socket()+ioctl(SIOCGIFHWADDR), (2) recursively enumerates the filesystem from an encrypted base path, (3) reads the full contents of encrypted target file paths, (4) harvests an environment variable whose name is encrypted. All collected data is passed to a JavaScript callback (stored at napi_env load time via Startup()) which routes it to a ChaCha20-encrypted WebSocket C2. All C2 hostnames, target file paths, and env var names are encrypted in-place in the .data segment using a per-entry ChaCha20 keystream and cannot be recovered by static analysis alone. The package name 'probity' is itself obfuscated inside the binary as 'qqpajszldz', decoded via an alternating +0xFF/+0x01 byte arithmetic — confirming the binary was purpose-built for this specific npm package.
src/addon.cpp uses dlopen(path, RTLD_LAZY) to load lib/x64.so (Linux) or lib/x64.dll (Windows) and resolves function pointers Action(const char*), Free(const char*). src/index.js calls addon.load('lib/x64.so') then exposes addon.action() as a JSON-in/JSON-out interface implementing a legitimate slot game API (set_options, get_combination, get_session_data). The .so exports three symbols (confirmed by nm -D): Startup (0x21c10), Action (0x37cb0), Free (0x21da0). Startup() stores the napi_env* at global 0x261c98 and a JS callback reference at 0x261c90. A detached pthread (pthread_create confirmed in dynamic symbol table) runs the stealer: MAC extraction via socket(AF_INET,SOCK_DGRAM)+ioctl(0x8912 SIOCGIFCONF, 0x8927 SIOCGIFHWADDR); filesystem traversal via opendir()/readdir() from encrypted path at 0x2616xx; file read via fopen()/fseek(SEEK_END)/ftell()/fread() on two encrypted target paths (10-char at 0x2616c0, 15-char at 0x2616b0); env var harvest via getenv(encrypted_10-char_name_at_0x261703). Exfil: fcn.0002fff0 invokes the stored JS callback (**(**napi_env+0x40))(*0x261c98, 0x261c90, data_string). C2 hostnames are three ChaCha20-encrypted strings in .data at 0x2616e0 (34 chars), 0x2616c0 (10 chars), 0x2616b0 (15 chars) with seed bytes 0x50, 0x6b, 0x6b. Three vtable class names confirmed in binary: GBufferWebsocket, GBufferJson, Chacha20 — indicating WebSocket + ChaCha20-encrypted JSON C2 protocol.
Weaknesses (CWE)
CWE-506Embedded Malicious Code
Risk Scores
CVSS 3.1
9.6/10
Critical · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Affected Products
| Vendor | Product | Versions | Platforms |
|---|---|---|---|
| unknown | probity | 1.2.0 through 1.2.10 (11 versions across 2026-03-30 to 2026-04-01) (affected) | — |
Browse GCVE Records
73,734 records in the GCVE database · Updated July 18, 2026
No matching records found.
Explore Further
Investigate this vulnerability in the interactive console or download the raw GCVE record.