- All Or Nothing
- 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.comorgraphql.target.commay 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/meorPOST /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)—queryuser(id:"abc")often exposes IDs.
Switch Accounts: Log in/out as
hunter1andhunter2to 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/fileswith{"file_id":"abc123"}.Headers:
X-User-Id: def456orAuthorization: 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 OKwith no data).
Test Horizontal Privilege Escalation (25 min):
What: Accessing another user’s resources (e.g.,
hunter1viewshunter2’s files) by swapping obscured IDs.How:
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_tokenResponse:
{"id":"550e8400...","email":"[email protected]"}(hunter1’s profile).
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), notehunter2’s UUID.
Send to Repeater:
Use the original request (
/profile/550e8400...) withhunter1’s token (Bearer hunter1_token).Replace the ID with
hunter2’s (e.g.,/profile/6ba7b810...).
Send the request.
Check Response: If you get
{"id":"6ba7b810...","email":"[email protected]"}, it’s an IDOR—hunter1accessedhunter2’s data.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]"}withhunter1’s token.If it updates
hunter2’s profile, it’s a critical BAC bug.
Alt Test: If IDs are in headers (e.g.,
X-User-Id: abc123), swaphunter1’s ID forhunter2’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.,
hunter1lists all users).How:
Find a potential admin endpoint in logs, e.g.:
GET /api/v1/admin/users HTTP/1.1 Host: api.target.com Authorization: Bearer hunter1_tokenLikely found via errors, DevTools, or clicking “Settings.”
Send to Repeater with
hunter1’s token (normal user).Send unchanged.
Check Response: If you get
200 OKwith sensitive data (e.g.,[{"id":"xyz","email":"[email protected]"}]), it’s a vertical BAC bug—the API didn’t enforce admin privileges.Alt Test:
Try without a token (remove
Authorizationheader). A200response means no auth check—huge flaw.If logs show role-based bodies (e.g.,
POST /api/v1/roleswith{"role":"user"}), try{"role":"admin"}withhunter1’s token.
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 } }) withhunter1’s token.
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/hunter2tokens quickly.
Step 4: Document and Save (10 min)
If You Find BAC:
Screenshot Burp’s request/response (e.g.,
hunter1accessinghunter2’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
/apiin 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. Gethunter1’s andhunter2’s IDs from logs (e.g.,/api/v1/me).If IDs are missing, check responses for lists (e.g.,
/api/v1/ordersmay 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/jsonresponses 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 tohunter2’s (/users/6ba7b810...). Get{"email":"[email protected]"}—IDOR!Vertical: Test
/api/v1/admin/statswithhunter1’s token. Returns{"total_users":1000}—unauthorized access!
9:50–10:00: Screenshot Burp, save project, note findings.