ghost_sec writes
Mobile App Sec · Case Study

Breaking a crypto vault

A full kill chain against a high-value digital-asset password manager on Android and iOS: how a split encryption key, leaked pipeline secrets, an MFA logic flaw, a client-controlled subscription and broken access control chained from "no account" to admin control and unauthenticated data exposure.

@ghost_sec Mobile & API case study Educational write-up

00What this application is, and why it matters

The target was a password and secrets manager built for the cryptocurrency world, delivered as Android and iOS applications: a vault that stores the logins, keys and recovery material that gate access to digital assets. In a normal application, a breach means exposed data. In a vault like this, the contents are the money. Access to the vault can mean access to irreversible, bearer-style assets, where a single successful theft has no chargeback, no reversal and no insurer of last resort.

Because it is a mobile product, some of the vault lives on the device. The apps stored user data locally and protected it with client-side encryption, which puts the secrecy of a key in the one place an attacker fully controls: the handset in their hand. The engagement covered both app binaries, the data they left on the device, and the backend API they talk to. Around that sat tiered subscriptions with premium vault features, multi-factor authentication, management of user devices and sessions, an administrative console, and a cloud backend behind a web application firewall. On the surface, a serious security posture for a serious product.

The assessment told a different story. None of the individual issues was exotic. Chained together, they took the engagement from no account at all to administrative control and unauthenticated data exposure, against the one class of product that can least afford it. This is the walk-through, sanitised: no organisation, product, person, host or credential is named, and the explanation stays at the level of technique and lesson rather than a runbook.

Note. This write-up is for educational purposes only. The techniques described illustrate offensive security methodology and are intended to help defenders understand and improve their detection capabilities.

01The kill chain at a glance

A reconstructable encryption key. Static analysis recovered the field-encryption key in two halves, one hardcoded in the app, one in a public third-party repo it pointed to, alongside other unrotated secrets from the build pipeline.
Account enumeration without limits. Differential responses revealed valid accounts, and no rate limiting left authentication open to unrestricted testing.
MFA bypass. A logic flaw in the second-factor step reduced authentication to single factor in practice, granting a session.
Subscription manipulation. A client-controlled tier parameter granted premium vault features without payment.
Broken access control. Replayed requests reached admin-only actions and audit logs with no server-side privilege check.
Infrastructure exposure. An admin console reachable from anywhere, default database credentials, and a weak firewall ruleset opened the backend.
Unauthenticated impact. SSRF and an unauthenticated file-download path exposed internal reach and stored data with no login at all.

02Stage one: a key in two halves, and a leaking pipeline

The intrusion began before any login attempt, in the app itself. Because the vault encrypts user data on the device, the key that protects it has to exist somewhere the app can reach, and static analysis of the Android and iOS binaries is where that search starts.

The design tried to hide the field-encryption key by splitting it in two. One half was hardcoded in the application. The other was not shipped in the binary at all; instead the app carried a hardcoded URL pointing to a public repository of a third-party library, which hosted the second half. Pulling the app apart revealed the first half and the pointer; following the pointer gave up the second. Combined, they reconstructed the key that protected the data stored on the device. Splitting a secret across two readable locations is obfuscation, not protection: both halves were ultimately in the attacker's reach.

Separately, reconnaissance of the target's build pipeline surfaced further hardcoded secrets that had never been rotated and were still valid at test time, including application API keys and an OIDC private signing key. Leaked secrets are common; unrotated leaked secrets with cryptographic weight are the dangerous kind. A reconstructable field-encryption key undermines the confidentiality of on-device data, and an OIDC signing key undermines the trustworthiness of the identity tokens the application issues. Before a single credential was guessed, the engagement already held cryptographic material and authenticated API access.


03Stage two: an authentication layer with no brakes

With the surface mapped, the registration endpoint gave away which email addresses already had accounts, through small differences in how it responded to known versus unknown addresses. On its own, user enumeration is low severity. What made it matter was the next gap: the authentication endpoints had no rate limiting. Nothing throttled or locked out repeated attempts, which turned every authentication step into something an attacker could test at volume. That absence is what set up the stage that followed.


04Stage three: the MFA bypass, explained

