AlienVault's OTX pulse, sourced from Check Point Research, documents JSCeal — a sophisticated, cryptocurrency-focused infostealer distributed as compiled V8 bytecode rather than readable JavaScript. This delivery format is the core of its evasion strategy: because the payload ships as a .jsc binary executed through a bundled Node.js runtime, traditional static scanners that pattern-match JavaScript source code see nothing, and most sandboxes cannot execute the bytecode without the attacker's exact V8 engine version.
Check Point's team built a fully static deobfuscation pipeline that transforms View8 pseudocode without ever executing a sample — which tells us two things. First, JSCeal is actively resistant to both static and dynamic analysis, an investment level consistent with a financially motivated operation harvesting browser credentials and crypto wallet data at scale. Second, the campaign leverages MITM proxy injection to intercept browser traffic, meaning the operator is not merely scraping local credential stores but actively positioning between the victim and their sessions — including authenticated web sessions that bypass password theft entirely.
The collective intelligence picture: an unknown but technically mature actor is monetizing stolen browser sessions, saved credentials, and cryptocurrency wallet secrets, delivered via a Node.js-bundled payload that enterprises are largely blind to because endpoint controls rarely baseline node.exe behavior on user workstations.
Threat Actor / Malware Profile
Malware family: JSCeal | Attribution: Unknown | Motivation: Financial (cryptocurrency + credential theft) | TLP: WHITE
Distribution method. JSCeal arrives packaged with a legitimate Node.js runtime, with the malicious logic compiled into V8 bytecode (.jsc files). Because the interpreter itself is a signed, legitimate binary, application-allowlisting and reputation engines frequently let the loader through. Execution chains observed involve launching the bundled node.exe against the compiled payload rather than a readable .js file.
Payload behavior. Once running, the stealer targets browser-stored data — cookies, saved credentials, autofill data, and session tokens — across Chromium-based browsers, and enumerates cryptocurrency wallet artifacts (extension wallets, desktop wallet keystores). Tags associated with the pulse (browser theft, cryptocurrency stealer) align with standard infostealer exfiltration: staged collection, archive, then outbound transfer to actor-controlled infrastructure.
C2 communication. The mitm proxy tag indicates the malware establishes or leverages a local man-in-the-middle proxy to intercept encrypted browser traffic, enabling theft of session data in transit rather than only at rest on disk. Expect rogue proxy configuration changes (system proxy registry values, PAC file manipulation) and local listeners bound by the Node.js process.
Persistence mechanism. Node.js-based stealers typically persist through scheduled tasks, Run keys, or abuse of startup folders invoking the bundled interpreter with the .jsc payload. Hunt guidance below covers all three.
Anti-analysis techniques. This is JSCeal's defining trait, layered via javascript-obfuscator:
- Compiled V8 bytecode — no readable source for static engines to parse; sandbox detonation fails without the matching V8 build
- RC4-encrypted string table — all IOCs, URLs, and API names decrypted at runtime
- Control-flow flattening — logic restructured into dispatcher loops, defeating decompilers and human triage
- Proxy functions — indirect call indirection breaking API-call-based behavioral signatures
The practical consequence for defenders: signature-based detection on file content is near-worthless. Detection must be behavioral — interpreter process telemetry, proxy tampering, credential-store access, and hash-based blocking for known samples.
IOC Analysis
The pulse carries 12 indicators across two types:
File hashes (MD5, 10 indicators). These represent JSCeal samples and staged components identified by Check Point. MD5s are suitable for exact-match blocking in EDR custom indicator lists, file-reputation integrations, and retroactive hunts across file-creation telemetry. Actionable hashes include 03f4e47b9c2283c32bb8f8f042ce6e41, 0d1fce0cb2b9dec26a10f0822aeffb19, 581e2e2265d0c1509b3799c5a9039374, 91038aebe528a065c3e995a418db6826, de10c6b3dc4619f59bc9c80a0aa15e6a, and e27ae65977287bdfb7b0e15fd3603f85, with the full set of 10 retrievable from the pulse. Load them as custom file indicators in Microsoft Defender for Endpoint / your EDR with block action, and sweep historical DeviceFileEvents and Sysmon Event ID 1 for prior presence.
Domains (2 indicators). console.info and profile.info appear as domain-type indicators. Treat these cautiously — both resemble extracted JavaScript object references (console.info, profile.info) rather than genuine C2 FQDNs, a common artifact of automated IOC extraction from obfuscated script content. Do not add them to perimeter blocklists without validation; a false block of a legitimate .info TLD domain causes business disruption. Instead, run them through passive DNS and your TI platform for corroboration before operationalizing.
Operationalization guidance. Because JSCeal's strings are RC4-encrypted, network IOCs from static extraction will always lag. SOC teams should pair hash blocking with behavioral coverage: monitor for node.exe spawned outside developer contexts, rogue proxy registry writes, and Node processes touching browser profile paths. For analysts wanting to replicate Check Point's work, the View8 toolchain plus their published pipeline enables static extraction of runtime strings from any newly captured .jsc samples.
Detection Engineering
The following detections target JSCeal's core behaviors: Node.js execution of compiled bytecode outside legitimate developer workflows, MITM proxy tampering, and browser credential store access by non-browser processes.
---
title: Node.js Execution of Compiled V8 Bytecode Payload (JSCeal)
id: 9f3a1c7e-2b4d-4e8a-9c1f-jsceal0001
status: experimental
description: Detects node.exe or bundled Node runtimes executing .jsc compiled V8 bytecode files, the delivery format used by the JSCeal infostealer. Legitimate use of .jsc on end-user workstations is rare outside packaged commercial applications.
author: Security Arsenal Threat Intelligence
logsource:
category: process_creation
product: windows
detection:
selection_img:
Image|endswith: '\node.exe'
selection_cli:
CommandLine|contains:
- '.jsc'
filter_known_paths:
Image|startswith:
- 'C:\Program Files\nodejs\'
- 'C:\Program Files (x86)\nodejs\'
condition: selection_img and selection_cli and not filter_known_paths
falsepositives:
- Packaged commercial applications bundling Node with compiled bytecode
- Developer environments
level: high
tags:
- attack.execution
- attack.t1059.007
date: 2026/08/31
---
title: Rogue System Proxy Configuration via Registry (MITM Injection)
id: 9f3a1c7e-2b4d-4e8a-9c1f-jsceal0002
status: experimental
description: Detects modification of Internet Settings proxy registry values (ProxyServer, ProxyOverride, AutoConfigURL) by non-browser processes, consistent with JSCeal's MITM proxy injection used to intercept browser traffic and steal sessions in transit.
author: Security Arsenal Threat Intelligence
logsource:
category: registry_set
product: windows
detection:
selection_key:
TargetObject|contains:
- '\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer'
- '\Software\Microsoft\Windows\CurrentVersion\Internet Settings\AutoConfigURL'
- '\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyOverride'
filter_legit:
Image|endswith:
- '\svchost.exe'
- '\explorer.exe'
- '\msiexec.exe'
condition: selection_key and not filter_legit
falsepositives:
- Enterprise GPO proxy deployment tooling
- VPN and secure gateway clients
level: medium
tags:
- attack.collection
- attack.t1557
date: 2026/08/31
---
title: Browser Credential Store Access by Node.js Process (JSCeal Theft)
id: 9f3a1c7e-2b4d-4e8a-9c1f-jsceal0003
status: experimental
description: Detects node.exe accessing Chromium browser Login Data, Cookies, or Web Data files or cryptocurrency wallet paths — the collection behavior of browser/credential stealers such as JSCeal. Browsers do not use node.exe to read their own stores.
author: Security Arsenal Threat Intelligence
logsource:
category: file_access
product: windows
detection:
selection_img:
Image|endswith: '\node.exe'
selection_target:
TargetObject|contains:
- '\Google\Chrome\User Data\'
- '\Microsoft\Edge\User Data\'
- '\BraveSoftware\Brave-Browser\User Data\'
- '\Opera Software\Opera Stable\'
- '\Login Data'
- '\Cookies'
- '\Web Data'
- '\wallet.dat'
- '\Exodus\'
- '\Electrum\'
- '\atomic\Local Storage\'
condition: selection_img and selection_target
falsepositives:
- Legitimate Electron-based applications with embedded browser profiles
- Browser sync or backup utilities using Node runtimes
level: high
tags:
- attack.credential_access
- attack.t1555.003
- attack.t1539
date: 2026/08/31
Hunt JSCeal activity across the estate in Microsoft Sentinel — Node execution of bytecode, browser store access, proxy tampering, and known pulse hashes.
let JscealHashes = dynamic([
"03f4e47b9c2283c32bb8f8f042ce6e41",
"0d1fce0cb2b9dec26a10f0822aeffb19",
"581e2e2265d0c1509b3799c5a9039374",
"91038aebe528a065c3e995a418db6826",
"de10c6b3dc4619f59bc9c80a0aa15e6a",
"e27ae65977287bdfb7b0e15fd3603f85"]);
let Lookback = 14d;
let ProcessHits = DeviceProcessEvents
| where TimeGenerated > ago(Lookback)
| where FileName =~ "node.exe"
| where ProcessCommandLine has_any (".jsc", "bytenode", "v8-compile-cache")
or ProcessCommandLine has_any ("Login Data", "Cookies", "wallet", "Local Storage")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, FolderPath, InitiatingProcessFileName;
let HashHits = DeviceFileEvents
| where TimeGenerated > ago(Lookback)
| where MD5 in (JscealHashes) or SHA256 in (JscealHashes)
| project TimeGenerated, DeviceName, FolderPath, FileName, MD5, InitiatingProcessFileName;
let ProxyNetHits = DeviceNetworkEvents
| where TimeGenerated > ago(Lookback)
| where InitiatingProcessFileName =~ "node.exe"
| where not(RemoteUrl has_any ("npmjs.org", "nodejs.org", "microsoft.com", "github.com"))
| where RemotePort in (80, 443, 8080, 8443)
| summarize Connections=count(), RemoteEndpoints=make_set(RemoteIP, 10), RemoteUrls=make_set(RemoteUrl, 10)
by DeviceName, InitiatingProcessFolderPath, bin(TimeGenerated, 1h)
| where Connections > 5;
union ProcessHits, HashHits, ProxyNetHits
| sort by TimeGenerated desc
Standalone hunt script for hosts without full EDR coverage — checks running Node processes, rogue proxy settings, persistence entries invoking Node, and known JSCeal file hashes under user profiles.
# JSCeal V8 Bytecode Stealer — Host Hunt Script
# Run elevated. Outputs findings to console and C:\Temp\JscealHunt_<hostname>.txt
$hashes = @(
"03f4e47b9c2283c32bb8f8f042ce6e41",
"0d1fce0cb2b9dec26a10f0822aeffb19",
"581e2e2265d0c1509b3799c5a9039374",
"91038aebe528a065c3e995a418db6826",
"de10c6b3dc4619f59bc9c80a0aa15e6a",
"e27ae65977287bdfb7b0e15fd3603f85"
)
$findings = @()
Write-Host "[*] Checking running Node.js processes..." -ForegroundColor Cyan
Get-CimInstance Win32_Process -Filter "Name='node.exe'" | ForEach-Object {
if ($_.CommandLine -match '\.jsc|Login Data|Cookies|wallet|bytenode') {
$findings += "[ALERT] Suspicious node.exe PID $($_.ProcessId): $($_.CommandLine)"
} else {
$findings += "[INFO] node.exe running PID $($_.ProcessId) — review: $($_.CommandLine)"
}
}
Write-Host "[*] Checking for rogue proxy configuration (MITM indicator)..." -ForegroundColor Cyan
foreach ($hive in @("HKCU:","HKU:")) {
Get-ChildItem "$hive" -ErrorAction SilentlyContinue | Out-Null
}
$proxyPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
$proxy = Get-ItemProperty -Path $proxyPath -ErrorAction SilentlyContinue
if ($proxy.ProxyEnable -eq 1 -and $proxy.ProxyServer) {
$findings += "[ALERT] Manual proxy enabled: ProxyServer=$($proxy.ProxyServer) — verify legitimacy"
}
if ($proxy.AutoConfigURL) {
$findings += "[ALERT] PAC file configured: $($proxy.AutoConfigURL) — verify legitimacy"
}
Write-Host "[*] Checking persistence locations for Node.js invocation..." -ForegroundColor Cyan
$runKeys = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
)
foreach ($key in $runKeys) {
Get-ItemProperty -Path $key -ErrorAction SilentlyContinue | Get-Member -MemberType NoteProperty | ForEach-Object {
$val = (Get-ItemProperty -Path $key -Name $_.Name -ErrorAction SilentlyContinue).($_.Name)
if ($val -match 'node\.exe|\.jsc') {
$findings += "[ALERT] Run key persistence ($key): $($_.Name) = $val"
}
}
}
Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object {
($_.Actions | Out-String) -match 'node\.exe|\.jsc'
} | ForEach-Object {
$findings += "[ALERT] Scheduled task invoking Node: $($_.TaskName) — $($_.Actions.Execute) $($_.Actions.Arguments)"
}
Write-Host "[*] Sweeping user profiles for known JSCeal sample hashes..." -ForegroundColor Cyan
$searchPaths = @("$env:USERPROFILE\Downloads","$env:USERPROFILE\AppData","$env:TEMP")
foreach ($path in $searchPaths) {
Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Length -lt 50MB } |
ForEach-Object {
$md5 = (Get-FileHash -Path $_.FullName -Algorithm MD5 -ErrorAction SilentlyContinue).Hash
if ($hashes -contains $md5.ToLower()) {
$findings += "[CRITICAL] Known JSCeal sample found: $($_.FullName) (MD5: $md5)"
}
}
}
Write-Host "[*] Checking for .jsc bytecode files outside Program Files..." -ForegroundColor Cyan
Get-ChildItem -Path "$env:USERPROFILE" -Recurse -Filter "*.jsc" -ErrorAction SilentlyContinue | ForEach-Object {
$findings += "[ALERT] Compiled V8 bytecode file in user profile: $($_.FullName)"
}
$out = "C:\Temp\JscealHunt_$env:COMPUTERNAME.txt"
New-Item -Path "C:\Temp" -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null
if ($findings.Count -eq 0) { $findings = @("[CLEAN] No JSCeal indicators found on $env:COMPUTERNAME") }
$findings | Tee-Object -FilePath $out
Write-Host "[*] Hunt complete. Results written to $out" -ForegroundColor Green
Response Priorities
Immediate (0–4 hours)
- Push the 10 MD5 hashes from the OTX pulse into your EDR custom indicator list with block action; sweep 14–30 days of file-creation and process telemetry for retroactive matches
- Hunt for
node.exeexecuting.jscfiles or residing in non-standard paths (user profiles,%TEMP%,%APPDATA%) — JSCeal's defining execution artifact - Audit endpoints for unauthorized proxy configuration changes; JSCeal's MITM capability means a rogue proxy equals intercepted sessions
- Do not blind-block
console.info/profile.infodomain indicators — validate via passive DNS first
24 hours
- JSCeal steals browser credentials, cookies, and session tokens: for any confirmed or suspected host, force password resets and full session invalidation (revoke OAuth tokens, sign out all sessions) for every account used on that machine — session cookies bypass MFA, so token revocation is as critical as password rotation
- Review cryptocurrency exposure: identify users on affected hosts who accessed exchange accounts or wallet extensions and flag those accounts for fraud monitoring
- Check for lateral movement from affected hosts — infostealer access is routinely sold to initial access brokers for ransomware staging
1 week
- Implement application control policy restricting
node.exeexecution to approved developer workstations and known packaged applications; alert on all other executions - Deploy the Sigma detections above into your SIEM and validate with purple-team emulation of the Node-bytecode execution pattern
- Enforce proxy configuration integrity monitoring (registry watch on
Internet Settings) and consider disabling user-modifiable proxy settings via GPO where a corporate proxy is already mandated - Brief helpdesk and identity teams on the credential-stealer reset playbook so session revocation is executed, not just password resets
Related Resources
Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.