Lab: Bypassing rate limits via race conditions
Predict a potential collision
After logging in to the exercise, your screen should look like the screenshot. The first step is to examine the login functions of the application. To do this, click on the ‘My account’ link at the top left. Note that this exercise has a timer that ends after 15 minutes. You will have to start the exercise again from the beginning if you run out of time.

We will now experiment a little with the login form. First, we enter the wrong password for the user wiener
four times. For the first three incorrect entries, we receive the message ‘Invalid username or password.’.

If we now enter an incorrect password for the fourth time, we receive the message ‘You have made too many incorrect login attempts. Please try again in 112 seconds.’ and we cannot make any further login attempts until the time has expired.

If we choose a different username, e.g. carlos, we will again receive the message ‘Invalid username or password.’ From this it can be deduced that the number of failed attempts per username must be saved on the server side. Please note that there may be a time delay between the submission of the login attempt and the increase in the failed login attempts counter on the website in connection with a particular username.

Benchmark the behavior
We now switch to the Burp Proxy and open the ‘HTTP history’ tab there. Now we search for a POST /login
request that receives an unsuccessful login attempt for our own account.

We send this enquiry to Burp Repeater. To do this, move the mouse over the request and press the right mouse button. A context menu opens in which we select the option ‘Send to Repeater’.

We now switch to the Burp Repeater and create a new tab group. To do this, we click on the plus sign next to the tab and select the option ‘Create tab group’.


A window appears in which we enter a name for the tab group, here ‘RC-2’ is used as the name. The first tab is selected in the second section.

Now we right-click on the tab in our tab group and select the ‘Duplicate tab’ option.

In the window, we specify how often we want to duplicate the tab. We enter ‘19’ there.

If you need more information about creating tab groups, you can find it in the Burp Suite documentation.
We now configure the Burp Repeater so that we send the requests in the ‘RC-2’ tab group to the application one after the other via separate connections. To do this, we click on the down arrow next to the ‘Send’ button.

There we select the option ‘Send group in sequence (separate connections)’.

The ‘Send’ button should now look like this:

We now send this tab group to the application and analyse the responses. Three responses were received with the message ‘Invalid username or password.’, all other responses contain the message ‘You have made too many incorrect login attempts. Please try again in 111 seconds.’. Everything as expected. If you need more information about sending requests via separate connections, you can find it in the Burp Suite documentation (https://portswigger.net/burp/documentation/desktop/tools/repeater/send-group#sending-requests-in-sequence).
Probe for clues
We now send the tab group with the option ‘Send group in parallel (single-packet attack)’.

If we now analyse the responses, we see that we have received the message ‘Invalid username or password.’ for all responses. Now we switch to the browser once and refresh the login form. Here we can see that the username wiener
has been blocked anyway.

From this we can conclude that if we are fast enough, we can make more than three login attempts before our account is blocked.
Prove the concept
We go back to the Burp Repeater and open the first request (POST /login
) in the Request section. In the request, move the mouse over the value of the password parameter and press the right mouse button.

A context menu appears in which we select ‘Extensions’, ‘Turbo Intruder’ and then ‘Send to turbo intruder’.



The Turbo Intruder extension will now open. You can see the request in the upper section. If you scroll down to the body of the request, you will see that the value of the password parameter has been set to the placeholder %s
.

We are now changing the user name from wiener
to carlos
.

We now select the script ‘example/race-single-packet-attack.py’ in the Turbo Intruder dropdown field.

We can insert the following code in the Python editor of the Turbo Intruder.
def queueRequests(target, wordlists):
# as the target supports HTTP/2, use engine=Engine.BURP2 and # concurrentConnections=1 for a single-packet attack
engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, engine=Engine.BURP2 )
# assign the list of candidate passwords from your clipboard
passwords = wordlists.clipboard
# queue a login request using each password from the wordlist # the 'gate' argument withholds the final part of each request # until engine.openGate() is invoked
for password in passwords:
engine.queue(target.req, password, gate='1')
# once every request has been queued # invoke engine.openGate() # to send all requests in the given gate simultaneously
engine.openGate('1')
def handleResponse(req, interesting):
table.add(req)
In line 7 you can see the code passwords = wordlists.clipboard
, before we start the attack we have to copy the passwords of the password list from the start page of the exercise.

After the attack has ended, we now analyse the responses in the Turbo Intruder. If a 302 Found
response was received, then a login attempt was successful. We should make a note of the password.

In our example, it is the password 111111
. If no 302 Found
response is received, simply repeat the attack. To do this, wait until the account lock is cancelled and then start the attack.
Now we log in to the application with the user name carlos
and the password 111111
.

At the top left, click on the ‘Admin panel’ link to delete the user carlos.

Click on the ‘Delete’ link to complete the exercise.

Video solution
Last updated