Account Takeover via Weak Encryption and Insecure Storage in Aquarius Desktop macOS

Note: No exploit code is released publicly, and the intent of this publication is to promote remediation and improve the security posture of the affected software. This disclosure follows the 90-day industry-standard timeline for responsible reporting. Want the details? Keep scrolling. The full timeline, contact history, and instructions for securely requesting the encrypted PoC are available further down the page.

Introduction

Welcome back!

This is post 2 of 3 into the security design of Aquarius Desktop.

After finding the local privilege escalation vulnerability in the Aquarius Desktop’s HelperTool XPC service, I continued digging into the application’s security design. This time, the focus shifted from privilege escalation to how the application handles authentication and persistence and what I found was equally concerning.

In this second part of my Aquarius Desktop analysis, I discovered that the app stores user credentials in a local configuration file (aquarius.settings) using weak encryption and without any device binding or integrity checks. This design allows an attacker to either exfiltrate the file to gain full account access on another machine, or decrypt the stored password entirely offline using a simple script.

While this mechanism appears to have been implemented to improve usability which enables producers to access their plugins across multiple systems, it ultimately introduces a severe account takeover risk. In this post, I’ll break down how the vulnerability works, why the encryption fails to protect users, and how it can be remediated without sacrificing convenience for legitimate users.

Vulnerability Overview

Now, this vulnerability is quite interesting. The Aquarius Desktop application stores user authentication data in a file called aquarius.settings located at:

~/Library/Application Support/Aquarius/aquarius.settings

This file includes sensitive fields such as:

<USERNAME>
<OLDUSERNAME>
<PASSWORD>
[...]

The problem lies in how this file is handled:

  • It is not cryptographically bound to the device.
  • It lacks integrity validation, making it fully portable.
  • The user’s password is encrypted with a static Blowfish key and ECB mode, allowing offline decryption.

For the account takeover via file import, an attacker with access to the aquarius.settings file (via local access, malware, or chaining with the previous LPE exploit) can simply copy it to another machine, relaunch Aquarius Desktop, and gain full authenticated access to the victim’s account without ever needing their credentials.

The app assumes that the presence of this file means the user is already authenticated so it restores the session without checking anything.

Think of it this way… anyone with access to the aquarius.settings file can take over your account. All they need is the encrypted string from the <PASSWORD> field because Aquarius “protects” it using a static Blowfish key hardcoded directly in the binary:

potkseD suoirauqA

This key is embedded in the binary and can be extracted via dynamic analysis (e.g., LLDB, etc). Because the Blowfish implementation uses ECB mode without any salt or IV, and the key isn’t tied to a specific user or device, the encryption is completely reversible.

I developed a Python script that:

  • Takes the base64-encoded string from aquarius.settings
  • Applies the static Blowfish key
  • Reverses 32-bit endianness (a quirk of how JUCE structures its data)
  • Outputs the original password in plaintext

This allows for offline password cracking in seconds, potentially enabling credential reuse across services if the same password is used elsewhere.

Proof of Concept

The password value in aquarius.settings is encrypted using a statically derived Blowfish key. Dynamic analysis with LLDB and disassembly of the juce::BlowFish::encrypt / decrypt methods confirmed the use of Blowfish in ECB mode with a hardcoded key. The password is encrypted and base64-encoded before being stored. We can set a breakpoint at juce::BlowFish::encrypt to revealed key input during runtime. Then, analysis of decrypted output revealed fixed 32-bit word reordering (endianness swap) and this mean the Blowfish key was static and not derived per user or per machine.

Looking at the LLDB debugging session, we can hit the breakpoint by triggering the juce::BlowFish::encrypt function. At the time of execution, register x21 holds the encryption key used by the application “potkseD suoirauqA”. This is the static hardcoded Blowfish key for encryption operations. Also, registers x22 and x23 point to the cipher’s initialized S-box and P-array structures, showing that standard Blowfish internals are in use.

With the key pulled from memory (potkseD suoirauqA), I was able to decrypt the password stored in aquarius.settings using a short Python script that mirrors the app’s Blowfish routine. The script takes the base64-encoded string, applies the static key, and returns the original password in plain text all without needing access to the original device. If someone gets a copy of this file, they can recover the user’s password in seconds.

I intentionally used a long, messy password with spaces and symbols to prove that it doesn’t matter. Any password gets decrypted the same way.

python3 poc_cracking.py -p “Yf21qsqdjAeVYVdclDSAEfoaG2Ck8HdIyQPdnhg4/sSpHlcmWLR1BUd6NkYj7V6a74PR2VC/6QE=-k “potkseD suoirauqA” -a

Once you have the password, you can log in as the user with full access to their account, plugins, downloads, and anything else linked to it.

This can be chained with the HelperTool XPC Service Local Privilege Escalation in Aquarius Desktop macOS to extract the aquarius.settings file.

Remediation

To fix this issue without breaking usability, Aquarius Desktop should stop storing user passwords locally even in encrypted form. Instead, the application should:

  • Use device-bound session tokens: Replace stored passwords with short-lived authentication tokens that are cryptographically tied to the device they were issued on. If the aquarius.settings file is copied to another system, the token should become invalid.
  • Adopt secure token storage: On macOS, use the Keychain to store sensitive authentication material. On Windows, use DPAPI. Never store secrets in plaintext files within user-writable directories.
  • Implement integrity checks: Add digital signatures or HMAC verification for local auth files. This would make tampering or reuse across systems detectable and prevent silent account takeover.
  • Leverage OAuth or refresh token flow: If cross-device access is required, use an authentication flow that allows secure re-authentication (e.g. OAuth2 + refresh tokens) rather than persisting long lived credentials.

These changes would preserve the current usability benefits (seamless plugin access across systems) while removing the risk of file based account takeover and offline password cracking.

Disclosure timeline

Date Action
August 2, 2025Vulnerability discovered during local security analysis of Aquarius Desktop and its helper components.
August 3–5, 2025Initial technical validation and proof-of-concept developed confirming local privilege escalation via the HelperTool XPC service.
August 7, 2025Full vulnerability report prepared, including reproduction steps and secure remediation guidance.
August 18, 2025Request for CVE to Mitre
August 19, 2025Responsible disclosure email sent to Acustica Audio with attached reports and researcher PGP key requesting a secure communication channel.
August 23, 2025No acknowledgment received from the vendor; follow-up email sent.
September 2, 2025No acknowledgment received from the vendor; follow-up email sent.
September 19, 2025Escalation attempt submitted to MITRE CVE Program for coordination assistance.
October 31, 2025No vendor or CNA response received; proceeding with public disclosure in accordance with a 90-day coordinated disclosure policy.