Multi-factor authentication is meant to be the backstop after credential compromise. Its entire value rests on one assumption: that an attacker who has valid credentials still cannot satisfy the second factor without the user's device or token. In this product, that assumption did not hold. Because the MFA issue is the hinge of the whole chain, it is worth explaining as a vulnerability class, without any sensitive detail.

Vulnerability deep-dive · MFA bypass

Class of weakness

The bypass sits at the intersection of an authentication-flow logic flaw and missing rate limiting. Neither alone is as damaging as the two together; they compound.

How it works, conceptually

Web frameworks usually enforce brute-force protection through middleware or a library on authentication endpoints. When that protection is applied inconsistently, guarding the password step but not the second-factor step, or when its enforcement can be influenced by client-controlled input, the protection effectively disappears for the step it misses.

Here the verification step for the second factor did not carry the same protection applied elsewhere in the flow. That asymmetry is the flaw: the first factor was guarded, but the second-factor check could be exercised freely. Short, time-based codes have a small character space and a brief validity window, so without a lockout or throttle on that step, systematically working through the valid space inside the window becomes a realistic attack rather than a theoretical one.

Why it matters

MFA is typically the last line of defence after a credential is phished, leaked or reused. Bypassing it quietly reduces the whole model to single factor, so leaked or reused credentials alone become sufficient, which is exactly the outcome the control existed to prevent.

Root cause

The protective mechanism relied on a library responsible for tracking and limiting authentication attempts, and that enforcement was not applied consistently across every step of the multi-factor flow. The second-factor verification was left exposed to unrestricted testing.

With the second factor neutralised, the engagement held an authenticated session. From here, the assessment moved from breaking in to abusing what being inside allowed.


05Stage four: the price of a premium tier was a parameter

During registration, the subscription tier was decided by the client, with no server-side enforcement behind it. Choosing an elevated package was simply a matter of asking for it, which granted premium vault features without any payment. This is classic business-logic abuse: the server trusted the client to state what it was entitled to, and the client is the one place an attacker fully controls. Beyond the obvious revenue impact, premium tiers often unlock functionality that widens the attack surface further.


06Stage five: admin actions from a standard account

Authenticated as an ordinary user, requests were replayed with modified identifiers aimed at administrative endpoints. Broken access control did the rest: the server enforced no privilege check, so a standard account could trigger admin-level device actions and pull audit and security logs meant only for administrators. Authorisation that is assumed in the interface but never enforced at the API is one of the most reliable ways a normal user becomes an administrator.

Every layer trusted the one before it. The client picked its tier, the API trusted the client, and the admin functions trusted the API.


07Stage six: the infrastructure underneath

The administrative console and its API were reachable from arbitrary addresses, with no network restriction placing them behind a trusted boundary. Behind them, default database credentials were still active, granting direct access to the backend data store, and the perimeter firewall's ruleset was weak enough to bypass. A management plane exposed to the whole internet, protected by a password that ships in the box, is the point where an application issue becomes an infrastructure one.


08Stage seven: impact with no login at all

Finally, two issues were confirmed without any authentication, independent of the session work above:

These mattered on their own, but in context they close the loop: even a visitor who never cleared the front door could reach internal services and stored files.


09Why each link held

StageRoot causeVulnerability class
Encryption keyField-encryption key split across the app binary and a public repo; pipeline secrets unrotatedInsecure key storage
EnumerationDifferential responses reveal valid accountsInformation disclosure
No rate limitingAuth steps not throttled or locked outMissing anti-automation
MFA bypassRate-limit protection not applied to the second-factor stepAuth logic flaw
Subscription abuseClient-controlled tier, no server-side checkBusiness-logic flaw
Admin accessNo server-side authorisation on admin endpointsBroken access control
InfrastructureExposed console, default DB credentials, weak firewallSecurity misconfiguration
Unauth impactServer-side fetch of attacker URLs; unauthenticated downloadsSSRF / access control

10What would have broken the chain

The individual flaws here are the familiar furniture of application security. The lesson of a vault is that chaining still works, and when the product guards irreversible assets, a chain that ends in admin and unauthenticated data access is not a finding to schedule, it is the whole risk.