Most applications perform multiple transactions and processes at the same time. In this video, you’ll learn how attackers can take advantage of this characteristic with a race condition.
A race condition is when two events happen at nearly the same time with an application, and the application doesn’t take into account that these two conditions may be operating simultaneously. This is something application developers commonly check when they’re building their application. But there may be times when a combination of different events inside the application might have an unexpected outcome. And this would be the textbook example of a race condition.
One common type of a race condition is a TOCTOU. This is a Time-Of-Check to Time-Of-Use attack. This means the application is going to check the system to retrieve information that may be stored. And then after it retrieves that information, it may perform a particular function with that value. But sometimes, there’s another process that occurs behind the scenes between the time when you’ve checked the system for the value and you’re actually using that particular value. And if you don’t take into account that that value might change without you knowing it, you’ve run into a race condition.
Let’s look at a practical example of a race condition where you have two users that are moving dollars between two different accounts. There’s user 1 and user 2. And the two accounts are Account A and Account B. The race condition that you’re going to see here is one that was created because the application developer takes deposits that are put into the account and has them immediately updated in the application. But if someone withdraws money from an account, that information may not be immediately updated in the ledger.
Let’s see how this would play out if the two users are transferring information from one account to another. We’ll start with two accounts, Account A and Account B, and both have a starting account value of $100. User 1 is going to transfer $50 from Account A to Account B. User 1 is going to check the balance and see that Account A is $100 and Account B has $100. User 2 is also going to check the balance and see that both of the balances are indeed at $100.
So far, everything is working as you would expect. Now user 1 is going to add $50 to Account B. Because deposits are updated immediately, we know that Account A has $100, and Account B, with an extra $50 in it, has a $150 value. Now user 2 is going to perform the same function. They’re going to add $50 to Account B. And when they do that, because this deposit is represented immediately, we now have Account A with $100 and Account B with $200.
And again, everything is still working exactly as expected. Now user 1 is going to remove $50 from Account A. From user 1’s perspective, Account A now has $50 and Account B has $200. Now user 2 is going to perform the same transaction and remove $50 from Account A. Because these withdrawals are not updated immediately for all users, from user 2’s perspective, Account A has $50 and Account B has $200.
This is the step where the race condition really occurs. Because the application is not immediately taken into account any withdrawals, the final ending account value for user 2 is going to have Account A as $50 and Account B as $200 when, in reality, Account A should have $0. These types of race conditions can occur anywhere the application is not taking into account one of these many different events that can occur.
In 2004, we saw a race condition occur on the planet Mars with the Mars rover Spirit. There’s a safety mechanism within the rover where it will reboot itself if it recognizes that a fatal error has occurred. And in the case of Mars rover, the problem that was occurring was with the file system itself. So during this reboot process, the rover recognizes that there’s a file system error, and its programming knows that it should be rebooting itself to correct this. It reboots itself and runs into exactly the same file system error again. And we effectively have a reboot loop.
In this example, the developers were able to send additional code to the rover to bypass this particular error and get the rover back up and running. And it seems appropriate that we should have a race condition that occurs inside of a car. And indeed, we had one during Pwn2Own in Vancouver 2023 with a Tesla Model 3.
This TOCTOU attack took advantage of a vulnerability in the Tesla of its infotainment system that you could access through Bluetooth. They were able to elevate privileges to be the root user of the infotainment system. And this allowed the attackers to earn a $100,000 US prize, and they keep the Tesla.