Skip to main content
Blog

Flags, Fake Jobs, and Fileless Payloads: Inside DPRK's SVG-Steganography Contagious Interview Campaign

  • July 21, 2026
  • 0 replies
  • 4 views
Aaron Beardslee
Forum|alt.badge.img

Overview

On May 26, 2026, a user calling themselves "Maxwell" posted in the #jobs channel of Elastic's public community Slack workspace, claiming to be upgrading an e-commerce platform to "a modern, scalable architecture using Next.js (v14), NestJS, PostgreSQL, and Auth.js" and looking for an experienced developer to help. Interested developers were moved into direct messages and asked to complete a take-home coding assessment -- a familiar Contagious Interview playbook that has been running since at least December 2022.

What was not familiar was how the payload was hidden. Elastic Security Labs, which discovered the campaign after the actor targeted its own Slack community, found that the malicious code was split into Base64-encoded fragments and stashed inside HTML comments across every SVG "flag" image (AE.svg, AF.svg, and so on) bundled into the trojanized repository's assets directory. A helper script reassembled the fragments in alphabetical order and eval()'d the result on every server start. Elastic states this specific infection chain "has not been previously documented," and that none of the trojanized archives were flagged by any antivirus vendor at the time of publication.

Elastic tracks this activity cluster as REF9403 and assesses the payload as OTTERCOOKIE-aligned. This campaign is seeing active exploitation, nation-state (DPRK) attribution, and 13 associated indicators of compromise (nine file hashes, four C2 domains).


Threat Actor Profile

Contagious Interview (also referenced in industry reporting alongside the malware families BEAVERTAIL and OTTERCOOKIE) is a DPRK-aligned social engineering and malware operation that has run continuously since at least late 2022, with the goal of compromising individual software developers to steal credentials, source code, and cryptocurrency, and to establish footholds that can cascade into broader supply chain compromise. Microsoft documented the campaign's fake-interview tradecraft in a March 11, 2026 writeup, and NTT Security first disclosed OTTERCOOKIE in December 2024.

Elastic's assessment is that the group's toolset has been converging: historically, BEAVERTAIL served as a first-stage stealer/downloader while OTTERCOOKIE operated as a later-stage, C2-driven infostealer and RAT. In the samples analyzed for this campaign, Elastic observed a consolidated, all-in-one package -- a Socket.IO-based RAT, clipboard stealer, and combined credential/wallet/file stealer -- with no separate Python stage, leading Elastic to lean toward the OTTERCOOKIE naming convention while noting the boundary between the two families "is no longer clear."

The operation also shares infrastructure and code-level overlap with a separate but related DPRK campaign distributing malicious npm packages masquerading as Rollup polyfill tooling, identified by JFrog Security research, indicating the actor is running multiple propagation vectors in parallel: open-source package registries and direct social-engineering delivery through developer-facing forums.

Victimology: Individual software developers and open-source contributors, reached through public developer communities (Slack workspaces, freelance job boards, and similar forums) rather than any single named organization. Elastic found no evidence the lure was targeted specifically at Elastic's users -- any developer-facing open forum is a potential watering hole.


Attack Chain

Stage 1 -- Social Engineering and Lure Delivery

