This report documents a malvertising campaign exploiting WebAssembly (WASM) to conduct attribution fraud across mobile advertising ecosystems. The campaign simulates legitimate user interactions, clicks and impressions, to manipulate attribution platforms including AppsFlyer and Adjust, diverting ad revenue from legitimate publishers and developers.
WebAssembly’s involvement in malvertising is uncommon. In early 2022, GeoEdge documented its use in redirect attacks in How Cybercriminals Exploit WASM Security Vulnerabilities. This campaign is more sophisticated: WASM is deployed here specifically for its execution speed and resistance to static analysis, enabling the fraud logic to run undetected in live app sessions.
The campaign employs shadow DOM manipulation, custom HTML elements, cloaked server responses, server-side fingerprinting, and a post-execution DOM clean-up routine, all designed to ensure fraud fires only against real users while appearing clean to automated scanners.
This report details the campaign’s full technical flow, presents the Indicators of Compromise (IoCs) and Tactics, Techniques, and Procedures (TTPs), and includes a walkthrough of the WebAssembly debugging process.
Understanding the Terminology
Click Fraud refers to the manipulation of online advertisements to generate fake clicks, exploiting the pay-per-click (PPC) model to extract illegitimate revenue. In certain ad environments, click fraud can escalate into auto-redirect attacks, pushing users to malicious destinations without their consent.
Impression Fraud involves generating fake ad views with no genuine user engagement, artificially inflating impression counts to exploit the CPM model, which compensates based on views rather than clicks.
WebAssembly (WASM) is a binary instruction format that allows code written in languages such as C, C++, and Rust to execute in the browser at near-native speed. It is supported across all major browsers and in many cases is faster than JavaScript. In the context of malvertising, WASM is attractive to attackers for two reasons: it is significantly harder for security scanners to analyze than JavaScript, and its binary format complicates debugging, making malicious logic easier to conceal.
Business Impact
Attribution platforms like AppsFlyer and Adjust sit at the center of how ad revenue gets distributed: they determine which ad or publisher receives credit and payment for a user action such as a click or app install. This campaign exploits that mechanism directly. By generating fake interactions that attribution platforms log as real, the attacker gets credited as a legitimate affiliate or publisher and paid accordingly, while ad networks and advertisers pay for performance that was never delivered.
The direct financial victim is the advertiser, but app developers face indirect consequences that can be equally damaging. When click fraud rates inflate across a supply partner’s traffic, advertisers and DSPs respond by pulling budgets, lowering CPM/CPI rates, or withholding payouts, and developers who have nothing to do with the fraud can get flagged in the process.
The exposure is compounded when a fraudster spoofs a legitimate app’s ID. Attribution systems may log fraudulent installs under the real app, and that developer becomes the apparent source of the fraud, facing audits, reduced demand, or suspension from ad networks they depend on for monetization.
The Campaign’s Flow
Brief Overview
At its core, the attack embeds malicious scripts inside ad tags that appear legitimate to standard scanners. When a real user is detected via server-side fingerprinting, the fraud logic activates: obfuscated code fetches fraudulent click and impression URLs from the attacker’s server, and WebAssembly executes the fraud by dynamically setting iframe origins to those URLs. The page then simulates ad views and clicks without any visible user interaction. Once complete, the DOM elements used to generate the fake events are deleted, leaving no trace. Attribution platforms receive these interactions and log them as real.
A key characteristic of this campaign is that the fraud does not target only the promoted app. While a legitimate ad runs in the foreground, one or more fraudulent impression and click events fire simultaneously in the background, each attributed to apps entirely unrelated to the promoted ad and to each other.
For example, Ad Promoting Heetch:
Have Click and Impression Fraud to the following apps:
Step-by-Step Breakdown
Step 1: Banner Code
The ad tag loads a dummy image and a click URL. Inside the ad tag, a script tag is embedded, which sends a network request to the attackers’ private domain.
Step 2: Cloaked Content via Script
A network request is made to retrieve the script tag, structured as follows:
https://{domain}/banner/{filename}.js?{query_params}
The attacker’s server uses server-side fingerprinting to return different content depending on the user. If the user is filtered out, the returned script contains obfuscated code with a second loader to make it appear as a legitimate request.
If the fraud attack is initiated, the returned script contains additional content, unpacked and executed using the eval and atob functions. This creates two environment variables: one containing a list of encoded URLs, the other holding a number in hexadecimal format.
Step 3: Tricky Class
The malicious code creates a new HTMLElement named Tricky, defined and instantiated under the name my-tricky. The element is declared as a Shadow DOM: a self-contained web component whose internal structure is hidden and isolated from the rest of the page.
The Shadow DOM conceals the iframes created inside it from standard inspection.
The Tricky element makes fetch requests for each of the encoded URLs stored in the environment variable from Step 2.
Example of decoded URL: https://{domain}/redirect?{query_params}&type=json
The redirect endpoint may also appear in a versioned form such as redirectV2.
Step 4: Click Fraud URL
The fetch requests return JSON files containing embedded URLs. Server-side fingerprinting is applied again here: the response is cloaked with a google.com URL when the user is filtered out, and switches to the click-fraud domain go.g2app.net when the attack is initiated.
Example of a cloaked JSON response:
{o_id:0, url: “https://google.com”}
Example of a click-fraud JSON response:
{o_id:0, url: “https://go.g2app.net/click?{query_params}”}
Step 5: Dynamic Rendering
For each response URL, a new iframe is dynamically rendered while evaluating another encoded script. At this stage, no network request is made for the URL, it is only embedded under the link attribute. This iframe will be referred to as a dynamic iframe in the steps that follow.
Step 6: WebAssembly Declarations
The dynamically loaded script acts as a WebAssembly initiator, containing the definitions of JavaScript functions that will be imported from within it. Several of these functions come from the ASDOM library, built to facilitate communication between the DOM and WebAssembly.
Step 7: Fraud Initiator
The WebAssembly code sets the dynamic iframe’s origin to the URL returned from the JSON request in Step 4. When the server initiates the fraud, go.g2app.net/click? returns a 302 redirect, resetting the iframe’s origin to a fake ad click or impression URL.
When the user is filtered out, the iframe attempts to load google.com instead, producing the following error:
The error occurs because X-Frame-Options is an HTTP header that controls whether a browser may render a page inside a frame or iframe. When set to sameorigin, content can only be displayed in a frame if the request originates from the same domain. This is a standard clickjacking protection, and in this context, it serves as a signal that the user has been filtered out rather than targeted.
Step 8: Clean-Up
After the fraud is executed, the attacker clears the dynamic iframes created inside the my-tricky element by setting the Shadow DOM’s innerHTML to an empty string via setTimeout.
Debugging the WebAssembly code
To debug the .wasm code, we replicated the dynamic iframe’s content by constructing a frame with a ‘body’ element containing a ‘link’ attribute and a ‘script’ element with the decoded WebAssembly declarations, using ‘example.com’ as the URL.
‘.wasm’ refers to files with the WebAssembly binary format.
A debugger was set on the JavaScript function betaTeta, which serves as the entry point of the WebAssembly code, and its execution was traced into the ‘.wasm’ code.
The Memory Inspector was accessed through Chrome DevTools.
The same data can be observed within the ‘.wasm’ code’s data segments, likely part of a module defining error messages.
Due to the complexity of the code (4,156 lines), the following focuses on two sections directly responsible for executing the click fraud.
The first step in using the URL is to store it in memory. The highlighted code in the screenshot below corresponds to a call to getAttribute, one of the imported JavaScript functions. It checks for the existence of the link attribute and, if found, stores its content in memory at $var, which holds the value 23,296 in decimal, or 0x5B00 in hexadecimal.
In the real attack, the fraud URL fires in the background with no visible effect on the user.
In some environments, however, this behavior may escalate into an auto-redirect attack.
IOCs
hatzorhaglilit[.]online
spacepeace1010[.]com
banana-cheese-2024[.]com
worldvoice1010[.]com
knife-eagle-2024[.]com
earnose1010[.]com
prize-eagle-2024[.]com
dancevoice1010[.]com
lemon-grape-2024[.]com
earthphoto1010[.]com
quart-chase-2024[.]com
heartdream1010[.]com
olive-fancy-2024[.]com
urbanoasis08[.]com
rihsiiyoscrz[.]com
freshhorizon08[.]com
kxyaiaqyijjz[.]com
crystalpeak08[.]com
echovalley08[.]com
kdqjgqdrszkb[.]com
arcticbloom08[.]com
jhevztstuoyj[.]com
aaifnkivcoiy[.]com
quantumleap08[.]com
trxpnwvfsain[.]com
solarflare08[.]com
xjeaoqbmitzc[.]com
tmpgmzhsqfxr[.]com
beacharenas[.]com
yuxfedhtqgzy[.]com
gardena[.]world
myboss[.]life
tomergil[.]world
nurit[.]site
operafibre[.]com
wrpbbboabnvz[.]com
urzabevzbjze[.]com
outerquota[.]com
salon4[.]world
yehudit[.]world
limonmosifhamon[.]bio
artikmastik[.]bio
delta-honor-2024[.]com
quart-apple-2024[.]com
mango-knife-2024[.]com
smilepeace1010[.]com
earthheart1010[.]com
dancevideo1010[.]com
paintdream1010[.]com
spacemagic1010[.]com
021e0e850ff8669[.]com
fancy-tiger-2024[.]com
e0c26a7cd3[.]com
delta-sugar-2024[.]com
247stoichimagr[.]com
flamingoflats456[.]com
habarzel99[.]com
6f3f6bfb4b[.]com
bluejayboulevard123[.]com
magpiemews456[.]com
hanehoshet4[.]com
8f972ab661[.]com
017ca73912606ed[.]com
kingfisherkourt456[.]com
halvaworld1010[.]com
449e4b24f1[.]com
bentzion47[.]com
mysticvoyage08[.]com
olive-prize-2024[.]com
cardinalway123[.]com
rebelorgan[.]com
cea7d73496[.]com
go[.]g2app[.]net
swallowstreet456[.]com
pelicanpathway123[.]com
delta-jolly-2024[.]com
finchavenue123[.]com
dovedalecourt123[.]com
cuckoocrescent456[.]com
heronharborport667[.]com
213c6eda8a[.]com
33a0acc4a3[.]com
photocolor1010[.]com
ravenridge123[.]com
kalevet[.]bio
nadirsheadir[.]bio
nicols[.]world
hasashdandash[.]bio
yoffitoffi[.]bio
shokoladbanana[.]bio
kaspiyon[.]pro
saknai[.]pro
blums[.]space
hatoltalol[.]pro
mishmish[.]life
af7051db0c[.]com
8c5c63f8b7[.]com
8479ac3765[.]com
06d52a9514[.]com
TTPs
The following techniques were employed by the attacker:
- Cloaked Content. Server responses are conditionally modified based on the requester’s profile, returning legitimate-looking content to scanners while delivering malicious payloads to real users.
- JSON Request for URL. Fraud destination URLs are fetched dynamically via JSON responses, allowing the attacker to change targets without modifying the ad tag.
- Rendering WebAssembly Inside an iFrame. Executing the fraud logic inside an iframe isolates it from the main page context, making it harder to detect and debug.
- Injecting Malicious Script via HTMLElement. Initiating execution through a custom HTMLElement adds an additional layer of obfuscation to the script’s entry point.
- Shadow DOM and Hiding Traces. Malicious iframes are encapsulated within a Shadow DOM element. After execution, the contents are wiped to remove evidence.
- Splitting the Script. Dividing the malicious logic between JavaScript and WebAssembly increases analysis complexity. Meaningless names in the exported JavaScript functions further obscure intent.
- Server-Side Fingerprinting. Targeting is applied at the server level, ensuring the fraud activates only against real users matching a specific profile.
- Obfuscation and Encoding. The malicious script is obfuscated and encoded to resist detection and static analysis by security solutions.
- Malicious Actor-Owned Domains. Attacker-controlled infrastructure allows the campaign to be adapted or redirected as needed without reliance on third-party services.


