1. Executive summary
Elastic Security Labs documented a new Contagious Interview campaign (tracked as REF9403) deploying OTTERCOOKIE-aligned malware via trojanized coding challenge repositories distributed through developer platforms, including Slack workspaces. The repositories contain fully functional Next.js e-commerce templates laced with steganographic SVG payloads that deploy a four-stage implant: a browser credential and crypto wallet stealer, a file stealer, a Socket.IO-based RAT, and a clipboard stealer. Attribution to the Contagious Interview group (MITRE G1052) is corroborated by code similarity and infrastructure overlap; the broader DPRK attribution is unconfirmed as no MITRE ATT&CK profile exists for that actor in the verified reference data. EMEA financial services face direct risk to developer workstations handling source code, cloud credentials, and production access keys.
2. Regulatory framing
| Article | Trigger (the fact in this item) | Practical impact |
|---|---|---|
| DORA Art. 28: ICT third-party risk — general principles | The attack vector is a trojanized external code repository introduced into the development pipeline via a socially engineered "coding challenge," directly engaging third-party/supply-chain intake controls. | Clients must assess developer procurement of external code repositories as an ICT third-party risk and apply vetting controls before execution on corporate endpoints. |
| NIS2 Art. 21(2)(d): supply chain security measures | The trojanized repositories have zero AV detections and are designed to be executed inside developer environments, directly engaging supply-chain security measures for source code intake. | In-scope NIS2 entities must review and tighten controls around unvetted external code execution on developer machines as part of supply chain security obligations. |
3. Technical analysis & attack chain
Attribution note: The Contagious Interview group is tracked as MITRE G1052. The broader DPRK attribution referenced by Elastic rests on code similarity and infrastructure overlap; however, no MITRE ATT&CK profile exists for "DPRK" in the verified reference data, so that attribution is treated as unconfirmed. This advisory is single-sourced (Elastic Security Labs); verify before enforcement.
Attack chain (confirmed steps)
- Initial access — social engineering: On May 26, 2026, a user named "Maxwell" posted in a community Slack #jobs channel offering e-commerce upgrade work. Interactions were moved to DMs. Targets were given a trojanized repository as a "test challenge."
- Payload delivery — trojanized repository: The repository is a functional Next.js e-commerce template (GoCart, copied from GreatStackDev). Malicious code is inserted with benign variable names. At time of writing, the repositories have zero detections across AV vendors. Known trojanized archive names: -
next-ecommerce-private-main.zip-shopping-platform-main.zip-ecommerce-platform.zip-ecommerce-platform-main.zip-shopping-platform.rar-shop-main.zip-ecommerce-main.zip - Steganographic payload assembly: Base64-encoded payload fragments are embedded in HTML comments inside SVG flag images (e.g.,
AE.svg,AF.svg) in theassets/flags/directory. A JavaScript fileserverValidation.jsreassembles chunks in alphabetical order via avalidation()function that reads all.svgfiles, extracts comment blocks (<!-- ... -->), and joins them. The payload is decoded via a custom Base64 functionCheck()and executed viaeval(), avoidingBuffer.fromandatobdetection. The functionrunServerValidation()is called fromserver/index.json every server start. Bothnpm run devandnpm startlaunchserver/index.js, so the payload executes on boot. - Obfuscation: The malware is protected by obfuscator.io — string array extraction with index-based lookups, self-rotating array for anti-tampering, and an infinite loop using
while (!![]). - Stage 1 — Browser credential and crypto wallet stealer: Process title is set to
npm-cachefor masquerading. Enumerates browser profiles on Windows (%LOCALAPPDATA%), macOS (~/Library/Application Support/), and Linux (~/.config/) for Chrome, Edge, Brave, Opera, LT Browser. ExfiltratesLogin Data,Web Data, andLocal Extension Settingsvia multipart HTTP POST to/uploadonldb.rightwidth[.]dev(User-Agent:axios/1.18.1). Targets 25 crypto wallet browser extensions (full list in §5). The first 8 prioritized wallets receive retry-with-acknowledgment logic via the/cldbsendpoint; remaining wallets use fire-and-forget. On macOS, exfiltrates~/Library/Keychains/login.keychain-db. - Stage 2 — File stealer: On Windows, enumerates drives via
wmic logicaldisk get name; on macOS/Linux, targets home directories. Recursively scans for:*.env*,*.doc,*.docx,*.pdf,*.md,*.rtf,*.odt,*.xls,*.xlsx,*.txt,*.pem,*.ini,*.secret,*.png,*.jpg,*.jpeg,*.webp,*.json,*.ts,*.js,.zsh_history,.bash_history,*.csv. Also collects any file under.aws,.azure,.config,.ssh,.bash_history,.zsh_historyregardless of extension. Files are POSTed unencrypted to/uploadonupload.rightwidth[.]dev. Deliberately excludes AI tooling directories (.claude,.cursor,.gemini,.windsurf) and common framework directories (node_modules,.git,.next,build,dist, etc.). - Stage 3 — Socket.IO RAT: Establishes persistent HTTPS Socket.IO C2 channel to
controller.rightwidth[.]dev. Enforces single-instance via PID lock file atC:\Users\<user>\.npm\vhost.ctl. Performs VM/sandbox detection (Windows:wmic computersystem get model,manufacturerchecking forvmware,virtualbox,qemu,microsoft corporation; macOS:system_profiler SPHardwareDataTypechecking/vmware|virtualbox|qemu|parallels|virtual/; Linux:/proc/cpuinfochecking/hypervisor|vmware|virtualbox|qemu|kvm|xen|parallels|bochs/i). VM tags are sent in C2 response but do not prevent execution. Registration beacon sent to/api/service/process/<uid>with host info. Health logging via/api/service/makelog. Operator sendscommandevents executed viachild_process.exec()with output returned asmessageevents — providing interactive shell access. - Stage 4 — Windows dropper and clipboard stealer: Windows-only dropper downloads three binaries via
curlfromfile.rightwidth[.]devdisguised as.txtfiles, renamed to.exebefore execution:hostService.txt→hostService.exe,printSvc.txt→printSvc.exe,dhcpSvc.txt→dhcpSvc.exe. C2 was unavailable at analysis time; payloads not retrieved and their purpose is unconfirmed. Clipboard stealer polls every 500ms. macOS usespbpaste; Windows usespowershell -NoProfile -NonInteractive Get-Clipboard(spawns new PowerShell process each poll). Clipboard content exfiltrated via POST to/api/service/makelog/onrightwidth[.]dev. Linux clipboard is a no-op (returns null).
Observed API endpoints (matching JFrog Security-linked infrastructure)
/api/service/makelog/api/service/process/<uid>/cldbs/upload
4. Mitigation & containment
P1 — Within 24 hours
- Block the following domains and IPs at DNS, proxy, and firewall layers:
rightwidth[.]dev,ldb.rightwidth[.]dev,upload.rightwidth[.]dev,controller.rightwidth[.]dev,file.rightwidth[.]dev,195.26.248[.]212,188.40.64[.]61. - Search endpoints and developer workstations for the trojanized repository archives (hashes in §5) and quarantine any matches.
- Search EDR/SIEM for processes named
npm-cachethat are not legitimate npm caching operations — this is the masquerading process title used by the credential stealer module. - Search for the PID lock file path
~/.npm/vhost.ctlon developer endpoints — this is the Socket.IO RAT single-instance enforcement mechanism. - Search for PowerShell processes spawned with
-NoProfile -NonInteractive Get-Clipboardat 500ms intervals — this is the clipboard stealer on Windows. - Search for
curldownloads of.txtfiles from external domains followed by rename to.exeand execution — this is the Windows dropper stage.
P2 — Within 72 hours
- Review developer onboarding and external code intake procedures. Prohibit execution of unvetted external repositories on corporate endpoints. Require all external code to pass through CI/CD sandbox and static analysis before local execution.
- Audit developer Slack/Teams/Discord workspaces for unsolicited job offers or coding challenge requests, particularly from users named "Maxwell" or similar ad-hoc accounts.
- Search source code repositories (GitHub, GitLab, internal) for the trojanized archive names listed in §3 — Elastic notes some victims unknowingly pushed backdoored repos to GitHub.
- Search for outbound HTTPS connections to
controller.rightwidth[.]devindicating active Socket.IO RAT sessions — if found, treat the endpoint as compromised and initiate incident response. - Review browser extension inventories on developer endpoints for the 25 targeted crypto wallet extensions listed in §5 and assess whether any are authorized.
P3 — Within 7 days
- Deploy YARA and Sigma rules from §6 to EDR and SIEM platforms.
- Implement network egress filtering to restrict developer endpoints from direct HTTPS connections to newly registered or low-reputation domains.
- Review and tighten DLP controls for sensitive file types targeted by the file stealer (
.env,.pem,.ssh,.aws,.azure) — ensure exfiltration alerts trigger on bulk POST uploads of these file types. - Brief development teams on the Contagious Interview social engineering pattern (fake job offers → coding challenges → trojanized repos).
5. Indicators of compromise
| Type | Value | Confidence | Source |
|---|---|---|---|
| sha256 | 8e571d58794b9b44ae53c2c67bedef72c500e8adbb80aab7a5c263adcba55b1e | High | Elastic Security Labs |
| sha256 | 3e6360f83a95540aa2176d279ca4694513afb1e5116a7ffe591c6b5bcf3b9c3c | High | Elastic Security Labs |
| sha256 | 4e7639045b4a64de60bfb6312951a5c3dffbd3fb04b84837663242ed27f09864 | High | Elastic Security Labs |
| sha256 | 54bf36910d81ab516037cb3d69d7c85190f90aa0da9e58617799c1fc738dc5a9 | High | Elastic Security Labs |
| sha256 | 96357529d17c4690826d5d4c74deac51743a5388733b3f04004d898f0635ef20 | High | Elastic Security Labs |
| sha256 | 9df01d242ef46adfedf8c35cb7cc67b1d27d7dc4a1ce74ab32e984090d579886 | High | Elastic Security Labs |
| sha256 | c5aed4c063d4970a03250778da8041da9e0c83d8f22d2f1994da0ad72567ebd9 | High | Elastic Security Labs |
| sha256 | cc97517f80f567977300450de11e9a0be53f52657525a20b1091c99fe9e45730 | High | Elastic Security Labs |
| sha256 | fb94b2caee2c40635448a98ba0118421e19a400e74ccff73315f8fa42351f53f | High | Elastic Security Labs |
| domain | rightwidth[.]dev | High | Elastic Security Labs |
| domain | ldb.rightwidth[.]dev | High | Elastic Security Labs |
| domain | upload.rightwidth[.]dev | High | Elastic Security Labs |
| domain | controller.rightwidth[.]dev | High | Elastic Security Labs |
| domain | file.rightwidth[.]dev | High | Elastic Security Labs |
| ipv4 | 195.26.248[.]212 | High | Elastic Security Labs |
| ipv4 | 188.40.64[.]61 | High | Elastic Security Labs |
sha256 8e571d58794b9b44ae53c2c67bedef72c500e8adbb80aab7a5c263adcba55b1e
sha256 3e6360f83a95540aa2176d279ca4694513afb1e5116a7ffe591c6b5bcf3b9c3c
sha256 4e7639045b4a64de60bfb6312951a5c3dffbd3fb04b84837663242ed27f09864
sha256 54bf36910d81ab516037cb3d69d7c85190f90aa0da9e58617799c1fc738dc5a9
sha256 96357529d17c4690826d5d4c74deac51743a5388733b3f04004d898f0635ef20
sha256 9df01d242ef46adfedf8c35cb7cc67b1d27d7dc4a1ce74ab32e984090d579886
sha256 c5aed4c063d4970a03250778da8041da9e0c83d8f22d2f1994da0ad72567ebd9
sha256 cc97517f80f567977300450de11e9a0be53f52657525a20b1091c99fe9e45730
sha256 fb94b2caee2c40635448a98ba0118421e19a400e74ccff73315f8fa42351f53f
domain rightwidth[.]dev
domain ldb.rightwidth[.]dev
domain upload.rightwidth[.]dev
domain controller.rightwidth[.]dev
domain file.rightwidth[.]dev
ipv4 195.26.248[.]212
ipv4 188.40.64[.]61
Targeted crypto wallet browser extension IDs (behavioural context — not atomic IOCs)
| Extension ID | Wallet |
|---|---|
| nkbihfbeogaeaoehlefnkodbefgpgknn | MetaMask Wallet |
| acmacodkjbdgmoleebolmdjonilkdbch | Rabby Wallet |
| bfnaelmomeimhlpmgjnjophhpkkoljpa | Phantom Wallet |
| dmkamcknogkgcdfhhbddcghachkejeap | Keplr |
| ejbalbakoplchlghecdalmeeeajnimhm | MetaMask (Edge) |
| ppbibelpcjmhbdihakflkdcoccbgbkpo | UniSat Wallet |
| egjidjbpglichdcondbcbdnbeeppgdph | Trust Wallet |
| ibnejdfjmmkpcnlpebklmnkoeoihofec | TronLink Wallet |
| bhhhlbepdkbapadjdnnojkbgioiodbic | Solflare Wallet |
| omaabbefbmiijedngplfjmnooppbclkk | Tonkeeper |
| khpkpbbcccdmmclmpigdgddabeilkdpd | Sui Wallet |
| fhbohimaelbohpjbbldcngcnapndodjp | BNB Chain Wallet (Binance) |
| aeachknmefphepccionboohckonoeemg | Coin98 |
| hifafgmccdpekplomjjkcfgodnhcellj | Crypto.com Wallet |
| jblndlipeogpafnldhgmapagcccfchpi | Kaia Wallet |
| dlcobpjiigpikoobohmabehhmhfoodbb | Ready Wallet |
| mcohilncbfahbmgdjkbpemcciiolgcge | OKX Wallet |
| agoakfejjabomempkjlepdflaleeobhb | Core Wallet |
| aholpfdialjgjfhomihkjbmgjidlcdno | Exodus Web3 Wallet |
| nphplpgoakhhjchkkhmiggakijnkhfnd | TON Wallet |
| penjlddjkjgpnkllboccdgccekpkcbin | OpenMask (TON) |
| lgmpcpglpngdoalbgeoldeajfclnhafa | SafePal Wallet |
| fldfpgipfncgndfolcbkdeeknbbbnhcc | My TON Wallet |
| gjnckgkfmgmibbkoficdidcljeaaaheg | Atomic Wallet |
| afbcbjpbpfadlkmhmclhkeeodmamcflc | MathWallet |
6. Detection
rule OTTERCOOKIE_Ref9403_Stage1 {
meta:
author = "Adverse Trace"
date = "2026-07-17"
reference = "https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography"
description = "Detects OTTERCOOKIE REF9403 SVG steganography reassembly and eval execution chain"
strings:
$reassembly = "function validation()" ascii
$flags_dir = "assets" ascii
$svg_filter = ".endsWith(\".svg\")" ascii
$comment_regex = "/<!--\\s*([\\s\\S]*?)\\s*-->/" ascii
$check_func = "function Check(" ascii
$eval_call = "eval(Check(validation()))" ascii
$run_validation = "function runServerValidation()" ascii
$npm_cache = "npm-cache" ascii
$axios_ua = "axios/1.18.1" ascii
$cldbs = "/cldbs" ascii
$upload = "/upload" ascii
$makelog = "/api/service/makelog" ascii
$process_uid = "/api/service/process/" ascii
$vhost_ctl = ".npm/vhost.ctl" ascii
$while_inf = "while (!![])" ascii
$wmic_disk = "wmic logicaldisk get name" ascii
$wmic_model = "wmic computersystem get model,manufacturer" ascii
$proc_cpuinfo = "/proc/cpuinfo" ascii
$sys_profiler = "system_profiler SPHardwareDataType" ascii
$pbpaste = "pbpaste" ascii
$get_clipboard = "Get-Clipboard" ascii
$host_svc = "hostService.txt" ascii
$print_svc = "printSvc.txt" ascii
$dhcp_svc = "dhcpSvc.txt" ascii
$keychain = "login.keychain-db" ascii
$login_data = "Login Data" ascii
$web_data = "Web Data" ascii
$local_ext = "Local Extension Settings" ascii
condition:
6 of them
}
title: OTTERCOOKIE REF9403 Clipboard Stealer PowerShell Activity
id: 7a3c1f2e-9b4d-4e8a-a6f1-3c5d7e9b1a02
status: experimental
description: Detects the OTTERCOOKIE clipboard stealer module spawning PowerShell with Get-Clipboard at frequent intervals
author: Adverse Trace
date: 2026/07/17
references:
- https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography
logsource:
product: windows
category: process_creation
detection:
selection_clipboard:
CommandLine|contains|all:
- "-NoProfile"
- "-NonInteractive"
- "Get-Clipboard"
condition: selection_clipboard
falsepositives:
- Legitimate clipboard monitoring tools using PowerShell with these exact flags (rare)
level: high
title: OTTERCOOKIE REF9403 Socket.IO RAT PID Lock File Creation
id: 8b4d2g3f-0c5e-5f9b-b7a2-4d6e8f0c2b13
status: experimental
description: Detects creation of the .npm/vhost.ctl PID lock file used by OTTERCOOKIE Socket.IO RAT for single-instance enforcement
author: Adverse Trace
date: 2026/07/17
references:
- https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography
logsource:
product: windows
category: file_event
detection:
selection_lockfile:
TargetFilename|endswith: ".npm\\vhost.ctl"
condition: selection_lockfile
falsepositives:
- Unlikely — this path is not used by legitimate npm operations
level: critical
title: OTTERCOOKIE REF9403 Windows Dropper Curl Download and Rename
id: 9c5e3h4g-1d6f-6g0c-c8b3-5e7f9a1d3c24
status: experimental
description: Detects curl downloading .txt files from external hosts followed by rename to .exe — pattern matching OTTERCOOKIE Windows dropper stage
author: Adverse Trace
date: 2026/07/17
references:
- https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography
logsource:
product: windows
category: process_creation
detection:
selection_curl:
Image|endswith: "curl.exe"
CommandLine|contains:
- "hostService.txt"
- "printSvc.txt"
- "dhcpSvc.txt"
condition: selection_curl
falsepositives:
- Unlikely — these filenames are not standard for legitimate curl downloads
level: critical
Threat actor context
Contagious Interview · G1052 · aka DeceptiveDevelopment, Gwisin Gang, Tenacious Pungsan, DEV#POPPER, PurpleBravo
Contagious Interview is a North Korea–aligned threat group active since 2023. The group conducts both cyberespionage and financially motivated operations, including the theft of cryptocurrency and user credentials. Contagious Interview targets Windows, Linux, and macOS systems, with a particular focus on individuals engaged in software development and cryptocurrency-related activities.
No MITRE ATT&CK profile for: DPRK.
7. Sources
- Elastic Security Labs, "Contagious Interview malware in SVG images: DPRK campaign," https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography, published 2026-07-18.
8. Adverse Trace position
This is a high-severity threat to EMEA financial services with active developer-targeting operations. The campaign demonstrates mature tradecraft: zero-detection trojanized repositories, steganographic payload concealment in SVG files, multi-platform credential and wallet theft, interactive RAT capability, and deliberate exclusion of AI tooling directories to minimize noise — indicating an actor tuned to the current developer ecosystem. The convergence of BEAVERTAIL and OTTERCOOKIE capabilities into a single all-in-one package without a Python stage increases deployment flexibility and reduces detection surface. Attribution to Contagious Interview (MITRE G1052) is supported by code similarity and infrastructure overlap with prior NTT Security and JFrog reporting; the broader DPRK attribution is unconfirmed per verified reference data. This advisory is single-sourced from Elastic Security Labs — clients should verify IOCs against internal telemetry before enforcement. Adverse Trace will monitor for additional campaign infrastructure, secondary payload retrieval from file.rightwidth[.]dev, and any expansion of targeting beyond developer communities into financial services direct engagement.
Published via PulseTrace — Adverse Trace threat intelligence.