I got a binary file and I'm supposed to crack its password (homework). There was also a function given (a function which is a part of the binary file). That function showed that the input string was compared with the correct password character by character and returned false instantly when a character was wrong (that's not secure way of doing it I guess because it's leaking time and we get an idea of the correct password length as example). But our teacher has added a random timer that returns the result (Correct / Wrong) to make it a little harder for us…
Anyway, I have I already done it successfully with reverse engineering and got the correct password. Now I'm playing with it in the command line:
/usr/bin/time -v ./program_name enter_password
With this command, I get a lot information such as system time, swaps, execution time..But what is most interesting to me is "Voluntary context switches" because the more correct characters of the password I enter, the less "Voluntary context switches" I get!
The more wrong characters I enter, the more "Voluntary context switches" I get.
It took me almost two hours to crack the password just by entering that command, entering characters and observing "Voluntary context switches". Whenever ONE character was correct, the "Voluntary context switches" decreased by one.
My question, what exactly are "Voluntary context switches" and why did they help me cracking the password?
Best Answer
The man page for
time
explains the concept of voluntary and involuntary context switches:(quote is from my Debian system, the linked man page has a slightly different text)
That is, a context switch is voluntary, if the process leaves the CPU because it has nothing else to do (while waiting for something external to happen). Involuntary, if it would like to continue some computation, but the OS decides it's time to switch to some other process.
How any of this is related to the password-checking program, depends on what the program actually does.
From the source code linked in the comments, we see that the program calls
usleep()
once for each non-matching character, continuing the comparison loop on the next character afterwards. Sleeping is about as voluntary as yielding the CPU ever gets, so these calls will show as voluntary context switches for each non-maching character.On Linux, you should be able to see the calls with
strace
, too.The final delay comes from a randomized sleep of
T * (rand() % 3)
, i.e. 0, 1, or 2 times a constant. That's a rather coarse granularity, so it should be easy to average out by doing multiple attempts with the same password.