ezBookkeeping - v0.7.0 - OTP Bruteforce

By 0xhamy 03:01 AM - September 29th 2025
Type software
Product Environment web
Product Name ezBookkeeping
Product Vendor Mayswind
Product Version 0.7.0
Product Link https://github.com/mayswind/ezbookkeeping
Vulnerability Name OTP Bruteforce
Severity High
CVSS String CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score 8.8
CVE ID CVE-2024-57604
Vendor Acknowledgement Yes
Affected digital Assets 100
Affected Users 100
Date of Reporting Dec 27, 2024
PoC Exploit https://gist.github.com/0xHamy/908011130bc8ec05db3ac9bc54c7593a
Credit 0xhamy

Description

The 2-factor recovery flow allows an attacker with valid username/password to repeatedly request short-lived recovery tokens and brute-force backup (recovery) codes. Each token permits ~10 attempts before expiring, but the attacker can simply re-login to obtain another token and continue trying codes until one succeeds. A successful recovery code exchange returns a token that grants full account access, enabling actions like changing the account email or disabling 2FA — resulting in full account takeover.


Reproduce

  1. Preconditions: an existing account (no privileged access required) and a list of candidate recovery codes.
  2. Login to the application: POST /api/login (or use the UI at http://10.0.0.94/desktop#/login) with valid username and password. The app returns a short-lived bearer token for the 2FA/recovery step.
  3. Choose the “use backup code” option on the 2FA prompt. Submit a recovery code to the recovery endpoint:
POST /api/2fa/recovery.json HTTP/1.1
Host: 10.0.0.94
Content-Type: application/json
Authorization: Bearer [Redacted short-lived token]
Cookie: [Redacted]
Content-Length: 30

{"recoveryCode":"8cv9j-i136a"}
  1. Observe response (success/failure). The token allows roughly 10 attempts before it expires; re-login yields a new token.
  2. Repeat: re-login and submit another batch of up to ~10 codes, repeat until a correct code is found. On success the system returns an auth token that enables full account access (e.g., email change, disable 2FA).
  3. Impact: automated chaining of login → 10 attempts → re-login → 10 attempts allows an attacker to brute-force a user’s set of backup codes and fully take over the account.

Recommendation

  • Scope tokens tightly: Issue recovery tokens with the narrowest possible scope (only allow a single recovery code submission) and make them single-use. A token that permits only one submission removes the lease for brute force chaining.
  • Enforce server-side attempt limits: Track and enforce per-account and per-token attempt counters server-side (e.g., allow ≤3 failed recovery submissions per token/account before temporary lockout) and block further attempts for a cooldown period.
  • Rate limit and backoff: Implement strict rate limits and exponential backoff for recovery submissions per account, per IP, and per token. Consider short account lockouts or progressive delays after repeated failures.
  • Treat recovery flow as high-sensitivity: Require additional verification for sensitive post-recovery actions (changing email, disabling 2FA). For example, require the account password again or confirmation through the registered email before making those changes.
  • Use one-time backup codes: Ensure backup codes are generated server-side as single-use values and stored hashed. When a code is used (or exhaustion is detected), invalidate it immediately.
  • Protect token issuance: Throttle the login endpoint itself (limit how often an account can obtain a new recovery token) and monitor for repeated login+recovery patterns indicative of automated attacks.
  • Detect and alert: Log recovery attempts and alert on suspicious patterns (high volume of recovery attempts across accounts, repeated re-logins immediately followed by recovery submissions).
  • UX/security improvements: Consider requiring a short (e.g., 24-48 hour) cooling period after N failed recovery attempts or sending an out-of-band notification (email/SMS) when recovery is attempted or when recovery settings are changed.
  • Defense-in-depth: Deploy a WAF or bot-protection (CAPTCHA, device fingerprinting) on the recovery endpoint to slow/stop automated brute-force chains.

Applying the combination of scoped single-use tokens, server-enforced attempt limits, and requiring re-authentication for sensitive changes will prevent the described chaining attack and greatly reduce the risk of account takeover.