• George
  • Posts
  • Spending 2 hours a night looking for BAC bugs on Hackerone & Bugcrowd

Spending 2 hours a night looking for BAC bugs on Hackerone & Bugcrowd

2-Hour Nightly Plan to Find BAC Bugs in Modern RESTful APIs

Goal: Hunt BAC vulnerabilities (e.g., IDORs, unauthorized access) in HackerOne/Bugcrowd programs with RESTful APIs, where user/resource IDs are obscured (e.g., UUIDs like 550e8400-e29b-41d4-a716-446655440000) and passed in paths, bodies, or headers.

Step 1: Pick a Juicy Target (10 min)

  • Choose a Program:

    • Log into HackerOne or Bugcrowd.

    • Select public programs with broad scopes (e.g., *.target.com) or private invites for less competition.

    • Target apps with RESTful APIs and user-driven features:

      • E-commerce: Order retrieval, account settings (e.g., APIs for cart, wishlist).

      • SaaS Platforms: User dashboards, team management (e.g., APIs for projects, reports).

      • Social Apps: Profiles, posts, messages (e.g., APIs for feeds, DMs).

      • Why? These apps manage user-specific resources (orders, files, teams) and roles (user, admin), ripe for BAC flaws despite obscured IDs.

    • Check bounty tables: Look for payouts for “Unauthorized Access,” “IDOR,” or “Privilege Escalation” to confirm BAC is valued.

    • Glance at recent reports (if public) for API-related bugs to gauge potential.

  • Select a Juicy URL:

    • Focus on API endpoints (e.g., api.target.com, app.target.com/v1) or main apps with heavy JavaScript (React, Vue) that call REST APIs.

    • Avoid non-API assets (e.g., static marketing.target.com)—check scope in program policy.

    • If possible, check the target’s API docs (e.g., api.target.com/docs, Swagger UI) or blog for new endpoints (e.g., “We launched /api/v2!”)—new APIs often skip access checks.

    • Pro Tip: Subdomains like beta.target.com or graphql.target.com may expose less-tested APIs, but confirm they’re in scope.

