Introduction
In this lab, we tackled a race condition vulnerability that exploits flawed synchronization between multiple endpoints interacting with shared data. Unlike typical race conditions involving repeated requests to a single endpoint, this lab required us to coordinate concurrent requests across different endpoints within a narrow timing window.
Modern web applications often process requests through hidden multi-step sequences, or sub-states, where transient logic is applied before reaching a final state. If these sub-states are accessible through multiple endpoints, they may expose race windows that can be abused to bypass intended validation or business logic. Our objective in this lab was to take advantage of such a flaw and manipulate the order placement process for personal gain.
Understanding Multi-Endpoint Race Conditions
Multi-endpoint race conditions occur when two or more endpoints operate on the same server-side object or record but do so independently and without proper synchronization. These issues are tricky to identify because the vulnerability does not reside in a single HTTP request but rather in the logic shared across multiple workflows.
For example, in an online store, the backend may validate payment in one endpoint and finalize the order in another. If these endpoints don’t lock the shared resource properly, it’s possible to initiate a legitimate payment and then immediately send a second request to modify the order before the backend finishes processing the first one. This misalignment in timing can allow attackers to receive more items than they paid for or reduce the total cost.
To exploit this, we followed the predict, probe, prove methodology:
- Predict: Identify critical endpoints that might operate on shared state.
- Probe: Use sequential and parallel requests to spot behavioral anomalies.
- Prove: Validate the exploit by reproducing the race reliably and observing the impact.
This lab exemplifies how dangerous unsynchronized workflows can be when they involve operations like inventory updates, payments, or account modifications across multiple endpoints.
Challenges
This lab’s purchasing flow contains a race condition that enables you to purchase items for an unintended price.
To solve the lab, successfully purchase a Lightweight L33t Leather Jacket.
You can log into your account with the following credentials: wiener:peter
.
Walkthrough
Step 1: We logged into the application using the default credentials wiener:peter
. Upon successful login, we noticed that the account had a store credit balance of $100. To test the functionality, we attempted to purchase a $10 gift card.
Step 2: We proceeded to place an order for the \$10 gift card using the available store credit.
Step 3: As soon as we placed the order, the application issued a $10 gift card coupon.
Step 4: We then attempted to redeem the $10 gift card coupon we had just received.
Step 5: Upon redeeming the coupon, we regained the $10 store credit that had been deducted during the gift card purchase.
Step 6: We switched to Burp Suite to identify the HTTP requests responsible for adding the gift card to the cart and initiating the checkout process.
Step 7: We identified the checkout request and sent both the add-to-cart and checkout requests to Burp Repeater. Additionally, we included a homepage request to help warm the connection for better timing control during testing.
Step 8: In the Repeater, we observed an interesting behavior in the response timings. When we sent the homepage request, it initially took around 500ms to 700ms. However, sending the same homepage request twice in quick succession resulted in a much faster response for the second one. This indicated that the server was handling the second request based on the processing done for the first, revealing a potential race window.
Step 9: Now, with the three requestsโhome, add-to-cart, and checkoutโin hand, we created a tab in Burp Repeater to prepare for the race condition exploit.
Step 10: Before sending the requests, we modified the product quantity from 2 to 1, as the lab challenge required us to purchase the Leet Leather Jacket, which has the product ID 1.
Step 11: Another prerequisite for exploiting this race window was ensuring that there was an item in the cart. This way, when the application processed the $10 gift card purchase on the backend, it would simultaneously process the checkout of the Leet Leather Jacket.
Step 12: Next, we set the requests to be sent as a group in parallel using the single-packet attack option, allowing all requests to be sent simultaneously.
Step 13: We successfully completed the lab, demonstrating the race condition exploit.
After refreshing the page, we noticed our store credit had gone negativeโan unusual and unintended behavior.