GlassWorm-Linked VS Code & Open VSX Color Theme Cluster

Trojanized color themes (Aurora Nocturne Night Theme, Cosmic Nebula Themes and cluster-linked identities) that run obfuscated JavaScript on every editor session, resolve C2 through a Solana dead drop, and drop a hidden batch file on Windows
Threat
GlassWorm-linked theme cluster
Severity
HIGH
Type
Supply chain · Developer endpoint · Loader
Access
TLP:CLEAR, public sources
Version
v0.1 (Draft) · 2026-10-05
Author
HuntPack
Confidence
Medium: secondary coverage only; Socket primary page blocked (403)
01

Executive Summary

Socket Threat Research tied a cluster of VS Code and Open VSX color theme extensions to the GlassWorm supply-chain campaign. A theme only needs declarative JSON, yet VS Code lets it ship JavaScript, and the editor has no fine-grained permission model for what that code does. Two extensions were confirmed malicious: Aurora Nocturne Night Theme (Windows downloader) and the Visual Studio Marketplace build of Cosmic Nebula Themes (GlassWorm loader). Socket linked six cluster identities in Open VSX, including versions of Coca-Cola Christmas, Aurora Borealis Studio Theme and Cosmic Nebula Themes. The reporting is dated 2026-10-03 to 2026-10-05.

Aurora Nocturne ran at editor start, carried a roughly 59 KB obfuscated out/extension.js with part of its payload hidden in zero-width Unicode characters, contacted fingercakes4sale[.]store, wrote the response to %TEMP%\temp_batch.cmd and launched it through cmd.exe with a hidden window. Cosmic Nebula declared a JavaScript entry point with activation on every session, decrypted an embedded stage with AES-256-CBC, ran it via eval(), skipped Russian-language and Russian-timezone hosts, then read a Solana transaction memo as a dead drop to resolve rotating next-stage infrastructure, so operators can change servers without publishing a new extension version. Socket rates the Cosmic Nebula build GlassWorm with high confidence and the wider cluster only as GlassWorm-associated.

This pack is built on developer-endpoint behavior, not on file hashes: the editor as the parent of cmd.exe or a shell, the temp_batch.cmd write and execution, DNS to the named payload host, Solana lookups from an editor process, and executables run out of extension folders. Earlier GlassWorm waves (for example the extension-dependency abuse reported in March 2026) appear only as background, and none of their indicators ship here.

Defender priority: run Q1 to Q4 now across all developer endpoints (zero tuning needed), inventory extensions on every VS Code-family editor including themes, and if a malicious theme ran, treat the host as compromised and rotate every credential, token and key that developer could reach. Removing the extension is not enough.

02

Source Review & Web Hunter Notes

Source limitation, stated plainly: the primary Socket research page (socket.dev/supply-chain-attacks/glassworm-v2) returned HTTP 403 (a bot challenge page) to automated fetch and could not be read. Every claim below rests on secondary coverage, one item of which (hendryadrian.com) is a verbatim digest of the Socket blog post and carries Socket's IOC list. Nothing was taken from the blocked page, and no snapshot was written for it.

TierSourceKey findingCarry forward
T2hendryadrian.com (Socket digest, 2026-10-03)Keypoints, MITRE list, IOC list incl. domain, URL path, dropped file, four SHA-256, Solana address, six extension IDsyes
T2gbhackers.com (2026-10-05)Infection chain, Cosmic Nebula loader detail, out/extension.js SHA-256, defender guidanceyes
T2cyberpress.org (2026-10-05)Corroborates two confirmed malicious extensions, 59 KB file, hidden cmd.exe launch, Open VSX countsyes
T2securityonline.infoDelivery, attribution confidence, detection guidance, CrowdStrike context (GlasswormRAT, May 2026 disruption)yes
T3csoonline.com (2026-03-16)Earlier GlassWorm wave (extension dependency abuse); background onlybackground only, no IOCs imported
blockedsocket.dev glassworm-v2HTTP 403 to automated fetchno

Decisions. (1) The build brief also mentioned XWorm RAT links, a SOCKS proxy and an HVNC client; none of those terms appear in any fetched snapshot, so they are not asserted here and no detection depends on them. (2) The brief said the Solana address, AES key and hashes were withheld; the hendryadrian digest of Socket's post does list them, so they are shipped with their actual source. (3) The Solana address and AES material are shared with earlier GlassWorm activity per the sources, so they are used as hunt context, not as import rows. (4) All fetched pages were screened for instruction-like text; none was found.

03

Hunt Brief & Attack Chain

