Security News

Cybersecurity news aggregator

⚔️
HIGH Attacks Reddit r/netsec

Detailed analysis of a sophisticated firefox extension malware found in the wild using browser-xpi-malware-scanner.py

A sophisticated Firefox extension malware, distributed via the official Mozilla store, uses steganography to hide a C2 payload within a PNG icon file, evades detection via sleeper and random sampling techniques, and ultimately gains total browser control for credential theft and affiliate hijacking. The article details the analysis using a provided scanner tool but does not specify a CVSS score, affected or fixed Firefox versions, or provide a workaround.
Read Full Article →

Home / Blog / Cryptography & Steganography Malware Analysis: Using browser-xpi-malware-scanner.py to find malware in the wild I got interested in how malware extensions written for browsers (in this case Firefox) manages to bypass firefox's publication and verification processes and started analyzing a malware extension I had downloaded a few weeks ago when I read an article about 10-20 or so malware extensions with over 100k users were detected on firefox's extension store. I started writing a script in python which focus is to scan .xpi extension files (which are regular zip archives renamed) which is availible here and installed ~10 extensions on a fresh firefox installation and found an extension containing malware which manages to break free of the extension sandboxing, evades detection by using sleeper and random sampling techniques before sending beacon to C2 server and many , many other interesting malware techniques. I am sure that if i could find this in just 15 minutes of looking through random extensions with few users, there are many MANY more examples This is coded by a highly skilled coder and gives the attacker total control over the browser including credential stealing, sending commands and affiliate commission hijacking . Check out the browser-xpi-malware-scanner here: https://github.com/ernos/browser-xpi-malware-scanner Detailed analysis of malware extension YTMP4 — Download YouTube Videos to MP4 Extension Name: YTMP4 — Download YouTube Videos to MP4 Extension ID: 1efab3c2-06ac-4040-975d-e006baac07ce@ytmp4 File: 1efab3c2-06ac-4040-975d-e006baac07ce@ytmp4.xpi SHA-256: f4c493377c6065e039f547ab0da5bafdfb8eaffa524fd744c119fd2bb6cfef30 Size: 99,547 bytes Analyzer verdict: CRITICAL RISK (1 CRITICAL · 22 HIGH · 17 MEDIUM · 1 INFO) Analysis date: April 2, 2026 Live at mozilla extension store as of date of writing this article. Introduction This, and many, many other extensions could be prevented simply by adding a check for data after the IEND tag in the PNG file which many malware browser extensions seems to use. Table of Contents How browser-xpi-malware-scanner.py Found This Extension Extension Surface — What It Claims to Do Finding 1 — Steganographic Payload in PNG Icon (CRITICAL) Finding 2 — Unicode Low-Byte Encoding Trick Finding 3 — Decoded Payload: The C2 String Table Finding 4 — 72-Hour Sleeper with Random Sampling Finding 5 — C2 Beacon via Another PNG File Finding 6 — Dynamic declarativeNetRequest Rule Injection Finding 7 — Affiliate Commission Hijacking Finding 8 — Content Script Privilege Escalation Bridge Finding 9 — Arbitrary URL Redirect on Any Domain Finding 10 — CSP Erasure Complete Attack Chain Indicators of Compromise What browser-xpi-malware-scanner.py Catches and Why 1. How browser-xpi-malware-scanner.py Found This Extension Running browser-xpi-malware-scanner.py against the XPI produces the following top-level verdict immediately: [i] Analyzing XPI: ../../YTMP4 - Download YouTube Videos to MP4.xpi ════════════════════════════════════════════════════════════════════════ XPI ANALYZER — YTMP4 - Download YouTube Videos to MP4.xpi ════════════════════════════════════════════════════════════════════════ Overall verdict: CRITICAL RISK Findings: 1 CRITICAL 24 HIGH 17 MEDIUM 1 INFO ── CRITICAL ────────────────────────────────────────────────────────── [CRITICAL] [PNG_APPENDED] icon/logo.png: 1902 bytes appended after PNG IEND (entropy=5.63) — classic stego carrier CODE: b'ncige\x1f\xe3\xbd\xa9\x18\xe3\xa1\x84\xe1\xa1\xa1\x18\xe3\xa1\xb9\x1f\xe3\xbd\xb3\x1c\xe3\xb0\xba\x1b\xe5\xac\xa0\r\n\… ── HIGH ────────────────────────────────────────────────────────────── [HIGH ] [CLASS_STORAGE_OVERLAP] js/content.js: String literal 'ncige' appears both as a JS string in this file and as an HTML class attribute in index.html — likely used as a covert stego marker or out-of-band key CODE: class='ncige' in index.html [HIGH ] [CLASS_STORAGE_OVERLAP] js/content.js: String literal '7yfuf2' appears both as a JS string in this file and as an HTML class attribute in index.html — likely used as a covert stego marker or out-of-band key CODE: class='7yfuf2' in index.html [HIGH ] [JS_OBFUSCATION] js/content.js:380 atob() — decoding base64 at runtime (possible payload decode) CODE: '); fileTip = atob(contentPool[screenValues]).replace(image [HIGH ] [JS_OBFUSCATION] js/content.js:719 atob() — decoding base64 at runtime (possible payload decode) CODE: return dataExt ? atob(atob(this)) : btoa(this).replace(/=/g, " [HIGH ] [JS_OBFUSCATION] js/content.js:719 atob() — decoding base64 at runtime (possible payload decode) CODE: turn dataExt ? atob(atob(this)) : btoa(this).replace(/=/g, ""); [HIGH ] [JS_OBFUSCATION] js/content.js:2364 atob() — decoding base64 at runtime (possible payload decode) CODE: ol); }); return atob(dataExt); } function getComponentNam [HIGH ] [JS_OBFUSCATION] js/snapany.com.js:126 decodeURIComponent(escape()) — encoding trick to bypass scanners CODE: return decodeURIComponent(escape(i.bin.bytes...

Share this article