Step 2: Set Up and Collect Logs (40 min)

  • Configure Burp Suite (5 min):

    • Open Burp Suite (Community/Pro).

    • Proxy your browser through Burp.

    • Set scope to the target (e.g., https://api.target.com) to reduce noise.

    • Enable HTTP history logging (Proxy > Options > Log all requests).

  • Interact with the App (30 min):

    • Create Two Accounts: Register as [email protected] and [email protected] (use disposable emails if needed) to test horizontal BAC later.

    • Explore RESTful Features:

      • Navigate core functions: view profiles, fetch orders, manage teams, download files, or post content.

      • Trigger API-heavy actions: search, sort, export data, or update settings (e.g., change email, add teammate).

      • Look for single-page app (SPA) behavior (URL doesn’t change much)—these rely on APIs like GET /api/v1/users/me or POST /api/v2/orders.

    • Force API Exposure:

      • Open browser DevTools (Network tab) alongside Burp to spot API calls (e.g., fetch('/api/v1/files/550e8400...')).

      • Try invalid inputs (e.g., paste a random UUID in a URL like /files/xyz) to trigger error responses that leak endpoints.

      • Check for GraphQL (e.g., /graphql)—query user(id:"abc") often exposes IDs.

    • Switch Accounts: Log in/out as hunter1 and hunter2 to capture different tokens (e.g., Authorization: Bearer xyz). If roles exist (e.g., user vs. manager), test both.

    • Goal: Generate Burp logs with 10–20 RESTful requests, focusing on:

      • Path-based IDs: GET /api/v1/orders/550e8400-e29b-41d4-a716-446655440000.

      • JSON Bodies: POST /api/v1/files with {"file_id":"abc123"}.

      • Headers: X-User-Id: def456 or Authorization: Bearer ....

  • Quick Log Review (5 min):

    • In Burp’s HTTP history, filter for:

      • API Paths: /api, /v1, /v2, /graphql.

      • UUIDs/Hashed IDs: Look for long strings (e.g., 550e8400..., abc123xyz) in URLs, bodies, or headers.

      • Sensitive Methods: GET (fetch data), POST/PUT (update), DELETE (remove).

    • Search for keywords: user, account, order, file, admin, settings.

    • Tag 2–3 requests with obscured IDs or admin-like paths (e.g., GET /api/v1/users/abc123, POST /api/v2/team).

Step 3: Test for BAC (60 min)

  • Analyze Logs (10 min):

    • Select 2–3 requests from Burp’s logs with:

      • Obscured IDs: UUIDs or hashes in paths (e.g., /orders/550e8400...), bodies (e.g., {"user_id":"abc123"}), or headers (e.g., X-Account-Id: def456).

      • Admin Endpoints: /api/v1/admin/*, /api/v2/settings, /api/users/list.

      • Sensitive Data: Responses with user info (e.g., {"id":"abc123","email":"[email protected]"}) or resources (orders, files).

    • Ignore generic requests (e.g., /api/health, 200 OK with no data).

  • Test Horizontal Privilege Escalation (25 min):

    • What: Accessing another user’s resources (e.g., hunter1 views hunter2’s files) by swapping obscured IDs.

    • How:

      1. Identify a request with an obscured ID, e.g.:

        GET /api/v1/profile/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
        Host: api.target.com
        Authorization: Bearer hunter1_token
        
      2. Find hunter2’s ID:

        • Log in as hunter2, repeat the same action (e.g., view profile), and check Burp logs for their ID (e.g., GET /api/v1/profile/6ba7b810-9dad-11d1-80b4-00c04fd430c8).

        • Or, if the app exposes IDs (e.g., via /api/v1/users/me), note hunter2’s UUID.

      3. Send to Repeater:

        • Use the original request (/profile/550e8400...) with hunter1’s token (Bearer hunter1_token).

        • Replace the ID with hunter2’s (e.g., /profile/6ba7b810...).

      4. Send the request.

      5. Check Response: If you get {"id":"6ba7b810...","email":"[email protected]"}, it’s an IDORhunter1 accessed hunter2’s data.

      6. Test Updates:

        • If logs show a POST, e.g.:

          POST /api/v1/profile HTTP/1.1
          Host: api.target.com
          Authorization: Bearer hunter1_token
          {"profile_id":"550e8400...","email":"[email protected]"}
          
        • Try {"profile_id":"6ba7b810...","email":"[email protected]"} with hunter1’s token.

        • If it updates hunter2’s profile, it’s a critical BAC bug.

      7. Alt Test: If IDs are in headers (e.g., X-User-Id: abc123), swap hunter1’s ID for hunter2’s and check for leaks.

    • Validate: Log in as hunter2 (if ethical) to confirm their data was exposed (e.g., view their profile).

    • Burp Tip: Use Comparer to diff responses (e.g., hunter1’s ID vs. hunter2’s ID) for unauthorized data.

  • Test Vertical Privilege Escalation (25 min):

    • What: Accessing admin or restricted features as a normal user (e.g., hunter1 lists all users).

    • How:

      1. Find a potential admin endpoint in logs, e.g.:

        GET /api/v1/admin/users HTTP/1.1
        Host: api.target.com
        Authorization: Bearer hunter1_token
        
        • Likely found via errors, DevTools, or clicking “Settings.”

      2. Send to Repeater with hunter1’s token (normal user).

      3. Send unchanged.

      4. Check Response: If you get 200 OK with sensitive data (e.g., [{"id":"xyz","email":"[email protected]"}]), it’s a vertical BAC bug—the API didn’t enforce admin privileges.

      5. Alt Test:

        • Try without a token (remove Authorization header). A 200 response means no auth check—huge flaw.

        • If logs show role-based bodies (e.g., POST /api/v1/roles with {"role":"user"}), try {"role":"admin"} with hunter1’s token.

      6. GraphQL Check (if applicable):

        • If logs show /graphql, look for queries like:

          POST /graphql HTTP/1.1
          {"query":"{ user(id:\"abc123\") { email } }"}
          
        • Try hunter2’s ID or an admin-like query (e.g., { allUsers { email } }) with hunter1’s token.

      7. Validate: Test the same endpoint with hunter2’s token to ensure it’s not a false positive (e.g., meant for all users).

    • Burp Tip: Use Copy/Paste Token in Repeater to swap hunter1/hunter2 tokens quickly.

Step 4: Document and Save (10 min)

  • If You Find BAC:

    • Screenshot Burp’s request/response (e.g., hunter1 accessing hunter2’s UUID-based profile).

    • Note: Endpoint (e.g., /api/v1/profile/6ba7b810...), ID used, impact (e.g., “Leaked another user’s email”).

    • Draft a report in HackerOne/Bugcrowd but verify before submitting (e.g., reproducible with both accounts).

  • No Bug?:

    • Save Burp project (File > Save Project) to pick up tomorrow.

    • Tag untested endpoints (e.g., /api/v2/files/xyz) for the next session.

  • Ethical Note: Avoid modifying data (e.g., updating hunter2’s profile) unless explicitly allowed. Focus on read-only tests.

Key Tips for RESTful APIs with Obscured IDs

  • Target Selection: Pick API-heavy programs (check for /api in scope). If they mention GraphQL or REST, even better.

  • Log Focus: Search Burp for UUIDs (32+ chars, hex/dashes) or hashes (e.g., abc123xyz) in:

    • Paths: /users/550e8400....

    • Bodies: {"file_id":"abc123"}.

    • Headers: X-Resource-Id: def456.

  • ID Hunting:

    • Obscured IDs aren’t guessable like 123, so rely on your two accounts. Get hunter1’s and hunter2’s IDs from logs (e.g., /api/v1/me).

    • If IDs are missing, check responses for lists (e.g., /api/v1/orders may return [{"id":"xyz","user":"[email protected]"}]) or errors leaking IDs.

  • Testing Speed: Test 1–2 endpoints per night (1 horizontal, 1 vertical). Repeater is key for swapping UUIDs/tokens.

  • Burp Hacks:

    • Use regex in HTTP history: [0-9a-f]{8}-[0-9a-f]{4} for UUIDs.

    • Filter for application/json responses to spot RESTful APIs.

    • Save tokens in Burp’s Session Handling to auto-apply hunter1/hunter2.

  • REST Nuance: Modern APIs use PATCH or PUT for updates (e.g., PATCH /api/v1/users/abc123). Test these like POSTs for unauthorized changes.

Example Night

  • 8:00–8:10: Pick api.target.com (SaaS, $1,000 for IDORs, RESTful API).

  • 8:10–8:50: Register hunter1/hunter2, fetch profiles, tag:

    • GET /api/v1/users/550e8400... (hunter1’s UUID).

    • GET /api/v1/admin/stats (error response hinted at admin).

  • 8:50–9:50:

    • Horizontal: In Repeater, use hunter1’s token, swap UUID to hunter2’s (/users/6ba7b810...). Get {"email":"[email protected]"}—IDOR!

    • Vertical: Test /api/v1/admin/stats with hunter1’s token. Returns {"total_users":1000}—unauthorized access!

  • 9:50–10:00: Screenshot Burp, save project, note findings.