The actor posts a fabricated, plausible-sounding freelance or contract developer job listing in a public forum (in this case, a vendor's community Slack #jobs channel), then moves promising conversations into direct messages. The victim is asked to complete a "coding challenge" or take-home assignment as a condition of the job offer -- a long-standing Contagious Interview tactic.

Stage 2 -- Trojanized Repository Delivery

The victim receives a link to, or archive of, a repository that is a copy of a legitimate open-source project (in this case, the GoCart Next.js e-commerce template by GreatStackDev). The actor has inserted small snippets of malicious code at scattered points in the codebase and used benign-sounding variable names to blend in. Observed archive names distributed in this wave include next-ecommerce-private-main.zip, shopping-platform-main.zip, ecommerce-platform.zip, ecommerce-platform-main.zip, shopping-platform.rar, shop-main.zip, and ecommerce-main.zip.

Stage 3 -- Steganographic Payload Storage

The actual malicious payload never appears in the JavaScript source as a readable blob. Instead it is split into Base64 fragments and embedded inside HTML comments within every SVG country-flag image under the project's assets/flags directory. Each flag file otherwise renders normally as a country flag image, so a visual or cursory code review would not surface anything unusual.

Stage 4 -- Reassembly and Execution

A bundled file, serverValidation.js, reads every .svg file in the flags directory in alphabetical order, extracts the HTML comment from each, concatenates the fragments, and returns the joined string. A second function, Check(), performs custom Base64 decoding on the reassembled data, and the result is passed directly to eval() -- deliberately avoiding Buffer.from or atob() calls that simple static or behavioral rules might flag. The project's package.json wires this into both npm run dev and npm start, so server/index.js invokes the reassembly-and-eval routine on every single server boot, guaranteeing repeated execution as the developer works on the "assignment."

Stage 5 -- Payload Execution: Four Concurrent Modules

Once decoded and evaluated, four modules launch:

  1. Browser credential and crypto-wallet stealer. Sets its process title to npm-cache to blend into Task Manager/process listings. Enumerates Chrome, Edge, Brave, Opera, and "LT Browser" profile paths across Windows, macOS, and Linux, exfiltrating saved logins, autofill data, and 25 named cryptocurrency wallet browser-extension datastores (MetaMask, Phantom, Trust Wallet, and others) via multipart HTTP POST to ldb.rightwidth[.]dev/upload and /cldbs, using the user agent axios/1.18.1. On macOS, the system keychain (~/Library/Keychains/login.keychain-db) is also collected.
  2. File stealer. Recursively sweeps mounted drives (enumerated via wmic logicaldisk get name on Windows) or home directories (macOS/Linux) for files matching a broad glob list (.env*, .doc(x), .pdf, .pem, .json, .ts, .js, shell history files, and more), plus anything under credential-store paths such as .aws, .azure, .ssh. Matches are uploaded unencrypted via POST to upload.rightwidth[.]dev/upload. The exclusion list is notably curated to skip AI coding-assistant directories (.claude, .cursor, .gemini, .windsurf, .pearai) -- not to protect them, but to reduce exfiltration noise and focus signal on higher-value targets.
  3. Socket.IO-based RAT. Establishes a persistent Socket.IO channel over HTTPS to controller.rightwidth[.]dev, enforcing single-instance execution via a PID lock file (observed at C:\Users\<user>\.npm\vhost.ctl). Performs VM/sandbox detection (checking for vmware, virtualbox, qemu, and similar strings via wmic, system_profiler, or /proc/cpuinfo depending on OS) and tags -- but does not block -- suspected sandbox hosts in its C2 check-in, likely to help the operator prioritize real victims. Registers new victims via /api/service/process/<uid> and reports implant health via /api/service/makelog. Operator-issued command events are executed via child_process.exec(), giving interactive remote shell access.
  4. Clipboard stealer and Windows dropper. Polls the clipboard every 500ms (pbpaste on macOS, a fresh Get-Clipboard PowerShell process on Windows) and exfiltrates changes to rightwidth[.]dev/api/service/makelog/. On Windows only, this module also downloads three additional binaries via curl from file.rightwidth[.]dev, disguised as .txt files (hostService.txt, printSvc.txt, dhcpSvc.txt) and renamed to .exe before execution. Elastic was unable to retrieve these second-stage binaries because the C2 was unavailable at analysis time, so their exact capability remains unconfirmed.

Defense Evasion

The JavaScript payload is packed with obfuscator.io, using string-array extraction with index-based lookups, a self-rotating anti-tampering array, and infinite-loop toolmarks (while (!![])) -- all standard commodity JS obfuscation, but combined here with the SVG steganography to defeat both static file-content scanning and casual code review.


Timeline

Date Event
December 2022 Contagious Interview campaign family first begins operating (per prior public reporting).
September 2024 OTTERCOOKIE malware family first emerges (per Hacker News reporting on OTTERCOOKIE v4).
December 2024 NTT Security first publicly documents OTTERCOOKIE.
March 11, 2026 Microsoft publishes writeup on Contagious Interview fake developer job interview tradecraft.
May 26, 2026 "Maxwell" posts fake e-commerce developer job listing in Elastic's community Slack #jobs channel; victims moved to DMs and given a trojanized coding-challenge repository.
July 2026 (undated, pre-publication) JFrog Security links related infrastructure/API endpoint patterns to a separate DPRK npm "Rollup polyfill" masquerading campaign.
July 17-18, 2026 Elastic Security Labs publishes full technical findings (tracked as REF9403); The Hacker News and other outlets syndicate coverage.
July 18, 2026 Campaign flagged High risk in internal Morning Threat Intelligence Brief with 13 associated IOCs.

Detection Guidance

Network Layer

  • C2 domain resolution/traffic: Alert on any DNS resolution or HTTP(S)/proxy traffic to rightwidth[.]dev or its subdomains ldb.rightwidth[.]dev, upload.rightwidth[.]dev, controller.rightwidth[.]dev, and file.rightwidth[.]dev. See DRAFT_PXY-NEW09-RUN.yml.
  • Known API endpoint paths: Independent of domain, watch for outbound requests to the path patterns /api/service/makelog, /api/service/process/<uid>, /cldbs, and /upload -- these endpoint names have also been linked by JFrog to the related Rollup-polyfill npm campaign, suggesting they may recur across future infrastructure changes.
  • Ingress tool transfer via curl: Flag curl process invocations that reference the rightwidth[.]dev domain family, particularly where the retrieved file has a .txt extension but is subsequently renamed and executed as .exe. See DRAFT_EDR-NEW14-RUN.yml.

Process / Endpoint Layer

  • Process masquerading: Alert on processes with title/name npm-cache that do not correspond to an actual npm cache-verification workflow, particularly when observed alongside outbound connections to non-npm-registry infrastructure.
  • Known trojanized archive hashes: Match file-write/download telemetry against the nine SHA-256 hashes for the identified trojanized repository archives. See DRAFT_EDR-NEW13-RUN.yml. Treat this as perishable coverage -- zero AV vendors detected these samples at time of publication, and file/archive names are generic and likely to be rotated in future waves.
  • Node.js reassembly-and-eval pattern: Where source-level or runtime JS instrumentation is available, flag Node.js server processes that read and eval() content dynamically reconstructed from image file contents/comments -- an unusual and high-signal behavior for a production or development server process.
  • Suspicious WMI/system enumeration paired with Node.js: wmic logicaldisk get name, wmic computersystem get model,manufacturer, and repeated Get-Clipboard PowerShell invocations (every ~500ms) spawned from or alongside a Node.js parent process are anomalous and worth correlating.
  • PID lock file artifact: The RAT module's single-instance lock file was observed at %USERPROFILE%\.npm\vhost.ctl -- an atypical path for legitimate npm operations and worth a targeted file-creation watch.

Identity / Credential Layer

  • Browser credential store access from Node.js processes: Alert on Node.js or related development-tooling processes reading Chrome/Edge/Brave/Opera Login Data, Web Data, or Local Extension Settings files outside of expected browser-automation/testing workflows.
  • Cryptocurrency wallet extension data access: Monitor for reads of the LevelDB stores associated with the 25 targeted wallet extension IDs (MetaMask, Phantom, Trust Wallet, Rabby, and others) from non-browser processes.
  • macOS keychain access: Flag non-standard process access to ~/Library/Keychains/login.keychain-db.

Indicators of Compromise

Network

Type Indicator Notes
Domain rightwidth[.]dev Root C2 domain; clipboard exfil via /api/service/makelog/
Domain ldb.rightwidth[.]dev Browser credential + crypto wallet stealer C2 (/upload, /cldbs)
Domain upload.rightwidth[.]dev File-stealer exfiltration endpoint (/upload)
Domain controller.rightwidth[.]dev Socket.IO RAT registration/beacon (/api/service/process/<uid>, /api/service/makelog)
Domain file.rightwidth[.]dev Windows second-stage binary staging host
IPv4 195.26.248[.]212 OTTERCOOKIE C2 server (per Elastic)
IPv4 188.40.64[.]61 OTTERCOOKIE C2 server (per Elastic)

File Hashes (SHA-256)

Hash Associated File
3e6360f83a95540aa2176d279ca4694513afb1e5116a7ffe591c6b5bcf3b9c3c next-ecommerce-private-main.zip
4e7639045b4a64de60bfb6312951a5c3dffbd3fb04b84837663242ed27f09864 shopping-platform-main.zip
54bf36910d81ab516037cb3d69d7c85190f90aa0da9e58617799c1fc738dc5a9 ecommerce-platform.zip
8e571d58794b9b44ae53c2c67bedef72c500e8adbb80aab7a5c263adcba55b1e ecommerce-main.zip
96357529d17c4690826d5d4c74deac51743a5388733b3f04004d898f0635ef20 shop-main.zip
9df01d242ef46adfedf8c35cb7cc67b1d27d7dc4a1ce74ab32e984090d579886 ecommerce-platform-main.zip
c5aed4c063d4970a03250778da8041da9e0c83d8f22d2f1994da0ad72567ebd9 shopping-platform.rar
cc97517f80f567977300450de11e9a0be53f52657525a20b1091c99fe9e45730 shopping-platform.rar (second sample)
fb94b2caee2c40635448a98ba0118421e19a400e74ccff73315f8fa42351f53f shop-main.zip (second sample)

Host Artifacts

Type Value
Process title masquerade npm-cache (credential/wallet stealer module)
PID lock file %USERPROFILE%\.npm\vhost.ctl
Second-stage payload (unconfirmed capability) hostService.txt -> hostService.exe
Second-stage payload (unconfirmed capability) printSvc.txt -> printSvc.exe
Second-stage payload (unconfirmed capability) dhcpSvc.txt -> dhcpSvc.exe
Targeted repository template GoCart (Next.js e-commerce template, GreatStackDev)

 


MITRE ATT&CK Mapping

Technique ID Technique Name Usage
T1566.001 Phishing: Spearphishing Attachment Trojanized repository delivered as a "coding challenge" via DM
T1204.002 User Execution: Malicious File Victim runs npm run dev/npm start, triggering payload execution
T1001.002 Data Obfuscation: Steganography Payload fragments hidden in HTML comments inside SVG flag images
T1027 Obfuscated Files or Information obfuscator.io JS packing; custom Base64 Check() decoder instead of atob()/Buffer.from
T1082 System Information Discovery wmic logicaldisk get name, wmic computersystem get model,manufacturer, VM/sandbox detection
T1083 File and Directory Discovery Recursive file-stealer glob sweep across drives/home directories
T1555 Credentials from Password Stores Browser Login Data/Web Data and macOS keychain access
T1005 Data from Local System File stealer collection of documents, configs, source code
T1115 Clipboard Data 500ms clipboard polling module
T1071.001 Application Layer Protocol: Web Protocols Socket.IO RAT and HTTP(S) POST-based exfil channels
T1105 Ingress Tool Transfer curl-based download of second-stage Windows binaries
T1036.008 Masquerading: Masquerade File Type .txt-to-.exe rename of downloaded binaries
T1041 Exfiltration Over C2 Channel Credential, wallet, file, and clipboard data sent to rightwidth[.]dev endpoints

Key Takeaways

Steganography moves from novelty to operational tradecraft. Hiding payload fragments inside HTML comments in ordinary-looking SVG image assets is a meaningfully different evasion technique from prior Contagious Interview waves, and one that neither static file scanning nor a quick visual code review is well-suited to catch. Security teams that rely primarily on "does this file look like an image" checks should treat SVG (and other markup-based image formats that permit comments or metadata) as a viable code-smuggling vector going forward.

The developer supply chain remains the softest target. This campaign did not need a zero-day or a novel exploit -- it needed one developer to run npm start on a plausible-looking take-home assignment. Elastic's own framing is worth repeating directly: a single compromised developer "can provide the initial access needed to enable far-reaching supply chain attacks against downstream organizations."

Zero AV detection is the norm, not the exception, for these lures. None of the trojanized archives identified in this wave were flagged by any antivirus vendor. Detection strategy for this actor class has to lean on behavioral and network indicators (unusual eval() patterns, C2 domain/endpoint matching, curl-then-rename execution chains) rather than signature or reputation-based file scanning alone.

Infrastructure and tooling convergence across DPRK campaigns. The overlap in API endpoint naming between this campaign and the separate Rollup-polyfill npm masquerading campaign, and the general blurring of the line between BEAVERTAIL and OTTERCOOKIE, suggests shared development resources or personnel across what look like independent campaigns. Detections built around durable behavioral patterns (rather than any single campaign's specific domains or hashes) are likely to have a longer useful life against this actor.


References

  1. Stepanic, D. (2026, July 18). New North Korean campaign uses fake coding interviews to steal developer credentials. Elastic Security Labs. https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography
  2. Lakshmanan, R. (2026, July 17). Fake Coding Tests Deliver OtterCookie-Aligned Malware Hidden in SVG Flag Images. The Hacker News. https://thehackernews.com/2026/07/north-korea-linked-hackers-hide.html
  3. Microsoft Security. (2026, March 11). Contagious Interview malware delivered through fake developer job interviews. https://www.microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews/
  4. NTT Security. (2024, December). OTTERCOOKIE: Contagious Interview malware analysis. https://jp.security.ntt/insights_resources/tech_blog/en-contagious-interview-ottercookie/
  5. JFrog Security Research. (2026). Rollup polyfill masquerading infrastructure. https://research.jfrog.com/post/rollup-polyfill-masquerading/
  6. The Hacker News. (2025, May). OtterCookie v4 Adds VM Detection and Enhanced Data Theft Capabilities. https://thehackernews.com/2025/05/ottercookie-v4-adds-vm-detection-and.html
  7. MITRE ATT&CK. (2024). Data Obfuscation: Steganography (T1001.002). https://attack.mitre.org/techniques/T1001/002/