Hypotheses

  • H1 (high): a compromised Windows developer host shows a VS Code-family editor spawning cmd.exe against temp_batch.cmd (Q1, Q2, Q3).
  • H2 (high): the same host resolves fingercakes4sale[.]store shortly before the batch file is written (Q4, Q3).
  • H3 (medium): a GlassWorm-style loader host shows an editor process resolving Solana infrastructure (Q6).
  • H4 (medium): a rare child process, or an executable run from an extension folder, appears under an editor (Q5, Q7, Q8).
  • H5 (medium): a cluster-linked extension identity is installed (Q9).
StepBehaviorTelemetryHunt angle
1 DeliveryName-squatted or brand-themed theme on Marketplace or Open VSX; promotional post pushed four Open VSX themesNone at endpointExtension inventory (S7, Playbook A)
2 ActivationExecutable JS entry point, activationEvents "*", runs every sessionNone directlyPackage inspection (S7)
3 Decode / decryptZero-width Unicode decode, AES-256-CBC stage, eval()None (in-process)Gap, see S15
4 EvasionRussian language and timezone check, exit if matchedNoneGap, see S15
5 Dead dropSolana transaction memo read to resolve next-stage addressDnsRequestQ6
6 DownloadAurora Nocturne contacts the payload host and fetches contentDnsRequestQ4
7 Drop and runContent written to %TEMP%\temp_batch.cmd, run by cmd.exe, hidden windowProcessRollup2, DnsRequest (the write itself is not covered by any documented file-write event)Q1, Q2, Q3; write is a gap, see S15
8 Follow-onIn-memory JS with Node.js access; credential, token and wallet theft known for GlassWorm; GlasswormRAT per CrowdStrikeProcessRollup2 (children)Q5, Q7, Q8
04

Consolidated IOC Table

Atomic indicators below are traced to the saved source snapshots. Cross-platform reuse note: the Solana address and AES material are reported as shared with earlier GlassWorm waves, so they are hunt context, not import rows.

TypeValueConfidenceActionContext
Domainfingercakes4sale[.]storehighdetectAurora Nocturne payload host; 4 secondary sources
URLhxxps://fingercakes4sale[.]store/dsyuChighdetectAurora Nocturne download location. Not importable to Falcon IOC Management
File path%TEMP%\temp_batch.cmdhighdetectDropped and executed batch script; behavioral (Q1 to Q3)
SHA-2565e68ca8c2097caccdb74d2752b85b85595a4bf646b442b8431a2416e87dbf268mediumdetectAurora Nocturne out/extension.js loader; two sources. Sensor hash telemetry covers PE files, so a JavaScript hash is unlikely to match
SHA-256a276b76d3b00f302bb4dfb3690125c85ff472b16049c3c37476ac5e51096df07lowhuntAurora Nocturne package hash; single source
SHA-256684c877a52d226d50584cb886ca8ec5bec6355d4de853f406734c79d5b387804lowhuntCosmic Nebula Themes; single source
SHA-256da2d950e50326171adbff9c2bfd6f28998e32623ea7c2c475b9159a45cfb86bblowhuntCosmic Nebula Themes; single source
Solana addressBjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SCmediumhuntDead-drop address in Cosmic Nebula loader; shared with earlier GlassWorm per Socket. Context only
Crypto materialwDO6YyTm6DL0T0zJ0SXhUql5Mo0pdlSz, 4c4b9a3773e9dced6015a670855fd32blowpivotLoader parameters per one digest; key vs IV role unconfirmed. Pivot only
HTTP headersivbase64, secretkeylowpivotStage-retrieval response headers per one digest
Repositoryvovanloc2234-sudo/Cosmic-Nebula-ThemeslowpivotCosmic Nebula source repository (public source may not match shipped package)
Extension IDsholiday-themes.theme-coca-cola-christmas, lohsebhipolg2s.theme-aurora-borealis, aurora-them-creator.theme-aurora-nocturne, solidity-syntax.deep-focus, charcoal-mint-studio.theme-charcoal-mint, cosmic-themes.theme-cosmic-nebulamediumhuntCluster-linked Open VSX identities; not all weaponized
UndisclosedFinal-stage payload, rotating C2 behind the memo, hashes for Coca-Cola Christmas / Aurora Borealis buildsn/an/aNot published in any fetched source; not invented. See S15
05

Affected Surface & Telemetry Matrix

SurfaceTelemetryPriorityGap risk
Windows dev workstations (VS Code, Cursor, Windsurf, VSCodium)ProcessRollup2, DnsRequestHighLow for process and DNS; extension file contents invisible, and the dropped .cmd script is not a PE so no file-write event fires on it
macOS developer laptopsProcessRollup2, DnsRequestMediumReported downloader is Windows-specific; loader is cross-platform Node.js
Linux dev boxes, devcontainers, remote hostsProcessRollup2MediumRemote extension hosts may not run a sensor
Open VSX consumers (Cursor and other VS Code forks)Extension inventoryHighNo sensor view of registry installs; needs inventory
06

ATT&CK Mapping

TacticTechniqueObserved behaviorQuery or control
Initial AccessT1195.002 Compromise Software Supply ChainTheme extensions on Marketplace and Open VSXQ9, Playbook A/B
ExecutionT1059.007 JavaScripteval() of decrypted stage, Node.js VMQ5, Q7 (gap in-process)
ExecutionT1059.003 Windows Command Shellcmd.exe runs temp_batch.cmdQ1, Q2, Q3
Defense EvasionT1027 Obfuscated Files59 KB obfuscated JS, zero-width UnicodeGap (static analysis)
Defense EvasionT1140 Deobfuscate/DecodeZero-width decode, AES-256-CBCGap (in-process)
DiscoveryT1614.001 System Language DiscoveryRussian locale/timezone exitGap
Command and ControlT1102.001 Dead Drop ResolverSolana transaction memoQ6
Command and ControlT1105 Ingress Tool TransferDownload from payload host to temp_batch.cmdQ3, Q4
07

Native Audit-Log Hunts

  • Extension inventory: code --list-extensions --show-versions per editor, and for Cursor and other forks their equivalent CLI. Run Playbook A to flag themes that ship a JavaScript entry point.
  • Package inspection: in each installed extension folder read package.json: main or browser set on a theme, activationEvents containing "*", and any out/extension.js near 59 KB on a theme. Inspect the installed package, not the public repo; Socket reports they diverged.
  • Marketplace removal status: Microsoft removed the reported Marketplace themes; confirm installed copies are gone and that the editor blocked the removed IDs.
  • Network and proxy logs: search for fingercakes4sale[.]store and for editor user-agents calling Solana RPC endpoints.
  • Version drift: re-run inventory after every extension update; Socket notes clean themes can turn malicious later.
08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.
Q1 · Editor process spawns cmd.exe that runs temp_batch.cmd (Aurora Nocturne execution)
CONF HIGHFP LOWCOST LOW

Looks for: A VS Code-family editor (Code, Cursor, Windsurf, VSCodium) as the parent of cmd.exe where the command line references temp_batch.cmd, the exact drop-and-run behavior reported for the Aurora Nocturne Night Theme downloader.

// HUNT: Editor spawns cmd.exe running temp_batch.cmd (GlassWorm theme downloader)
// MITRE: T1059.003, T1195.002, T1105
// CONF: high
// FP: low
// COST: low
// REQUIRES: ProcessRollup2 on Windows developer endpoints
// FALSE POSITIVES: none expected; a color theme has no legitimate reason to spawn a batch file
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| ParentBaseFileName=/^(code|code - insiders|cursor|windsurf|codium|vscodium)(\.exe)?$/i
| FileName=/^cmd\.exe$/i
| CommandLine=/temp_batch\.cmd/i
| table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, TargetProcessId, SHA256HashData])
Q2 · Any cmd.exe executing temp_batch.cmd from a temp path
CONF HIGHFP LOWCOST LOW

Looks for: Parent-agnostic execution of temp_batch.cmd through cmd.exe. Catches a variant that re-parents through node.exe or an Electron helper, where the editor is not the direct parent.

// HUNT: cmd.exe executing temp_batch.cmd (parent-agnostic)
// MITRE: T1059.003
// CONF: high
// FP: low
// COST: low
// REQUIRES: ProcessRollup2 on Windows
// FALSE POSITIVES: an unrelated internal script that happens to share the filename (verify the parent chain)
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| FileName=/^cmd\.exe$/i
| CommandLine=/temp.{0,3}temp_batch\.cmd/i
| table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine, TargetProcessId])
Q3 · Payload-host lookup correlated with batch execution on the same host
CONF HIGHFP LOWCOST MEDIUM

Looks for: Both halves of hypothesis H2 on one host: the DNS lookup of the payload domain, and a cmd.exe that runs temp_batch.cmd. Correlating them raises confidence well above either signal alone. Why this is not a file-write query: the loader writes the batch file from inside the editor's in-process Node runtime, and a .cmd script is not a PE, ELF, archive or document, so no documented Falcon file-write event (NewExecutableWritten, PeFileWritten, ElfFileWritten, ZipFileWritten, DocumentFileWritten) fires on it. The write itself is recorded as a gap in S15 rather than detected with an event name this pack cannot verify.

// HUNT: payload-host DNS lookup correlated with temp_batch.cmd execution on the same host
// MITRE: T1105, T1059.003, T1071.001
// CONF: high
// FP: low
// COST: medium
// REQUIRES: Falcon sensor on Windows developer hosts (DnsRequest + ProcessRollup2)
// FALSE POSITIVES: near none; requires both the named attacker domain and the named batch filename on one host
// TUNING: selfJoinFilter correlates by host (aid) over the search window, not by exact process tree or ordering; confirm the DNS lookup precedes the cmd.exe start before escalating, and widen the window if the drop and run are minutes apart
#event_simpleName=/^(DnsRequest|ProcessRollup2|SyntheticProcessRollup2)$/
| selfJoinFilter(field=[aid], where=[
    {#event_simpleName=DnsRequest DomainName=/fingercakes4sale\.store$/i},
    {FileName=/^cmd\.exe$/i CommandLine=/temp_batch\.cmd/i}
  ])
| table([@timestamp, aid, ComputerName, UserName, #event_simpleName, DomainName, ParentBaseFileName, FileName, CommandLine])
Q4 · Egress to the Aurora Nocturne payload host fingercakes4sale[.]store
CONF HIGHFP LOWCOST LOW

Looks for: DNS resolution of the one named payload domain, and the process that asked for it. The reported URL path is /dsyuC on that host; DNS telemetry carries only the name.

// HUNT: DNS lookup of fingercakes4sale[.]store (Aurora Nocturne payload host)
// MITRE: T1105, T1071.001
// CONF: high
// FP: low
// COST: low
// REQUIRES: DnsRequest telemetry
// FALSE POSITIVES: security researchers or sandboxes resolving the domain on purpose
#event_simpleName=DnsRequest
| DomainName=/(^|\.)fingercakes4sale\.store$/i
| table([@timestamp, aid, ComputerName, DomainName, ContextBaseFileName, ContextProcessId])
Q5 · Editor spawns a shell, scripting host or download tool (generic theme-loader behavior)
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: Rare child-process pairs under a VS Code-family editor on Windows: cmd, PowerShell, wscript, cscript, mshta, node, curl, certutil, bitsadmin. A theme loader that runs decoded JavaScript and hands off to the shell lands here even when the filename changes. FP: the integrated terminal, Git, task runners and debuggers legitimately spawn shells and node. Review the rare tail, not the head.

// HUNT: Editor process spawns shell, script host or downloader
// MITRE: T1059.003, T1059.007, T1059.001, T1105
// CONF: medium
// FP: medium
// COST: medium
// REQUIRES: ProcessRollup2 on Windows developer endpoints
// FALSE POSITIVES: integrated terminal, git, npm/node tasks, debuggers, language servers
// TUNING: baseline 14 days, then exclude the CommandLine values your developers legitimately use (for example CommandLine=/git\.exe|conhost|--ms-enable-electron-run-as-node/i) and sort ascending so rare spawn pairs surface first
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| ParentBaseFileName=/^(code|code - insiders|cursor|windsurf|codium|vscodium)(\.exe)?$/i
| FileName=/^(cmd|powershell|pwsh|wscript|cscript|mshta|node|curl|certutil|bitsadmin)\.exe$/i
| groupBy([aid, ComputerName, ParentBaseFileName, FileName], function=[count(as=Spawns), max(@timestamp, as=LastSeen), collect([CommandLine])])
| sort(Spawns, order=asc, limit=200)
Q6 · Editor process resolves Solana infrastructure (dead-drop lookup)
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: The Cosmic Nebula loader reads a Solana transaction memo to learn its next-stage address. A code editor has no business resolving Solana RPC hosts; the sources advise alerting on developer machines that query the Solana blockchain unexpectedly. FP: developers building web3 or Solana projects will resolve these hosts from their own tooling, usually from node or a terminal, not from the editor process itself.

// HUNT: Editor process DNS lookup for Solana RPC / blockchain hosts
// MITRE: T1102.001
// CONF: medium
// FP: medium
// COST: low
// REQUIRES: DnsRequest with ContextBaseFileName (validate the field in your tenant)
// FALSE POSITIVES: web3 and Solana developers; Solana extensions that call RPC on purpose
// TUNING: exclude hosts in a web3 developer group (aid list or sensor grouping tag) and any approved Solana extension; keep the editor-parent filter so terminal-launched tooling stays out
#event_simpleName=DnsRequest
| DomainName=/solana/i
| ContextBaseFileName=/^(code|code - insiders|cursor|windsurf|codium|vscodium|code helper.*|cursor helper.*)(\.exe)?$/i
| groupBy([aid, ComputerName, ContextBaseFileName, DomainName], function=[count(as=Lookups), max(@timestamp, as=LastSeen)])
| sort(Lookups, order=desc, limit=200)
Q7 · Binary or script launched from a VS Code extensions directory
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Processes whose image sits under a .vscode, .cursor, .windsurf or .vscode-oss extensions folder. A theme extension has no native executable to run, so any hit from a theme folder is a strong lead; hits from language-tooling extensions are the noise. FP: language servers and debuggers ship native binaries inside extension folders (Go, Rust, C/C++, Python).

// HUNT: Process image launched from an editor extensions directory
// MITRE: T1195.002, T1059
// CONF: medium
// FP: medium
// COST: low
// REQUIRES: ProcessRollup2; the dot after the profile folder matches the path separator so no slash is needed
// FALSE POSITIVES: language servers, debug adapters, formatter binaries bundled by legitimate extensions
// TUNING: exclude known publisher folders (for example ImageFileName=/ms-python|golang\.go|rust-lang|ms-vscode\.cpptools/i) and keep any hit whose folder name contains "theme"
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ImageFileName=/\.(vscode|cursor|windsurf|vscode-oss|vscode-insiders).extensions/i
| groupBy([aid, ComputerName, ImageFileName, ParentBaseFileName], function=[count(as=Runs), max(@timestamp, as=LastSeen), collect([CommandLine])])
| sort(Runs, order=asc, limit=200)
Q8 · macOS and Linux: editor helper spawns a shell, curl or osascript
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: The reported downloader is Windows-specific, but the loader runs full Node.js in-process on every platform. On macOS and Linux the same pivot is an editor helper process launching sh, bash, zsh, curl, wget or osascript. FP: the integrated terminal is a shell child of an editor helper process by design.

// HUNT: macOS/Linux editor helper spawns shell, curl, wget or osascript
// MITRE: T1059.004, T1059.002, T1105
// CONF: medium
// FP: medium
// COST: medium
// REQUIRES: ProcessRollup2 on macOS and Linux sensors
// FALSE POSITIVES: integrated terminal, Git operations, task runners, extension install scripts
// TUNING: exclude interactive terminal launches (CommandLine=/^-?(zsh|bash)( -l)?$/) and sort ascending so one-off curl or osascript spawns surface first
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=/^(Mac|Lin)$/
| ParentBaseFileName=/^(code|cursor|windsurf|codium|electron|code helper.*|cursor helper.*)$/i
| FileName=/^(sh|bash|zsh|curl|wget|osascript)$/i
| groupBy([aid, ComputerName, ParentBaseFileName, FileName], function=[count(as=Spawns), max(@timestamp, as=LastSeen), collect([CommandLine])])
| sort(Spawns, order=asc, limit=200)
Q9 · Cluster-linked extension identities on disk or on a command line
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: The six Open VSX identities Socket tied to the cluster, seen in a process path or an --install-extension command line. Socket states not every version was weaponized, so a hit means inventory and inspect that package, not auto-confirm. FP: Coca-Cola Christmas and Aurora Borealis Studio were not weaponized in the versions Socket examined; the solidity-syntax.deep-focus name resembles a legitimate Solidity ecosystem name. Confirm version and package contents before escalating.

// HUNT: Cluster-linked extension identities in process paths or install commands
// MITRE: T1195.002
// CONF: medium
// FP: medium
// COST: low
// REQUIRES: ProcessRollup2 (extension host and CLI launches expose the extension folder in the image path or command line)
// FALSE POSITIVES: unweaponized versions of the same identities; similarly named legitimate extensions
// TUNING: confirm the installed version against Socket's weaponized builds; treat a hit as an inventory lead and inspect package.json activationEvents and the main entry point
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| CommandLine=/holiday-themes\.theme-coca-cola-christmas|lohsebhipolg2s\.theme-aurora-borealis|aurora-them-creator\.theme-aurora-nocturne|solidity-syntax\.deep-focus|charcoal-mint-studio\.theme-charcoal-mint|cosmic-themes\.theme-cosmic-nebula/i
| table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine])
09

CrowdStrike Custom IOA Recommendations

Q1 to Q3 are behavior-pinned and rotate-proof, so they are IOA candidates. Q5 to Q9 stay Investigate-only until baselined.

IOA-1 · Editor spawns cmd.exe running temp_batch.cmd HIGH PRIORITY

Pattern: Process Creation, parent image matches the editor list, image cmd.exe, command line contains temp_batch.cmd. Deployment: deploy directly in detect mode; no baseline needed. Exclusions: none. Alert framing: [CRITICAL] Detection: GlassWorm theme loader, editor ran temp_batch.cmd.

IOA-2 · Batch file written to temp by an editor-launched process

Pattern: File Creation, file name temp_batch.cmd in a user temp directory. Deployment: detect mode. Exclusions: none identified.

IOA-3 · Editor spawns a shell or script host (promote after baseline)

Pattern: Q5 logic. Deployment: run Q5 for 14 days, build the exclusion list from observed developer tooling, then promote.

10

Machine-Readable IOC Appendix

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
domain,fingercakes4sale.store,detect,high,2027-04-05,Aurora Nocturne Night Theme payload host,campaign:GlassWorm-VSCodeThemes
sha256,5e68ca8c2097caccdb74d2752b85b85595a4bf646b442b8431a2416e87dbf268,detect,medium,2027-04-05,Aurora Nocturne out/extension.js loader (JS file; low match odds),campaign:GlassWorm-VSCodeThemes
sha256,a276b76d3b00f302bb4dfb3690125c85ff472b16049c3c37476ac5e51096df07,hunt,low,2027-01-05,Aurora Nocturne package hash (single source),campaign:GlassWorm-VSCodeThemes
sha256,684c877a52d226d50584cb886ca8ec5bec6355d4de853f406734c79d5b387804,hunt,low,2027-01-05,Cosmic Nebula Themes hash (single source),campaign:GlassWorm-VSCodeThemes
sha256,da2d950e50326171adbff9c2bfd6f28998e32623ea7c2c475b9159a45cfb86bb,hunt,low,2027-01-05,Cosmic Nebula Themes hash (single source),campaign:GlassWorm-VSCodeThemes
sha256,REPLACE_WITH_COCA_COLA_CHRISTMAS_BUILD_SHA256,hunt,medium,2027-01-05,UNDISCLOSED hash for Coca-Cola Christmas build,campaign:GlassWorm-VSCodeThemes
sha256,REPLACE_WITH_AURORA_BOREALIS_STUDIO_BUILD_SHA256,hunt,medium,2027-01-05,UNDISCLOSED hash for Aurora Borealis Studio build,campaign:GlassWorm-VSCodeThemes
domain,REPLACE_WITH_SOLANA_MEMO_RESOLVED_C2,detect,high,2027-04-05,UNDISCLOSED rotating C2 resolved from Solana memo,campaign:GlassWorm-VSCodeThemes
Behavioral Signaturesnot file/network atomic
# Behavioral signatures (not atomic; do not import as IOCs)
editor_parent -> cmd.exe with CommandLine containing temp_batch.cmd
file write: %TEMP%\temp_batch.cmd, then cmd.exe execution with hidden window
DnsRequest: fingercakes4sale.store (and URL path /dsyuC upstream)
editor process (Code, Cursor, Windsurf, VSCodium) resolving Solana RPC hosts
theme extension with "main"/"browser" set and activationEvents ["*"]
~59 KB single-line obfuscated out/extension.js in a theme package
loader behavior: zero-width Unicode decode, AES-256-CBC stage, eval(), Russian locale/timezone exit
Solana address (context only, shared with earlier GlassWorm): BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC
Named Extensions & Malwareattribution
Cluster-linked Open VSX identities (not all weaponized):
holiday-themes.theme-coca-cola-christmas
lohsebhipolg2s.theme-aurora-borealis
aurora-them-creator.theme-aurora-nocturne
solidity-syntax.deep-focus
charcoal-mint-studio.theme-charcoal-mint
cosmic-themes.theme-cosmic-nebula
Confirmed malicious: Aurora Nocturne Night Theme, Cosmic Nebula Themes
Live but not weaponized when examined: Coca-Cola Christmas, Aurora Borealis Studio Theme
Malware: GlassWorm loader; GlasswormRAT (per CrowdStrike, via securityonline)
Extension Audit Checklistinventory
# Extension audit checklist
1. List extensions on every VS Code-family editor (code, cursor, windsurf, codium).
2. For each theme: package.json main/browser present? activationEvents contains "*"?
3. Any out/extension.js ~59 KB on a theme? Compare shipped package to public repo.
4. Search proxy/DNS for fingercakes4sale.store; editor processes resolving Solana hosts.
5. If a malicious theme ran: isolate, rotate GitHub, npm, Open VSX tokens, cloud keys, SSH keys, wallet data.
11

Detection Validation Gates

GateRequirement
Telemetry readyConfirm ProcessRollup2 and DnsRequest flow from developer host groups. Confirm DnsRequest exposes ContextBaseFileName in your tenant before relying on Q6. Do not expect a file-write event for the dropped .cmd script: it is not a PE, so the documented write events do not cover it (see S15).
Benign baselineRun Q5, Q7, Q8 over 14 to 30 days and fill the TUNING exclusions with observed developer tooling.
Positive testsSafe simulation only: from a lab host, have code.exe or a renamed copy launch a harmless cmd.exe /c echo with a file named temp_batch.cmd in a temp folder. Do not run any real extension payload.
Promotion pathInvestigate-only to Custom IOA after two clean baseline weeks. IOA-1 and IOA-2 can deploy immediately.
12

Hardening: Tiered

Immediate (this week)
  • Inventory every VS Code-family editor extension and flag themes with a JS entry point or activationEvents "*" (Playbook A). MITRE M1047 Audit. Best-practice, no formal benchmark.
  • Deploy Custom IOA-1 and IOA-2 in detect mode. MITRE M1049 Antivirus/Antimalware.
  • Remove and block any cluster-linked identity from section 4; rotate secrets of anyone who ran one.
Near term (1 to 4 weeks)
  • Enforce an extension allowlist through the VS Code managed policy (Playbook B). MITRE M1033 Limit Software Installation. Verify the policy name against your editor version.
  • Pilot restricting editor traffic: block Open VSX and unneeded marketplaces for managed fleets that only need Microsoft Marketplace. MITRE M1031 Network Intrusion Prevention.
Strategic (1 to 3 months)
  • Move to a private or mirrored extension registry that serves only reviewed versions. MITRE M1051 Update Software, M1033.
  • Cut developer credential blast radius: short-lived tokens, hardware-backed SSH keys, no long-lived npm or Open VSX publish tokens on laptops. MITRE M1026 Privileged Account Management.
13

Deployable Playbooks

Playbook A · extension audit

# Playbook A: flag theme extensions that ship executable JavaScript (read-only)
# Prerequisites: PowerShell 5.1+, read access to the user profile folders
# Reboot required: No
# Rollback: none required, this playbook only reads files
$roots = @("$env:USERPROFILE\.vscode\extensions","$env:USERPROFILE\.cursor\extensions","$env:USERPROFILE\.windsurf\extensions","$env:USERPROFILE\.vscode-oss\extensions")
foreach ($r in $roots) {
  if (-not (Test-Path $r)) { continue }
  Get-ChildItem $r -Directory | ForEach-Object {
    $pj = Join-Path $_.FullName 'package.json'
    if (-not (Test-Path $pj)) { return }
    $j = Get-Content $pj -Raw | ConvertFrom-Json
    $isTheme = $null -ne $j.contributes.themes
    $hasCode = ($null -ne $j.main) -or ($null -ne $j.browser)
    $always  = $j.activationEvents -contains '*'
    if ($isTheme -and ($hasCode -or $always)) {
      [pscustomobject]@{ Extension=$_.Name; Main=$j.main; ActivatesAlways=$always }
    }
  }
}

Playbook B · extension allowlist policy

Prerequisites: admin or GPO rights. Reboot required: No. Rollback: delete the AllowedExtensions value.

# Playbook B: restrict VS Code to an allowlist of extensions (managed policy)
# Prerequisites: local admin or GPO rights; VS Code build that supports the AllowedExtensions policy (verify in your version's policy docs)
# Reboot required: No (restart the editor)
# Rollback: Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\VSCode -Name AllowedExtensions
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\VSCode" -Force | Out-Null
$allow = '{"REPLACE_WITH_APPROVED_PUBLISHER":true,"REPLACE_WITH_PUBLISHER.REPLACE_WITH_EXTENSION":true}'
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\VSCode" -Name AllowedExtensions -Value $allow -PropertyType String -Force | Out-Null
# Verify
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\VSCode" | Select-Object AllowedExtensions

Playbook C · Custom IOA deployment

Playbook C: deploy IOA-1 and IOA-2 in Falcon
1. Prerequisites: Custom IOA rights in Falcon Prevention policy admin.
2. Create rule group (Windows). Add rule: Process Creation, parent image regex
   (code|cursor|windsurf|codium|vscodium)\.exe, image cmd\.exe, command line temp_batch\.cmd.
3. Add rule: File Creation, file name temp_batch\.cmd, in a temp directory.
4. Set action Detect, severity High. Assign the group to a pilot host group.
   Detect, never Prevent, and High rather than Critical: the whole indicator set rests on
   secondary coverage of one research post, so nothing in this pack carries a blocking
   posture or a critical rating (see S2).
5. Reboot required: No.
6. Rollback: disable the rule or unassign the rule group; no endpoint state changes.
14

Containment Runbook

PhaseActionsOwnerEvidence
IsolateNetwork-contain the host with Falcon containment; block fingercakes4sale[.]store at DNS and proxySOC / IRContainment timestamp, block rule ID
PreserveCollect the extension folder, %TEMP%\temp_batch.cmd if present, editor logs, and process tree for the editor sessionIRRTR session log, file hashes
EradicateUninstall the extension, delete the dropped batch file, remove persistence found in the batch contents, re-inspect all other extensions on the hostIR / Endpoint EngPost-clean scan, extension inventory
RecoverRotate GitHub, npm and Open VSX tokens, SSH keys, cloud and CI/CD secrets and wallet data reachable from the developer account; re-image if the batch content shows further executionIAM / IRToken revocation log
Lessons learnedDeploy Playbook B allowlist; confirm IOA-1 and IOA-2 are liveSecurity EngChange record
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1195.002Cluster-linked extension installedQ9NoPartial name-based; inventory is the real control
T1059.003cmd.exe runs temp_batch.cmdQ1, Q2Yes (IOA-1)Good
T1105Payload host lookup, correlated with the batch runQ3, Q4Yes (IOA-2)Good for the lookup and the execution
T1105 (write)Creation of %TEMP%\temp_batch.cmd itselfn/aNoGAP the loader writes it from the editor's in-process Node runtime, and a .cmd script is not a PE, ELF, archive or document, so none of the documented Falcon file-write events fire on it. Detected one step later, at execution (Q1, Q2) and by correlation (Q3)
T1059.007Editor spawns shell / nodeQ5, Q7, Q8NoPartial FP medium
T1102.001Solana dead-drop lookupQ6NoPartial needs ContextBaseFileName
T1027 / T1140Zero-width decode, AES stage, eval()n/aNoGAP in-process, not visible to the sensor
T1614.001Russian locale / timezone checkn/aNoGAP not observable
HashesJavaScript file hashesn/aNoGAP sensor hash events cover PE files

Undisclosed indicators, stated plainly. The following are not published in any fetched source and are not invented: hashes for the Coca-Cola Christmas and Aurora Borealis Studio builds, the rotating C2 resolved from the Solana memo, the recovered final-stage payload (Socket did not recover it), and any Falcon-matchable hash for the JavaScript files. They ship as labelled REPLACE_WITH_ placeholders in the CSV. The reported Solana address and AES-like strings come from one digest of Socket's post and are shared with earlier GlassWorm activity, so they are context, not import rows. Validation gates are in section 11.

16

Hunt Summary Ticket

TITLE:      GlassWorm-linked VS Code / Open VSX color theme cluster
SEVERITY:   HIGH, developer-endpoint supply chain, credential theft capability
SCOPE:      VS Code-family editors (Code, Cursor, Windsurf, VSCodium) on
            Windows, macOS, Linux developer hosts
HYPOTHESIS: A host that ran a trojanized theme shows an editor process
            spawning cmd.exe against temp_batch.cmd, DNS to
            fingercakes4sale[.]store, or an editor resolving Solana hosts.
QUERIES:    Q1-Q9 (Section 8); IOA-1 to IOA-3 (Section 9)
DO FIRST:   1. Run Q1-Q4 fleet-wide (7 days), no tuning needed.
            2. Run Playbook A extension audit on developer hosts.
            3. Run Q9 for cluster-linked extension identities.
            4. Baseline Q5-Q8 for 14 days, then tune.
FINDINGS:   REPLACE_WITH_FINDINGS_SUMMARY_AFTER_HUNT_EXECUTION
GAPS:       In-process decode/decrypt/eval, locale checks, JS file hashes,
            Solana-resolved C2 and final payload (Section 15).
ACTIONS:    Deploy IOA-1/IOA-2; allowlist extensions (Playbook B);
            rotate credentials on any confirmed host.
OWNER:      REPLACE_WITH_HUNT_OWNER
VERSION:    v0.1 (Draft) 2026-10-05
17

Changelog

v0.12026-10-05Initial pack build from four secondary sources (one a verbatim Socket digest) plus one background source. Socket primary page blocked (HTTP 403). 9 CQL queries, 3 IOA candidates, documented gaps and undisclosed indicators.
18

References

TierSourceUsed forAccess date
blockedSocket Threat Research, glassworm-v2 (HTTP 403, not read)Intended primary; blocked to automated fetch, nothing taken from it2026-10-05
T2hendryadrian.com, Socket digestIOC list, MITRE list, keypoints2026-10-05
T2GBHackersInfection chain, out/extension.js hash2026-10-05
T2Cyber PressCorroboration, Open VSX scale2026-10-05
T2Security OnlineAttribution, guidance, CrowdStrike context2026-10-05
T3CSO Online (2026-03-16)Background on an earlier wave only2026-10-05

Five fetched sources were saved verbatim to GlassWorm-VSCodeThemes-Hunt-sources/ for the provenance gate.

Generated 2026-10-05 by HuntPack · defensive content only